public class ChiseledMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>
Dead simple persistent ordered map. It is thread safe, via coarse synchronization on writes. Reads are unsynchronized, though the underlying FileChannel is shared. Deletes do not reclaim file space; they simply stop referencing the block. Writes are CRC checked on restart, file is truncated to match the valid length.
This class is useful for prototyping when you need a persistent store and don't want to bother much. You provide a file, and optionally an encoder and decoder, and you can shove Objects in a sorted map structure that will serve get()s from disk, and save mutations to disk. Basically, every change is written to a log, with crc. Old entries are just left there; no garbage collection is done. So it is not useful for massive stores, or fast changing ones, but for prototyping it's quite useful.
Null values are not allowed. An in-memory sorted list keeps keys/disk addresses for lookup. On restart, the entire log file is traversed, rebuilding the in memory picture of keys to locations.
The core methods are ioGet(), ioSet(), and ioUnset(); these throw IOExceptions on ... IO exceptions. The Map methods wrap these methods and throw the unchecked RuntimeIOException.
| Modifier and Type | Class and Description |
|---|---|
static interface |
ChiseledMap.Decoder<KK,VV>
Decode a byte array into a key/value pair.
|
static interface |
ChiseledMap.Encoder<KK,VV>
Encode a key/value (here you must handle null values) into a ByteBuffer.
|
static class |
ChiseledMap.OpenOption
Open methods.
|
static class |
ChiseledMap.RuntimeIOException
For the map methods, IOExceptions are wrapped in this.
|
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>| Modifier and Type | Field and Description |
|---|---|
static ChiseledMap.Decoder |
DECODE_JAVA_SER
Default java deserialization.
|
static int |
DIGEST_MASK |
static ChiseledMap.Encoder |
ENCODE_JAVA_SER
Default java serialization.
|
static byte[] |
HDR |
| Constructor and Description |
|---|
ChiseledMap(File file,
ChiseledMap.OpenOption open,
Comparator<K> comp) |
ChiseledMap(File file,
ChiseledMap.OpenOption open,
Comparator<K> comp,
ChiseledMap.Encoder<K,V> encoder,
ChiseledMap.Decoder<K,V> decoder)
Constructor.
|
| Modifier and Type | Method and Description |
|---|---|
long |
bytesOnDisk()
File footprint on disk.
|
void |
clear() |
void |
close()
Close this TinyKVMap.
|
V |
compute(K key,
BiFunction<? super K,? super V,? extends V> remappingFunction) |
V |
computeIfAbsent(K key,
Function<? super K,? extends V> mappingFunction) |
V |
computeIfPresent(K key,
BiFunction<? super K,? super V,? extends V> remappingFunction) |
boolean |
containsKey(Object key) |
Iterable<Map.Entry<K,V>> |
entries()
Entry iterator.
|
long |
entriesOnDisk()
Number of entries actually on the disk, even if invalid.
|
Set<Map.Entry<K,V>> |
entrySet() |
void |
flush()
Flush any buffered changes to disk, fsync.
|
V |
get(Object key) |
File |
getFile()
File being used.
|
V |
ioGet(Object key)
Retrieve the value associated with a specified key.
|
boolean |
ioSet(K key,
V v)
Associate a key to a value
|
V |
ioUnset(K key)
Clear a value.
|
V |
merge(K key,
V value,
BiFunction<? super V,? super V,? extends V> remappingFunction) |
V |
put(K key,
V value) |
V |
putIfAbsent(K key,
V value) |
V |
remove(Object key) |
boolean |
remove(Object key,
Object value) |
V |
replace(K key,
V value) |
boolean |
replace(K key,
V oldValue,
V newValue) |
boolean |
set(K key,
V value)
Unchecked verson of ioSet()
|
int |
size() |
ChiseledMap<K,V> |
snapshot(File f)
Copy only live entries to another file.
|
String |
toString() |
clone, containsValue, equals, hashCode, isEmpty, keySet, putAll, valuesfinalize, getClass, notify, notifyAll, wait, wait, waitforEach, getOrDefault, replaceAllpublic static final int DIGEST_MASK
public static final byte[] HDR
public static ChiseledMap.Encoder ENCODE_JAVA_SER
public static ChiseledMap.Decoder DECODE_JAVA_SER
public ChiseledMap(File file, ChiseledMap.OpenOption open, Comparator<K> comp) throws IOException
IOExceptionpublic ChiseledMap(File file, ChiseledMap.OpenOption open, Comparator<K> comp, ChiseledMap.Encoder<K,V> encoder, ChiseledMap.Decoder<K,V> decoder) throws IOException
file - File to use.open - Open modecomp - Comparator to use. If null, Comparator.naturalOrder() is used.encoder - Encoder to use. If null, default Java serializer is used.decoder - Decoder to use. If null, default Java deserializer is used.IOException - on exceptionpublic long entriesOnDisk()
public File getFile()
public long bytesOnDisk()
throws IOException
IOException - on exceptionpublic void close()
throws IOException
IOException - on exceptionpublic int size()
public Iterable<Map.Entry<K,V>> entries()
public void flush()
throws IOException
IOException - If you get an IOException, literally no guarantees
can be made about the on disk state of the data.public V ioGet(Object key) throws IOException
key - key valueIOException - on exceptionpublic V ioUnset(K key) throws IOException
key - key valueIOException - on exceptionpublic boolean ioSet(K key, V v) throws IOException
key - key valuev - value -- cannot be null.IOException - on exceptionpublic ChiseledMap<K,V> snapshot(File f) throws IOException
f - dest fileIOException - on exceptionpublic boolean containsKey(Object key)
containsKey in interface Map<K,V>containsKey in class AbstractMap<K,V>public boolean set(K key, V value)
key - key valuevalue - value to associate with keypublic void clear()
public V putIfAbsent(K key, V value)
putIfAbsent in interface ConcurrentMap<K,V>putIfAbsent in interface Map<K,V>public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
computeIfAbsent in interface ConcurrentMap<K,V>computeIfAbsent in interface Map<K,V>public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
computeIfPresent in interface ConcurrentMap<K,V>computeIfPresent in interface Map<K,V>public String toString()
toString in class AbstractMap<K,V>Copyright © 2020. All rights reserved.