mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-08-21 08:27:11 +00:00
perf[orm]: lpmap让最小的key可以为0
This commit is contained in:
@@ -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;
|
||||
|
||||
/**
|
||||
* 类型固定的map,key为long,value为IPacket
|
||||
* 其中long必须大于0,value可以为null
|
||||
* 其中long必须大于等于0,value可以为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);
|
||||
|
||||
Reference in New Issue
Block a user