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

software.amazon.event.ruler.ArrayMembership Maven / Gradle / Ivy

package software.amazon.event.ruler;

/**
 * Represents which JSON arrays within an Event structure a particular field appears within, and at which position.
 *  The arrays are identified using integers.
 */
class ArrayMembership {
    private static final IntIntMap EMPTY = new IntIntMap();

    private IntIntMap membership;

    ArrayMembership() {
        membership = new IntIntMap();
    }

    ArrayMembership(final ArrayMembership membership) {
        if (membership.size() == 0) {
            this.membership = EMPTY;
        } else {
            this.membership = (IntIntMap) membership.membership.clone();
        }
    }

    void putMembership(int array, int index) {
        if (index == IntIntMap.NO_VALUE) {
            membership.remove(array);
        } else {
            membership.put(array, index);
        }
    }
    void deleteMembership(int array) {
        membership.remove(array);
    }
    int getMembership(int array) {
        return membership.get(array);
    }
    boolean isEmpty() {
        return membership.isEmpty();
    }
    private int size() {
        return membership.size();
    }

    // for debugging
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (IntIntMap.Entry entry : membership.entries()) {
            sb.append(entry.getKey()).append('[').append(entry.getValue()).append("] ");
        }
        return sb.toString();
    }

    /**
     * We are stepping through the NameState machine field by field, and have built up data on the array memberships
     *  observed so far in this map. We need to compare this to the array-membership data of the field we're looking at
     *  and see if they are consistent.  Either or both memberships might be empty, which simplifies things.
     * Method returns null if the new field's membership is inconsistent with so-far membership.  If it is compatible,
     *  returns the possibly-revised array membership of the matching task.
     *
     * @param fieldMembership Array membership of the field under consideration
     * @param membershipSoFar Array membership observed so far in a rule-matching task
     * @return null or the new matching-task membership so far
     */
    static ArrayMembership checkArrayConsistency(final ArrayMembership membershipSoFar, final ArrayMembership fieldMembership) {

        // no existing memberships, so we'll take the ones from the field, if any
        if (membershipSoFar.isEmpty()) {
            return fieldMembership.isEmpty() ? membershipSoFar : new ArrayMembership(fieldMembership);
        }

        // any change will come from memberships in the new field we're investigating. For each of its memberships
        ArrayMembership newMembership = null;
        for (IntIntMap.Entry arrayEntry : fieldMembership.membership.entries()) {
            final int array = arrayEntry.getKey();
            final int indexInThisArrayOfThisField = arrayEntry.getValue();
            final int indexInThisArrayPreviouslyAppearingInMatch = membershipSoFar.getMembership(array);

            if (indexInThisArrayPreviouslyAppearingInMatch == IntIntMap.NO_VALUE) {

                // if there's no membership so far, this is an acceptable delta. Update the new memberships, first
                //  creating it if necessary
                if (newMembership == null) {
                    newMembership = new ArrayMembership(membershipSoFar);
                }
                newMembership.putMembership(array, indexInThisArrayOfThisField);

            } else {

                // This field does appear within an index that has already appeared in the matching task so far.
                //  If it's in the same element, fine, no updates. If it's a different entry, return null to
                //  signal array-inconsistency.
                if (indexInThisArrayOfThisField != indexInThisArrayPreviouslyAppearingInMatch) {
                    return null;
                }
            }
        }

        // we may have scanned all the fields and not added anything, in which case return the input
        return (newMembership == null) ? membershipSoFar : newMembership;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy