K
- the map key typeV
- the map value typeR
- methods return type, used for communication between lower- and higher-level SPIpublic interface MapEntryOperations<K,V,R>
ChronicleMap
entries. All ChronicleMap
modifications operate via an instance of this interface:
map.put()
, map.compute()
, map.remove()
iterator.remove()
.ChronicleMap
reconciliation operations:
see MapRemoteOperations
.
By default remove(net.openhft.chronicle.map.MapEntry<K, V>)
, insert(net.openhft.chronicle.map.MapAbsentEntry<K, V>, net.openhft.chronicle.hash.Data<V>)
and replaceValue(net.openhft.chronicle.map.MapEntry<K, V>, net.openhft.chronicle.hash.Data<V>)
return null
,
but subclasses could return something more sensible, to be used in higher-level SPI interfaces,
namely MapMethods
and MapRemoteOperations
. For example, in bidirectional map
implementation (i. e. a map that preserves the uniqueness of its values as well as that of
its keys), that includes two ChronicleMaps
, the MapEntryOperations
' methods return
type could be used to indicate if we were successful to lock both maps before performing
the update:
enum DualLockSuccess {SUCCESS, FAIL}
class BiMapEntryOperations<K, V>
implements MapEntryOperations<K, V, DualLockSuccess>
{
ChronicleMap<V, K>
reverse;
public void setReverse(ChronicleMap<V, K>
reverse) {
this.reverse = reverse;
}
@Override
public DualLockSuccess remove(@NotNull MapEntry<K, V>
entry) {
try (ExternalMapQueryContext<V, K, ?>
rq = reverse.queryContext(entry.value())) {
if (!rq.updateLock().tryLock()) {
if (entry.context() instanceof MapQueryContext)
return FAIL;
throw new IllegalStateException("Concurrent modifications to reverse map " +
"during remove during iteration");
}
MapEntry<V, K>
reverseEntry = rq.entry();
if (reverseEntry != null) {
entry.doRemove();
reverseEntry.doRemove();
return SUCCESS;
} else {
throw new IllegalStateException(entry.key() + " maps to " + entry.value() +
", but in the reverse map this value is absent");
}
}
}
// ... other methods
}
class BiMapMethods<K, V>
implements MapMethods<K, V, DualLockSuccess>
{
@Override
public void remove(MapQueryContext<K, V, DualLockSuccess>
q,
ReturnValue<V>
returnValue) {
while (true) {
q.updateLock().lock();
try {
MapEntry<K, V>
entry = q.entry();
if (entry != null) {
returnValue.returnValue(entry.value());
if (q.remove(entry) == SUCCESS)
return;
}
} finally {
q.readLock().unlock();
}
}
}
// ... other methods
}
Modifier and Type | Method and Description |
---|---|
default R |
insert(MapAbsentEntry<K,V> absentEntry,
Data<V> value)
Inserts the new entry into the map, of
the key from
the given insertion context (absentEntry ) and the given value . |
default R |
remove(MapEntry<K,V> entry)
Removes the given entry from the map.
|
default R |
replaceValue(MapEntry<K,V> entry,
Data<V> newValue)
Replaces the given entry's value with the new one.
|
default R remove(@NotNull MapEntry<K,V> entry)
entry
- the entry to removeMapMethods
implementationIllegalStateException
- if some locking/state conditions required to perform remove
operation are not metRuntimeException
- if removal was unconditionally unsuccessful due to any reasonMapEntry.doRemove()
on the given entry
and returns null
.default R replaceValue(@NotNull MapEntry<K,V> entry, Data<V> newValue)
entry
- the entry to replace the value inMapMethods
implementationIllegalStateException
- if some locking/state conditions required to perform replace
operation are not metRuntimeException
- if value replacement was unconditionally unsuccessful due
to any reasonentry.doReplaceValue(newValue)
and returns null
.default R insert(@NotNull MapAbsentEntry<K,V> absentEntry, Data<V> value)
the key
from
the given insertion context (absentEntry
) and the given value
.MapMethods
implementationIllegalStateException
- if some locking/state conditions required to perform insertion
operation are not metRuntimeException
- if insertion was unconditionally unsuccessful due to any reasonabsentEntry.doInsert(value)
and returns null
.Copyright © 2021. All rights reserved.