org.eclipse.viatra.query.runtime.matchers.util

## Interface IMultiLookupAbstract<Key,Value,Bucket extends MarkedMemory<Value>>

- All Superinterfaces:
    IMultiLookup<Key,Value>
  All Known Subinterfaces:
    IMultiLookupAbstract.ToMultisetsAbstract<Key,Value>, IMultiLookupAbstract.ToSetsAbstract<Key,Value>

      public interface IMultiLookupAbstract<Key,Value,Bucket extends MarkedMemory<Value>>
      extends IMultiLookup<Key,Value>

  Specialized multimap implementation that saves memory by storing singleton value objects (multiplicity 1) instead of multiset buckets whenever there is only one value associated with a key.

  See specialized `IMultiLookupAbstract.ToSetsAbstract`, `IMultiLookupAbstract.ToMultisetsAbstract` for various bucket types.

  Implemented as a Key->Object map with invariant:

  - key maps to null if associated with no values;
  - key maps to a single Value iff it is associated with a single value of multiplicity +1;
  - key maps to Bucket otherwise
  Note that due to the above invariant, handling +1 and -1 are asymmetric in case of delta maps.

  Not intended as an API, but rather as a 'base class' for implementors. Realized as an interface with default implementations, instead of an abstract class, to ensure that implementors can easily choose a base class such as UnifiedMap to augment.

  Implementor should inherit from a Map-like class (primitive map possible) and bind the lowLevel* methods accordingly.

  Since:
    2.0
  No Implement:
    This interface is not intended to be implemented by clients.
  No Reference:
    This interface is not intended to be referenced by clients.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Interface and Description
    --- | ---
    `static interface` | `IMultiLookupAbstract.ToMultisetsAbstract<Key,Value>` A multi-lookup whose buckets are multisets.
    `static interface` | `IMultiLookupAbstract.ToSetsAbstract<Key,Value>` A multi-lookup whose buckets are sets.

    - ### Nested classes/interfaces inherited from interface org.eclipse.viatra.query.runtime.matchers.util.IMultiLookup

      `IMultiLookup.ChangeGranularity`

  - ### Method Summary

    All Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `default IMultiLookup.ChangeGranularity` | `addPair(Key key, Value value)` Adds key-value pair to the lookup structure, or fails if not possible.
    `default IMultiLookup.ChangeGranularity` | `addPairInternal(Key key, Value value, boolean throwIfImpossible)`
    `default IMultiLookup.ChangeGranularity` | `addPairOrNop(Key key, Value value)` Adds key-value pair to the lookup structure.
    `default IMultiLookup.ChangeGranularity` | `addPairPositiveMultiplicity(Key key, Value value, int count)` Updates multiplicity of key-value pair by a positive amount.
    `boolean` | `addToBucket(Bucket bucket, Value value, boolean throwIfImpossible)` Increases the multiplicity of the value in the bucket.
    `Value` | `asSingleton(Bucket bucket)` Checks whether the bucket is a singleton, i.e.
    `default int` | `countKeys()`
    `Bucket` | `createDeltaBucket(Value positive, Value negative)`
    `Bucket` | `createSingletonBucket(Value value)`
    `default java.lang.Iterable<Key>` | `distinctKeys()`
    `default java.util.stream.Stream<Key>` | `distinctKeysStream()`
    `default java.lang.Iterable<Value>` | `distinctValues()` Iterates once over each distinct value.
    `default java.util.stream.Stream<Value>` | `distinctValuesStream()` Iterates once over each distinct value.
    `boolean` | `duplicatesAllowed()`
    `default void` | `handleSingleton(Key key, Bucket bucket)`
    `default IMemoryView<Value>` | `lookup(Key key)` Returns a (read-only) bucket of values associated with the given key.
    `default IMemoryView<Value>` | `lookupAndRemoveAll(Key key)` Returns a (read-only) bucket of values associated with the given key, while simultaneously removing them.
    `default boolean` | `lookupExists(Key key)` Returns true if there are any values associated with the given key.
    `default IMemoryView<Value>` | `lookupUnsafe(java.lang.Object key)` Returns a (read-only) bucket of values associated with the given key, which can be of any type.
    `java.lang.Object` | `lowLevelGet(Key key)` Implementor shall bind to the low-level get() or equivalent of the underlying Key-to-Object map
    `java.lang.Object` | `lowLevelGetUnsafe(java.lang.Object key)` Implementor shall bind to the low-level get() or equivalent of the underlying Key-to-Object map
    `java.lang.Iterable<Key>` | `lowLevelKeySet()` Implementor shall bind to the low-level keySet() or equivalent of the underlying Key-to-Object map
    `void` | `lowLevelPut(Key key, java.lang.Object valueOrBucket)` Implementor shall bind to the low-level put() or equivalent of the underlying Key-to-Object map
    `java.lang.Object` | `lowLevelPutIfAbsent(Key key, Value value)` Implementor shall bind to the low-level putIfAbsent() or equivalent of the underlying Key-to-Object map
    `java.lang.Object` | `lowLevelRemove(Key key)` Implementor shall bind to the low-level remove() or equivalent of the underlying Key-to-Object map
    `int` | `lowLevelSize()` Implementor shall bind to the low-level size() or equivalent of the underlying Key-to-Object map
    `java.lang.Iterable<java.lang.Object>` | `lowLevelValues()` Implementor shall bind to the low-level values() or equivalent of the underlying Key-to-Object map
    `boolean` | `negativesAllowed()`
    `boolean` | `removeFromBucket(Bucket bucket, Value value, boolean throwIfImpossible)` Decreases the multiplicity of the value in the bucket.
    `default IMultiLookup.ChangeGranularity` | `removePair(Key key, Value value)` Removes key-value pair from the lookup structure, or fails if not possible.
    `default IMultiLookup.ChangeGranularity` | `removePairInternal(Key key, Value value, boolean throwIfImpossible)`
    `default IMultiLookup.ChangeGranularity` | `removePairOrNop(Key key, Value value)` Removes key-value pair from the lookup structure.
    `default IMemoryView<Value>` | `yieldSingleton(Value value)`

    - ### Methods inherited from interface org.eclipse.viatra.query.runtime.matchers.util.IMultiLookup

      `clear, equals, hashCode, isEmpty, lookupOrEmpty, lookupUnsafeOrEmpty`

