All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.ikm.tinkar.coordinate.logic.PremiseSet Maven / Gradle / Ivy

There is a newer version: 1.78.0
Show newest version
/*
 * Copyright © 2015 Integrated Knowledge Management ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dev.ikm.tinkar.coordinate.logic;

import dev.ikm.tinkar.common.binary.*;
import dev.ikm.tinkar.coordinate.ImmutableCoordinate;
import dev.ikm.tinkar.collection.ConcurrentReferenceHashMap;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class PremiseSet implements ImmutableCoordinate {

    private static final ConcurrentReferenceHashMap SINGLETONS =
            new ConcurrentReferenceHashMap<>(ConcurrentReferenceHashMap.ReferenceType.WEAK,
                    ConcurrentReferenceHashMap.ReferenceType.WEAK);

    public static final PremiseSet INFERRED_ONLY = make(PremiseType.INFERRED);
    public static final PremiseSet STATED_ONLY = make(PremiseType.STATED);
    public static final PremiseSet STATED_AND_INFERRED = make(PremiseType.INFERRED, PremiseType.STATED);


    private int[] flags;
    private long bits = 0;

    private PremiseSet(PremiseType... premises) {
        flags = new int[premises.length];
        for (int i = 0; i < premises.length; i++) {
            PremiseType premise = premises[i];
            bits |= (1L << premise.ordinal());
            flags[i] = TaxonomyFlag.getFlagsFromPremiseType(premise);
        }
    }

    private PremiseSet(Collection premises) {
        flags = new int[premises.size()];
        Iterator premiseIterator = premises.iterator();
        for (int i = 0; i < premises.size(); i++) {
            PremiseType premise = premiseIterator.next();
            bits |= (1L << premise.ordinal());
            flags[i] = TaxonomyFlag.getFlagsFromPremiseType(premise);
        }
    }


    @Decoder
    public static Object decode(DecoderInput in) {
        switch (Encodable.checkVersion(in)) {
            default:
                int size = in.readVarInt();
                List values = new ArrayList<>(size);
                for (int i = 0; i < size; i++) {
                    values.add(PremiseType.valueOf(in.readString()));
                }
                return SINGLETONS.computeIfAbsent(new PremiseSet(values), statusSet -> statusSet);
        }
    }

    public static PremiseSet of(PremiseType... premises) {
        return make(premises);
    }

    public static PremiseSet make(PremiseType... premises) {
        return SINGLETONS.computeIfAbsent(new PremiseSet(premises), premiseSet -> premiseSet);
    }

    public static PremiseSet of(Collection premises) {
        return make(premises);
    }

    public static PremiseSet make(Collection premises) {
        return SINGLETONS.computeIfAbsent(new PremiseSet(premises), premiseSet -> premiseSet);
    }

    @Override
    @Encoder
    public void encode(EncoderOutput out) {
        EnumSet premiseSet = toEnumSet();
        out.writeVarInt(premiseSet.size());
        for (PremiseType premise : premiseSet) {
            out.writeString(premise.name());
        }
    }

    public EnumSet toEnumSet() {
        EnumSet result = EnumSet.noneOf(PremiseType.class);
        for (PremiseType premise : PremiseType.values()) {
            if (contains(premise)) {
                result.add(premise);
            }
        }
        return result;
    }

    public boolean contains(PremiseType status) {
        return (bits & (1L << status.ordinal())) != 0;
    }

    public int[] getFlags() {
        return flags;
    }

    public PremiseType[] toArray() {
        EnumSet statusSet = toEnumSet();
        return statusSet.toArray(new PremiseType[statusSet.size()]);
    }

    public boolean containsAll(Collection c) {
        for (PremiseType premise : c) {
            if (!contains(premise)) {
                return false;
            }
        }
        return true;
    }

    public boolean containsAny(Collection c) {
        for (PremiseType premise : c) {
            if (contains(premise)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(bits);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PremiseSet that = (PremiseSet) o;
        return bits == that.bits;
    }

    @Override
    public String toString() {
        return "PremiseSet{" +
                toEnumSet() +
                '}';
    }

    public String toUserString() {
        StringBuilder sb = new StringBuilder();
        AtomicInteger count = new AtomicInteger();
        addIfPresent(sb, count, PremiseType.INFERRED);
        addIfPresent(sb, count, PremiseType.STATED);
        return sb.toString();
    }

    private void addIfPresent(StringBuilder sb, AtomicInteger count, PremiseType premise) {
        if (this.contains(premise)) {
            if (count.getAndIncrement() > 0) {
                sb.append(" and ");
            }
            sb.append(premise);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy