Class ProofMapIndexProxy<K,​V>

java.lang.Object
com.exonum.binding.core.proxy.AbstractNativeProxy
com.exonum.binding.core.storage.indices.ProofMapIndexProxy<K,​V>
Type Parameters:
K - the type of keys in this map
V - the type of values in this map
All Implemented Interfaces:
HashableIndex, MapIndex<K,​V>, StorageIndex

public final class ProofMapIndexProxy<K,​V>
extends AbstractNativeProxy
implements MapIndex<K,​V>, HashableIndex
A ProofMapIndexProxy is an index that maps keys to values. A map cannot contain duplicate keys; each key corresponds to at most one value. This map is capable of providing cryptographic proofs that a certain key is mapped to a particular value or that there are no mapping for the key in the map.

This map is implemented as a Merkle-Patricia tree. It does not permit null keys and values.

The Merkle-Patricia tree backing the proof map uses internal 32-byte keys. The tree balance relies on the internal keys being uniformly distributed.

Key hashing in proof maps

By default, when creating the proof map using method #newInstance, the user keys are converted into internal keys through hashing. This allows to use keys of an arbitrary size and ensures the balance of the internal tree. It is also possible to create a proof map that will not hash keys with method #newInstanceNoKeyHashing. In this mode the map will use the user keys as internal tree keys. Such mode of operation is appropriate iff all of the following conditions hold:

  • All keys are 32-byte long
  • The keys are uniformly distributed
  • The keys come from a trusted source that cannot influence their distribution and affect the tree balance.

The "destructive" methods of the map, i.e., the one that change the map contents, are specified to throw UnsupportedOperationException if the map has been created with a read-only database access.

All method arguments are non-null by default.

This class is not thread-safe and and its instances shall not be shared between threads.

When the access goes out of scope, this map is destroyed. Subsequent use of the closed map is prohibited and will result in IllegalStateException.

