synchronized void save() { Long lastKey = this.lastSyncKey; Set<Entry<Long, RedoLogValue>> entrySet = lastKey == null ? skipListMap.entrySet() : skipListMap.tailMap(lastKey, false).entrySet(); if (!entrySet.isEmpty()) { WriteBuffer buff = WriteBufferPool.poll(); try { for (Entry<Long, RedoLogValue> e : entrySet) { lastKey = e.getKey(); keyType.write(buff, lastKey); valueType.write(buff, e.getValue()); } int chunkLength = buff.position(); if (chunkLength > 0) { buff.limit(chunkLength); buff.position(0); fileStorage.writeFully(pos, buff.getBuffer()); pos += chunkLength; fileStorage.sync(); } this.lastSyncKey = lastKey; } finally { WriteBufferPool.offer(buff); } } }
RedoLogChunk(int id, Map<String, String> config) { this.id = id; // 不使用ObjectDataType,因为ObjectDataType需要自动侦测,会有一些开销 this.keyType = new RedoLogKeyType(); this.valueType = new RedoLogValueType(); skipListMap = new ConcurrentSkipListMap<>(new KeyComparator<Long>(keyType)); String chunkFileName = getChunkFileName(config, id); fileStorage = new FileStorage(); fileStorage.open(chunkFileName, config); pos = fileStorage.size(); if (pos > 0) read(); }
private void read() { ByteBuffer buffer = fileStorage.readFully(0, (int) pos); while (buffer.remaining() > 0) { Long k = (Long) keyType.read(buffer); RedoLogValue v = (RedoLogValue) valueType.read(buffer); skipListMap.put(k, v); lastSyncKey = k; } }
@Override public String toString() { return "RedoLogChunk[" + id + ", " + fileStorage.getFileName() + "]"; }
void close() { save(); fileStorage.close(); }