MCPcopy Create free account
hub / github.com/cschanck/single-file-java / ChiseledMap

Class ChiseledMap

src/main/java/org/sfj/ChiseledMap.java:67–625  ·  view source on GitHub ↗

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 ma

Source from the content-addressed store, hash-verified

65 * @author cschanck
66 */
67public class ChiseledMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
68
69 public static final int DIGEST_MASK = 0x7fffffff;
70
71 public static final byte[] HDR = "(-:AnonymousBC:ChiseledMap-)".getBytes(StandardCharsets.US_ASCII);
72
73 /**
74 * Open methods.
75 */
76 public enum OpenOption {
77 MUST_BE_NEW, MUST_EXIST, DONT_CARE
78 }
79
80 /**
81 * For the map methods, IOExceptions are wrapped in this.
82 */
83 public static class RuntimeIOException extends RuntimeException {
84 public RuntimeIOException(Throwable cause) {
85 super(cause);
86 }
87 }
88
89 /**
90 * Encode a key/value (here you must handle null values) into a ByteBuffer.
91 * @param <KK> key type
92 * @param <VV> value type
93 */
94 @FunctionalInterface
95 public interface Encoder<KK, VV> {
96 ByteBuffer encode(KK k, VV v) throws IOException;
97 }
98
99 /**
100 * Decode a byte array into a key/value pair.
101 * @param <KK> key type
102 * @param <VV> value type
103 */
104 @FunctionalInterface
105 public interface Decoder<KK, VV> {
106 Entry<KK, VV> decode(byte[] bArray) throws IOException;
107 }
108
109 private final CRC32 digest;
110 private final Comparator<K> comp;
111 private final FileChannel fc;
112 private final ConcurrentSkipListMap<K, Long> map;
113 private final ByteBuffer lenBuffer = ByteBuffer.allocate(4);
114 private final ByteBuffer digestBuffer = ByteBuffer.allocate(4);
115 private final ByteBuffer writeBuffer = ByteBuffer.allocateDirect(1024 * 1024);
116 private final File file;
117 private long currentWritePos = HDR.length;
118 private long nextWritePos = HDR.length;
119 private volatile int pendingWrites = 0;
120 private final Encoder<K, V> encoder;
121 private final Decoder<K, V> decoder;
122 private long entriesOnDisk = 0;
123
124 /**

Callers

nothing calls this directly

Calls 1

flushMethod · 0.45

Tested by

no test coverage detected