See Also:
Access
  • Method Details

    • newInstance

      public static <K,​ V> ProofMapIndexProxy<K,​V> newInstance​(IndexAddress address, AbstractAccess access, Serializer<K> keySerializer, Serializer<V> valueSerializer)
      Creates a ProofMapIndexProxy.

      Warning: do not invoke this method from service code, use Access.getProofMap(IndexAddress, Serializer, Serializer).

      Type Parameters:
      K - the type of keys in the map
      V - the type of values in the map
      Parameters:
      address - an index address
      access - a database access. Must be valid. If an access is read-only, "destructive" operations are not permitted.
      keySerializer - a serializer of keys
      valueSerializer - a serializer of values
      Throws:
      java.lang.IllegalStateException - if the access is not valid
      java.lang.IllegalArgumentException - if the name is empty
      See Also:
      StandardSerializers
    • newInstanceNoKeyHashing

      public static <K,​ V> ProofMapIndexProxy<K,​V> newInstanceNoKeyHashing​(IndexAddress address, AbstractAccess access, Serializer<K> keySerializer, Serializer<V> valueSerializer)
      Creates a ProofMapIndexProxy that uses non-hashed keys. Requires that keys are 32-byte long.

      Warning: do not invoke this method from service code, use Access.getRawProofMap(IndexAddress, Serializer, Serializer).

      Type Parameters:
      K - the type of keys in the map
      V - the type of values in the map
      Parameters:
      address - an index address
      access - a database access. Must be valid. If an access is read-only, "destructive" operations are not permitted.
      keySerializer - a serializer of keys, must always produce 32-byte long values
      valueSerializer - a serializer of values
      Throws:
      java.lang.IllegalStateException - if the access is not valid
      java.lang.IllegalArgumentException - if the name is empty
      See Also:
      StandardSerializers
    • containsKey

      public boolean containsKey​(K key)
      Description copied from interface: MapIndex
      Returns true if this map contains a mapping for the specified key.
      Specified by:
      containsKey in interface MapIndex<K,​V>
    • put

      public void put​(K key, V value)
      Puts a new key-value pair into the map. If this map already contains a mapping for the specified key, overwrites the old value with the specified value.
      Specified by:
      put in interface MapIndex<K,​V>
      Parameters:
      key - a proof map key
      value - a storage value to associate with the key
      Throws:
      java.lang.IllegalStateException - if this map is not valid
      java.lang.IllegalArgumentException - if the size of the key is not 32 bytes (in case of a proof map that uses non-hashed keys)
      java.lang.UnsupportedOperationException - if this map is read-only
    • putAll

      public void putAll​(java.util.Map<? extends K,​? extends V> sourceMap)
      Description copied from interface: MapIndex
      Puts all key-value pairs from the given map into this map. Equivalent to a sequence of individual MapIndex.put(K, V) operations.
      Specified by:
      putAll in interface MapIndex<K,​V>
      Parameters:
      sourceMap - a map to put into this one
    • get

      public V get​(K key)
      Description copied from interface: MapIndex
      Returns the value associated with the specified key, or null if there is no mapping for the key.
      Specified by:
      get in interface MapIndex<K,​V>
      Parameters:
      key - a storage key
      Returns:
      the value mapped to the specified key, or null if this map contains no mapping for the key.
    • getProof

      public MapProof getProof​(K key, K... otherKeys)
      Returns a proof that there are values mapped to the specified keys or that there are no such mappings.
      Parameters:
      key - a proof map key which might be mapped to some value
      otherKeys - other proof map keys which might be mapped to some values
      Throws:
      java.lang.IllegalStateException - if this map is not valid
      java.lang.IllegalArgumentException - if the size of any of the keys is not 32 bytes (in case of a proof map that uses non-hashed keys)
      See Also:
      Blockchain Proofs
    • getProof

      public MapProof getProof​(java.util.Collection<? extends K> keys)
      Returns a proof that there are values mapped to the specified keys or that there are no such mappings.
      Parameters:
      keys - proof map keys which might be mapped to some values
      Throws:
      java.lang.IllegalStateException - if this map is not valid
      java.lang.IllegalArgumentException - if the size of any of the keys is not 32 bytes (in case of a proof map that uses non-hashed keys) or keys collection is empty
      See Also:
      Blockchain Proofs
    • getIndexHash

      public HashCode getIndexHash()
      Description copied from interface: HashableIndex
      Returns the index hash which represents the complete state of this index. Any modifications to the stored entries affect the index hash.

      How index hash is computed depends on the index data structure implementation.

      Specified by:
      getIndexHash in interface HashableIndex
    • remove

      public void remove​(K key)
      Description copied from interface: MapIndex
      Removes the value mapped to the specified key from the map. If there is no such mapping, has no effect.
      Specified by:
      remove in interface MapIndex<K,​V>
      Parameters:
      key - a storage key
    • keys

      public java.util.Iterator<K> keys()
      Description copied from interface: MapIndex
      Returns an iterator over the map keys. The keys are ordered in lexicographical order.
      Specified by:
      keys in interface MapIndex<K,​V>
    • values

      public java.util.Iterator<V> values()
      Description copied from interface: MapIndex
      Returns an iterator over the map values. The values are ordered in lexicographical order of keys.
      Specified by:
      values in interface MapIndex<K,​V>
    • entries

      public java.util.Iterator<MapEntry<K,​V>> entries()
      Description copied from interface: MapIndex
      Returns an iterator over the map entries. The entries are ordered by keys in lexicographical order.
      Specified by:
      entries in interface MapIndex<K,​V>
    • clear

      public void clear()
      Description copied from interface: MapIndex
      Removes all of the key-value pairs from the map. The map will be empty after this method returns.
      Specified by:
      clear in interface MapIndex<K,​V>
    • getAddress

      public IndexAddress getAddress()
      Description copied from interface: StorageIndex
      Returns the index address: its identifier in the database.

      Please note that the implementations may return either relative or absolute address. The address is not required to be equal to the one passed to the index constructor.

      Specified by:
      getAddress in interface StorageIndex
    • toString

      public java.lang.String toString()
      Overrides:
      toString in class java.lang.Object