Class MutableView
- All Implemented Interfaces:
KVStore
,DeltaKVStore
,Cloneable
- Direct Known Subclasses:
ReadWriteSpannerView
DeltaKVStore
interface.
The amount of memory required scales in proportion to the number of distinct key ranges that are read or removed (if tracking reads) plus the total lengths of all keys and values written.
-
Constructor Summary
ConstructorDescriptionMutableView
(KVStore kv) Constructor.MutableView
(KVStore kv, boolean trackReads) Constructor with optional read tracking.MutableView
(KVStore kv, Reads reads, Writes writes) MutableView
(KVStore kv, Writes writes) Constructor with no read tracking and caller-providedWrites
. -
Method Summary
Modifier and TypeMethodDescriptionvoid
adjustCounter
(byte[] key, long amount) Adjust the counter at the given key by the given amount.void
Apply all the givenMutations
to this instance.clone()
Clone this instance.long
decodeCounter
(byte[] bytes) Decode a counter value previously encoded byencodeCounter()
.void
Permanently disable read tracking and discard theReads
associated with this instance.byte[]
encodeCounter
(long value) Encode a counter value into abyte[]
value suitable for use withdecodeCounter()
and/oradjustCounter()
.byte[]
get
(byte[] key) Get the value associated with the given key, if any.Get theKVStore
that underlies this instance.getRange
(byte[] minKey, byte[] maxKey, boolean reverse) Iterate the key/value pairs in the specified range.getReads()
Get theReads
associated with this instance.Get theWrites
associated with this instance.boolean
Determine if this instance is read-only.void
put
(byte[] key, byte[] value) Set the value associated with the given key.void
remove
(byte[] key) Remove the key/value pair with the given key, if it exists.void
removeRange
(byte[] minKey, byte[] maxKey) Remove all key/value pairs whose keys are in a given range.void
setKVStore
(KVStore kv) Swap out the underlyingKVStore
associated with this instance.void
Configure this instance as read-only.toString()
void
withoutReadTracking
(boolean allowWrites, Runnable action) Temporarily disable read tracking in the current thread while performing the given action.Methods inherited from class io.permazen.kv.AbstractKVStore
getAtLeast, getAtMost
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Methods inherited from interface io.permazen.kv.KVStore
getAtLeast, getAtMost, getRange, getRange, removeRange
-
Constructor Details
-
MutableView
Constructor.The instance will use a new, empty
Reads
instance for read tracking.- Parameters:
kv
- underlyingKVStore
- Throws:
IllegalArgumentException
- ifkv
is null
-
MutableView
Constructor with optional read tracking.- Parameters:
kv
- underlyingKVStore
trackReads
- true to enable read tracking, or false for none- Throws:
IllegalArgumentException
- ifkv
is null
-
MutableView
Constructor with no read tracking and caller-providedWrites
.- Parameters:
kv
- underlyingKVStore
writes
- recorded writes- Throws:
IllegalArgumentException
- ifkv
is nullIllegalArgumentException
- ifwrites
is null
-
MutableView
- Parameters:
kv
- underlyingKVStore
reads
- recorded reads, or null for nonewrites
- recorded writes- Throws:
IllegalArgumentException
- ifkv
is nullIllegalArgumentException
- ifwrites
is null
-
-
Method Details
-
getBaseKVStore
Description copied from interface:DeltaKVStore
Get theKVStore
that underlies this instance.Note that in some implementations the returned object and/or its contents may change over time, for example, if this instance gets "rebased" on a newer underlying
KVStore
.- Specified by:
getBaseKVStore
in interfaceDeltaKVStore
- Returns:
- underlying
KVStore
-
setKVStore
Swap out the underlyingKVStore
associated with this instance.Note: the new
KVStore
should have a consistent encoding of counter values as the previousKVStore
, otherwise a concurrent thread may read previously written counter values back incorrectly.- Parameters:
kv
- new underlyingKVStore
- Throws:
IllegalArgumentException
- ifkv
is null
-
getReads
Description copied from interface:DeltaKVStore
Get theReads
associated with this instance.This includes all keys explicitly or implicitly read by calls to
get()
,getAtLeast()
,getAtMost()
, andgetRange()
.The returned object is "live" and should only be accessed while synchronized on this instance.
The read tracking may be imprecise, as long as all actual reads are included. For example, if keys
10001
,100002
, and100003
were read, the returnedReads
may contain those three keys, or it may contain the entire range10001-10003
, even though some keys in that range were not actually read in order to save memory. This optimization is acceptable as long as the keys that were actually read are always included.- Specified by:
getReads
in interfaceDeltaKVStore
- Returns:
- reads recorded, or null if this instance is not configured to record reads or read tracking has
been permanently disabled via
DeltaKVStore.disableReadTracking()
-
getWrites
Description copied from interface:DeltaKVStore
Get theWrites
associated with this instance.The returned object is "live" and should only be accessed while synchronized on this instance.
- Specified by:
getWrites
in interfaceDeltaKVStore
- Returns:
- writes recorded
-
disableReadTracking
public void disableReadTracking()Description copied from interface:DeltaKVStore
Permanently disable read tracking and discard theReads
associated with this instance.This can be used to save some memory when read tracking information is no longer needed.
Does nothing if read tracking is already disabled.
- Specified by:
disableReadTracking
in interfaceDeltaKVStore
-
withoutReadTracking
Description copied from interface:DeltaKVStore
Temporarily disable read tracking in the current thread while performing the given action.If
allowWrites
is false, then any write attempts byaction
will provoke anIllegalStateException
.Read tracking is disabled only for the current thread, and it ends when this method returns.
- Specified by:
withoutReadTracking
in interfaceDeltaKVStore
- Parameters:
allowWrites
- whether to allow writes (usually this is a bad idea)action
- the action to perform
-
isReadOnly
public boolean isReadOnly()Description copied from interface:DeltaKVStore
Determine if this instance is read-only.- Specified by:
isReadOnly
in interfaceDeltaKVStore
- Returns:
- true if this instance is read-only, otherwise false
-
setReadOnly
public void setReadOnly()Description copied from interface:DeltaKVStore
Configure this instance as read-only.Any subsequent write attempts will result in an
IllegalStateException
.This operation cannot be un-done.
- Specified by:
setReadOnly
in interfaceDeltaKVStore
-
get
public byte[] get(byte[] key) Description copied from interface:KVStore
Get the value associated with the given key, if any.Modifications to the returned
byte[]
array do not affect this instance.- Specified by:
get
in interfaceKVStore
- Overrides:
get
in classAbstractKVStore
- Parameters:
key
- key- Returns:
- value associated with key, or null if not found
-
getRange
Description copied from interface:KVStore
Iterate the key/value pairs in the specified range. The returnedCloseableIterator
'sremove()
method must be supported and should have the same effect as invokingremove()
on the corresponding key.If keys starting with
0xff
are not supported by this instance, andminKey
starts with0xff
, then this method returns an empty iteration.If keys starting with
0xff
are not supported by this instance, andmaxKey
starts with0xff
, then this method behaves as ifmaxKey
were null.The returned
CloseableIterator
is weakly consistent (seejava.util.concurrent
). In short, the returnedCloseableIterator
must not throwConcurrentModificationException
; however, whether or not a "live"CloseableIterator
reflects any modifications made after its creation is implementation dependent. Implementations that do make post-creation updates visible in theCloseableIterator
, even if the update occurs after some delay, must preserve the order in which the modifications actually occurred.The returned
CloseableIterator
itself is not guaranteed to be thread safe; is should only be used in the thread that created it.Invokers of this method are encouraged to
close()
the returned iterators, though this is not required for correct behavior.Modifications to the returned
KVPair
key and valuebyte[]
arrays do not affect this instance.- Specified by:
getRange
in interfaceKVStore
- Parameters:
minKey
- minimum key (inclusive), or null for no minimum (start at the smallest key)maxKey
- maximum key (exclusive), or null for no maximum (end at the largest key)reverse
- true to return key/value pairs in reverse order (i.e., keys descending)- Returns:
- iteration of key/value pairs in the range
minKey
(inclusive) tomaxKey
(exclusive)
-
put
public void put(byte[] key, byte[] value) Description copied from interface:KVStore
Set the value associated with the given key.- Specified by:
put
in interfaceKVStore
- Overrides:
put
in classAbstractKVStore
- Parameters:
key
- keyvalue
- value
-
remove
public void remove(byte[] key) Description copied from interface:KVStore
Remove the key/value pair with the given key, if it exists.- Specified by:
remove
in interfaceKVStore
- Overrides:
remove
in classAbstractKVStore
- Parameters:
key
- key
-
removeRange
public void removeRange(byte[] minKey, byte[] maxKey) Description copied from interface:KVStore
Remove all key/value pairs whose keys are in a given range.The
minKey
must be less than or equal tomaxKey
; if they equal (and not null) then nothing happens; if they are both null then all entries are deleted.If keys starting with
0xff
are not supported by this instance, then:- If
minKey
starts with0xff
, then no change occurs - If
maxKey
starts with0xff
, then this method behaves as ifmaxKey
were null
- Specified by:
removeRange
in interfaceKVStore
- Overrides:
removeRange
in classAbstractKVStore
- Parameters:
minKey
- minimum key (inclusive), or null for no minimummaxKey
- maximum key (exclusive), or null for no maximum
- If
-
encodeCounter
public byte[] encodeCounter(long value) Description copied from interface:KVStore
Encode a counter value into abyte[]
value suitable for use withdecodeCounter()
and/oradjustCounter()
.- Specified by:
encodeCounter
in interfaceKVStore
- Overrides:
encodeCounter
in classAbstractKVStore
- Parameters:
value
- desired counter value- Returns:
- encoded counter value
-
decodeCounter
public long decodeCounter(byte[] bytes) Description copied from interface:KVStore
Decode a counter value previously encoded byencodeCounter()
.- Specified by:
decodeCounter
in interfaceKVStore
- Overrides:
decodeCounter
in classAbstractKVStore
- Parameters:
bytes
- encoded counter value- Returns:
- decoded counter value
-
adjustCounter
public void adjustCounter(byte[] key, long amount) Description copied from interface:KVStore
Adjust the counter at the given key by the given amount.Ideally this operation should behave in a lock-free manner, so that concurrent transactions can invoke it without conflict. However, when lock-free behavior occurs (if at all) depends on the implementation.
If there is no value associated with
key
, orkey
's value is not a valid counter encoding as would be acceptable todecodeCounter()
, then how this operation affectskey
's value is undefined.- Specified by:
adjustCounter
in interfaceKVStore
- Overrides:
adjustCounter
in classAbstractKVStore
- Parameters:
key
- keyamount
- amount to adjust counter value by
-
apply
Description copied from interface:KVStore
Apply all the givenMutations
to this instance.Mutations are always to be applied in this order: removes, puts, counter adjustments.
The implementation in
KVStore
simply iterates over the individual changes and applies them viaremove()
(for removals of a single key),removeRange()
,put()
, and/oradjustCounter()
. Implementations that can process batch updates more efficiently are encouraged to override this method.Unlike
AtomicKVStore.apply()
, this method is not required to apply the mutations atomically. -
clone
-
toString
-