- - ### Method Detail

    - #### lowLevelGet

          java.lang.Object lowLevelGet(Key key)

      Implementor shall bind to the low-level get() or equivalent of the underlying Key-to-Object map

    - #### lowLevelGetUnsafe

          java.lang.Object lowLevelGetUnsafe(java.lang.Object key)

      Implementor shall bind to the low-level get() or equivalent of the underlying Key-to-Object map

    - #### lowLevelRemove

          java.lang.Object lowLevelRemove(Key key)

      Implementor shall bind to the low-level remove() or equivalent of the underlying Key-to-Object map

    - #### lowLevelPutIfAbsent

          java.lang.Object lowLevelPutIfAbsent(Key key,
                                               Value value)

      Implementor shall bind to the low-level putIfAbsent() or equivalent of the underlying Key-to-Object map

    - #### lowLevelPut

          void lowLevelPut(Key key,
                           java.lang.Object valueOrBucket)

      Implementor shall bind to the low-level put() or equivalent of the underlying Key-to-Object map

    - #### lowLevelValues

          java.lang.Iterable<java.lang.Object> lowLevelValues()

      Implementor shall bind to the low-level values() or equivalent of the underlying Key-to-Object map

    - #### lowLevelKeySet

          java.lang.Iterable<Key> lowLevelKeySet()

      Implementor shall bind to the low-level keySet() or equivalent of the underlying Key-to-Object map

    - #### lowLevelSize

          int lowLevelSize()

      Implementor shall bind to the low-level size() or equivalent of the underlying Key-to-Object map

    - #### lookupExists

          default boolean lookupExists(Key key)

      Description copied from interface: `IMultiLookup`
      Returns true if there are any values associated with the given key.
      Specified by:
        `lookupExists` in interface `IMultiLookup<Key,Value>`
      Parameters:
        `key` - a key for which associated values are sought

    - #### lookup

          default IMemoryView<Value> lookup(Key key)

      Description copied from interface: `IMultiLookup`
      Returns a (read-only) bucket of values associated with the given key. Clients must not modify the returned bucket.
      Specified by:
        `lookup` in interface `IMultiLookup<Key,Value>`
      Parameters:
        `key` - a key for which associated values are sought
      Returns:
        null if key not found, a bucket of values otherwise

    - #### lookupAndRemoveAll

          default IMemoryView<Value> lookupAndRemoveAll(Key key)

      Description copied from interface: `IMultiLookup`
      Returns a (read-only) bucket of values associated with the given key, while simultaneously removing them. Clients must not modify the returned bucket.
      Specified by:
        `lookupAndRemoveAll` in interface `IMultiLookup<Key,Value>`
      Parameters:
        `key` - a key for which associated values are sought
      Returns:
        a bucket of values, never null

    - #### lookupUnsafe

          default IMemoryView<Value> lookupUnsafe(java.lang.Object key)

      Description copied from interface: `IMultiLookup`
      Returns a (read-only) bucket of values associated with the given key, which can be of any type. Clients must not modify the returned bucket.
      Specified by:
        `lookupUnsafe` in interface `IMultiLookup<Key,Value>`
      Parameters:
        `key` - a key for which associated values are sought (may or may not be of Key type)
      Returns:
        null if key not found, a bucket of values otherwise

    - #### addPair

          default IMultiLookup.ChangeGranularity addPair(Key key,
                                                         Value value)

      Description copied from interface: `IMultiLookup`
      Adds key-value pair to the lookup structure, or fails if not possible.

      If the addition would cause duplicates but the bucket type does not allow it (`CollectionsFactory.MemoryType.SETS`), the operation throws an `IllegalStateException`.

      Specified by:
        `addPair` in interface `IMultiLookup<Key,Value>`
      Returns:
        the granularity of the change

    - #### addPairOrNop

          default IMultiLookup.ChangeGranularity addPairOrNop(Key key,
                                                              Value value)

      Description copied from interface: `IMultiLookup`
      Adds key-value pair to the lookup structure.

      If the addition would cause duplicates but the bucket type does not allow it (`CollectionsFactory.MemoryType.SETS`), the operation is silently ignored and `IMultiLookup.ChangeGranularity.DUPLICATE` is returned.

      Specified by:
        `addPairOrNop` in interface `IMultiLookup<Key,Value>`
      Returns:
        the granularity of the change, or `IMultiLookup.ChangeGranularity.DUPLICATE` if addition would result in a duplicate and therefore ignored

    - #### addPairInternal

          default IMultiLookup.ChangeGranularity addPairInternal(Key key,
                                                                 Value value,
                                                                 boolean throwIfImpossible)

    - #### addPairPositiveMultiplicity

          default IMultiLookup.ChangeGranularity addPairPositiveMultiplicity(Key key,
                                                                             Value value,
                                                                             int count)

      Description copied from interface: `IMultiLookup`
      Updates multiplicity of key-value pair by a positive amount.

      PRE: count > 0

      Specified by:
        `addPairPositiveMultiplicity` in interface `IMultiLookup<Key,Value>`
      Returns:
        the granularity of the change

    - #### removePair

          default IMultiLookup.ChangeGranularity removePair(Key key,
                                                            Value value)

      Description copied from interface: `IMultiLookup`
      Removes key-value pair from the lookup structure, or fails if not possible.

      When attempting to remove a key-value pair with zero multiplicity from a non-delta bucket type (`CollectionsFactory.MemoryType.SETS` or `CollectionsFactory.MemoryType.MULTISETS`}), an `IllegalStateException` is thrown.

      Specified by:
        `removePair` in interface `IMultiLookup<Key,Value>`
      Returns:
        the granularity of the change

    - #### removePairOrNop

          default IMultiLookup.ChangeGranularity removePairOrNop(Key key,
                                                                 Value value)

      Description copied from interface: `IMultiLookup`
      Removes key-value pair from the lookup structure.

      When attempting to remove a key-value pair with zero multiplicity from a non-delta bucket type (`CollectionsFactory.MemoryType.SETS` or `CollectionsFactory.MemoryType.MULTISETS`}), the operation is silently ignored and `IMultiLookup.ChangeGranularity.DUPLICATE` is returned.

      Specified by:
        `removePairOrNop` in interface `IMultiLookup<Key,Value>`
      Returns:
        the granularity of the change

    - #### removePairInternal

          default IMultiLookup.ChangeGranularity removePairInternal(Key key,
                                                                    Value value,
                                                                    boolean throwIfImpossible)

    - #### handleSingleton

          default void handleSingleton(Key key,
                                       Bucket bucket)

    - #### distinctValues

          default java.lang.Iterable<Value> distinctValues()

      Description copied from interface: `IMultiLookup`
      Iterates once over each distinct value.
      Specified by:
        `distinctValues` in interface `IMultiLookup<Key,Value>`

    - #### distinctValuesStream

          default java.util.stream.Stream<Value> distinctValuesStream()

      Description copied from interface: `IMultiLookup`
      Iterates once over each distinct value.
      Specified by:
        `distinctValuesStream` in interface `IMultiLookup<Key,Value>`

    - #### distinctKeys

          default java.lang.Iterable<Key> distinctKeys()

      Specified by:
        `distinctKeys` in interface `IMultiLookup<Key,Value>`
      Returns:
        the set of distinct keys that have values associated.

    - #### distinctKeysStream

          default java.util.stream.Stream<Key> distinctKeysStream()

      Specified by:
        `distinctKeysStream` in interface `IMultiLookup<Key,Value>`
      Returns:
        the set of distinct keys that have values associated.

    - #### countKeys

          default int countKeys()

      Specified by:
        `countKeys` in interface `IMultiLookup<Key,Value>`
      Returns:
        the number of distinct keys that have values associated.

    - #### negativesAllowed

          boolean negativesAllowed()

      Returns:
        iff negative multiplicites are allowed

    - #### duplicatesAllowed

          boolean duplicatesAllowed()

      Returns:
        iff larger-than-1 multiplicites are allowed
      Since:
        2.3

    - #### addToBucket

          boolean addToBucket(Bucket bucket,
                              Value value,
                              boolean throwIfImpossible)

      Increases the multiplicity of the value in the bucket.
      Returns:
        true iff non-duplicate
      Throws:
        `java.lang.IllegalStateException` - if disallowed duplication and throwIfImpossible is specified

    - #### removeFromBucket

          boolean removeFromBucket(Bucket bucket,
                                   Value value,
                                   boolean throwIfImpossible)

      Decreases the multiplicity of the value in the bucket.
      Returns:
        false if removing duplicate value
      Throws:
        `java.lang.IllegalStateException` - if removing non-existing value (unless delta map) and throwIfImpossible is specified

    - #### asSingleton

          Value asSingleton(Bucket bucket)

      Checks whether the bucket is a singleton, i.e. it contains a single value with multiplicity +1
      Returns:
        the singleton value, or null if the bucket is not singleton

    - #### createSingletonBucket

          Bucket createSingletonBucket(Value value)

      Returns:
        a new bucket consisting of a sole value

    - #### yieldSingleton

          default IMemoryView<Value> yieldSingleton(Value value)

      Returns:
        a read-only bucket consisting of a sole value, to be returned to the user

    - #### createDeltaBucket

          Bucket createDeltaBucket(Value positive,
                                   Value negative)

      Parameters:
        `positive` - the previously existing value, or null if the delta is to contain a single negative tuple
      Returns:
        a new bucket consisting of a delta of two values
      Throws:
        `java.lang.IllegalStateException` - if deltas not supported