mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
#3 Fixed a number of issue related to bit sets and blocks allocation in VanillaChronicleMap
This commit is contained in:
@@ -133,7 +133,8 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
this.removeReturnsNull = builder.removeReturnsNull();
|
||||
|
||||
this.actualSegments = builder.actualSegments();
|
||||
this.entriesPerSegment = builder.actualEntriesPerSegment();
|
||||
// align by 8 because otherwise sizeOfBitSets() might address less blocks than specified
|
||||
this.entriesPerSegment = align8(builder.actualEntriesPerSegment());
|
||||
this.metaDataBytes = builder.metaDataBytes();
|
||||
this.eventListener = builder.eventListener();
|
||||
|
||||
@@ -158,6 +159,10 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
return (l + 63) & ~63;
|
||||
}
|
||||
|
||||
static int align8(int n) {
|
||||
return (n + 7) & ~7;
|
||||
}
|
||||
|
||||
void initTransients() {
|
||||
keyReaderProvider = Provider.of((Class) originalKeyReader.getClass());
|
||||
keyInteropProvider = Provider.of((Class) originalKeyInterop.getClass());
|
||||
@@ -555,8 +560,8 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
long start = bytes.startAddr() + SEGMENT_HEADER;
|
||||
createHashLookups(start);
|
||||
start += align64(sizeOfMultiMap() + sizeOfMultiMapBitSet()) * multiMapsPerSegment();
|
||||
final NativeBytes bsBytes = new NativeBytes(
|
||||
tmpBytes.objectSerializer(), start, start + sizeOfBitSets(), null);
|
||||
final NativeBytes bsBytes = new NativeBytes(tmpBytes.objectSerializer(),
|
||||
start, start + ((entriesPerSegment + 7) / 8), null);
|
||||
freeList = new SingleThreadedDirectBitSet(bsBytes);
|
||||
start += numberOfBitSets() * sizeOfBitSets();
|
||||
entriesOffset = start - bytes.startAddr();
|
||||
@@ -914,15 +919,23 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
);
|
||||
}
|
||||
}
|
||||
updateNextPosToSearchFrom(ret, blocks);
|
||||
} else {
|
||||
// if bit at nextPosToSearchFrom is clear, it was skipped because
|
||||
// more than 1 block was requested. Don't move nextPosToSearchFrom
|
||||
// in this case. blocks == 1 clause is just a fast path.
|
||||
if (blocks == 1 || freeList.isSet(nextPosToSearchFrom)) {
|
||||
updateNextPosToSearchFrom(ret, blocks);
|
||||
}
|
||||
}
|
||||
// if bit at nextPosToSearchFrom is clear, it was skipped because
|
||||
// more than 1 block was requested. Don't move nextPosToSearchFrom
|
||||
// in this case. blocks == 1 clause is just a fast path.
|
||||
if (blocks == 1 || freeList.isSet(nextPosToSearchFrom))
|
||||
nextPosToSearchFrom = ret + blocks;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void updateNextPosToSearchFrom(int allocated, int blocks) {
|
||||
if ((nextPosToSearchFrom = allocated + blocks) >= freeList.size())
|
||||
nextPosToSearchFrom = 0;
|
||||
}
|
||||
|
||||
private boolean realloc(int fromPos, int oldBlocks, int newBlocks) {
|
||||
if (freeList.allClear(fromPos + oldBlocks, fromPos + newBlocks)) {
|
||||
freeList.set(fromPos + oldBlocks, fromPos + newBlocks);
|
||||
@@ -1188,6 +1201,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
try {
|
||||
hashLookup.clear();
|
||||
freeList.clear();
|
||||
nextPosToSearchFrom = 0;
|
||||
resetSize();
|
||||
} finally {
|
||||
unlock();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.set.ChronicleSet;
|
||||
import net.openhft.chronicle.set.ChronicleSetBuilder;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class Issue3 {
|
||||
|
||||
@Test
|
||||
public void test() throws IOException {
|
||||
Set<Long> set = ChronicleSetBuilder.of(Long.class)
|
||||
.actualSegments(1)
|
||||
.actualEntriesPerSegment(1000)
|
||||
.create();
|
||||
|
||||
Random r = new Random();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 300; j++) {
|
||||
set.add(r.nextLong());
|
||||
}
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user