Package 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 | 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 | 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, 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