perf[orm]: lpmap让最小的key可以为0

This commit is contained in:
jaysunxiao
2021-09-03 17:12:39 +08:00
parent 7c5136bccf
commit b795015ba0
6 changed files with 48 additions and 43 deletions
@@ -29,7 +29,7 @@ public class ConcurrentFileChannelHeapMap<V extends IPacket> implements LpMap<V>
private ConcurrentHeapMap<V> concurrentHeapMap;
public ConcurrentFileChannelHeapMap(String dbPath, int initialCapacity, Class<V> clazz) {
public ConcurrentFileChannelHeapMap(String dbPath, Class<V> clazz) {
fileChannelMap = new FileChannelMap<>(dbPath, clazz);
concurrentHeapMap = new ConcurrentHeapMap<>();
@@ -14,6 +14,7 @@ package com.zfoo.orm.lpmap;
import com.zfoo.protocol.IPacket;
import java.util.List;
import java.util.function.BiConsumer;
/**
@@ -49,6 +50,10 @@ public class ConcurrentFileChannelMap<V extends IPacket> implements LpMap<V> {
return fileChannelMap.get(key);
}
public synchronized List<V> getFrom(long startKey, long endKey) {
return fileChannelMap.getFrom(startKey, endKey);
}
@Override
public synchronized long getMaxIndex() {
return fileChannelMap.getMaxIndex();
@@ -14,6 +14,7 @@ package com.zfoo.orm.lpmap;
import com.zfoo.protocol.IPacket;
import com.zfoo.protocol.ProtocolManager;
import com.zfoo.protocol.exception.RunException;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolAnalysis;
import com.zfoo.protocol.util.FileUtils;
@@ -28,6 +29,9 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
/**
@@ -61,18 +65,13 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
this.indexFileRandomAccess = new RandomAccessFile(indexFile, "rw");
this.indexFileChannel = this.indexFileRandomAccess.getChannel();
if (indexFileChannel.size() <= 0) {
indexFileRandomAccess.writeLong(0L);
indexFileRandomAccess.writeLong(0L);
}
var protocolId = ProtocolAnalysis.getProtocolIdByClass(clazz);
protocolRegistration = ProtocolManager.getProtocol(protocolId);
indexBuffer = ByteBufAllocator.DEFAULT.ioBuffer(16);
dbBuffer = ByteBufAllocator.DEFAULT.ioBuffer(100);
maxIndex = readMaxIndex();
maxIndex = indexFileChannel.size() / 16;
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -87,11 +86,7 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
if (key <= maxIndex) {
previousValue = get(key);
} else {
for (var i = maxIndex + 1; i < key; i++) {
resetKey(i);
}
maxIndex = key;
setMaxIndex(maxIndex);
}
setKeyValue(key, packet);
@@ -136,6 +131,35 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
}
}
/**
* 获取从startKey到endKey的值
*
* @param startKey inclusive
* @param endKey exclusive
* @return list
*/
public List<V> getFrom(long startKey, long endKey) {
checkKey(startKey);
checkKey(endKey);
if (startKey >= endKey) {
throw new RunException("range error startKey < endKey");
}
if (startKey > maxIndex) {
return Collections.emptyList();
}
var list = new ArrayList<V>();
for (var i = startKey; i < endKey; i++) {
var value = get(i);
if (value != null) {
list.add(value);
}
}
return list;
}
@Override
public long getMaxIndex() {
return maxIndex;
@@ -144,15 +168,12 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
@Override
public long getIncrementIndex() {
maxIndex++;
// index索引文件的头16个字节是当前index的大小
setMaxIndex(maxIndex);
return maxIndex;
}
@Override
public void forEach(BiConsumer<Long, V> biConsumer) {
for (var i = 1L; i < getMaxIndex(); i++) {
for (var i = 0L; i < getMaxIndex(); i++) {
var value = get(i);
if (value != null) {
biConsumer.accept(i, value);
@@ -163,7 +184,8 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
@Override
public void clear() {
try {
setMaxIndex(0);
maxIndex = 0;
indexFileRandomAccess.setLength(0);
dbFileRandomAccess.setLength(0);
} catch (IOException e) {
throw new RuntimeException(e);
@@ -171,17 +193,6 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
}
private long readMaxIndex() {
try {
clearByteBuf();
indexBuffer.writeBytes(indexFileChannel, 0, 8);
return indexBuffer.readLong();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
clearByteBuf();
}
}
protected void setKeyValue(long key, V value) {
try {
@@ -220,18 +231,6 @@ public class FileChannelMap<V extends IPacket> implements LpMap<V>, Closeable {
}
}
protected void setMaxIndex(long maxIndex) {
try {
clearByteBuf();
indexBuffer.writeLong(maxIndex);
indexFileChannel.write(indexBuffer.nioBuffer(), 0);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
clearByteBuf();
}
}
protected void clearByteBuf() {
indexBuffer.clear();
dbBuffer.clear();
@@ -19,7 +19,7 @@ import java.util.function.BiConsumer;
/**
* 类型固定的mapkey为longvalue为IPacket
* 其中long必须大于0value可以为null
* 其中long必须大于等于0value可以为null
*
* @author jaysunxiao
* @version 3.0
@@ -53,8 +53,8 @@ public interface LpMap<V extends IPacket> {
void clear();
default void checkKey(long key) {
if (key <= 0) {
throw new RunException("key[{}]能为负数或0", key);
if (key < 0) {
throw new RunException("key[{}]能为大于等于0的正数", key);
}
}
@@ -34,6 +34,7 @@ public class FileChannelMapTest {
var myPacket = new MyPacket();
myPacket.setA(9999);
map.put(0, myPacket);
map.put(1, myPacket);
map.put(2, myPacket);
map.put(3, myPacket);
@@ -29,7 +29,7 @@ public class HeapMapTest {
var map = new HeapMap<MyPacket>(10);
var myPacket = new MyPacket();
var packet = map.put(1, myPacket);
var packet = map.put(0, myPacket);
Assert.assertNull(packet);
packet = map.put(3, myPacket);