@@ -75,7 +75,7 @@ public class HalfDiskHashMap implements AutoCloseable, Snapshotable, FileStatist
75
75
* starts to exceed the number of buckets times this average number of entries, the
76
76
* map is resized by doubling the number of buckets.
77
77
*/
78
- private static final long GOOD_AVERAGE_BUCKET_ENTRY_COUNT = 32 ;
78
+ private final int goodAverageBucketEntryCount ;
79
79
80
80
/** The limit on the number of concurrent read tasks in {@code endWriting()} */
81
81
private static final int MAX_IN_FLIGHT = 1024 ;
@@ -208,10 +208,11 @@ public HalfDiskHashMap(
208
208
throws IOException {
209
209
this .config = requireNonNull (configuration );
210
210
final MerkleDbConfig merkleDbConfig = this .config .getConfigData (MerkleDbConfig .class );
211
+ this .goodAverageBucketEntryCount = merkleDbConfig .goodAverageBucketEntryCount ();
211
212
// Max number of keys is limited by merkleDbConfig.maxNumberOfKeys. Number of buckets is,
212
213
// on average, GOOD_AVERAGE_BUCKET_ENTRY_COUNT times smaller than the number of keys. To
213
214
// be on the safe side, double that amount and use as a hard limit for bucket index size
214
- final long bucketIndexCapacity = merkleDbConfig .maxNumOfKeys () * 2 / GOOD_AVERAGE_BUCKET_ENTRY_COUNT ;
215
+ final long bucketIndexCapacity = merkleDbConfig .maxNumOfKeys () * 2 / goodAverageBucketEntryCount ;
215
216
this .storeName = storeName ;
216
217
Path indexFile = storeDir .resolve (storeName + BUCKET_INDEX_FILENAME_SUFFIX );
217
218
// create bucket pool
@@ -274,7 +275,7 @@ public HalfDiskHashMap(
274
275
// create store dir
275
276
Files .createDirectories (storeDir );
276
277
// calculate number of entries we can store in a disk page
277
- final int minimumBuckets = (int ) (initialCapacity / GOOD_AVERAGE_BUCKET_ENTRY_COUNT );
278
+ final int minimumBuckets = (int ) (initialCapacity / goodAverageBucketEntryCount );
278
279
// numOfBuckets is the nearest power of two greater than minimumBuckets with a min of 2
279
280
setNumberOfBuckets (Math .max (Integer .highestOneBit (minimumBuckets ) * 2 , 2 ));
280
281
// create new index
@@ -886,15 +887,15 @@ private Bucket readBucket(final int bucketIndex) throws IOException {
886
887
887
888
/**
888
889
* Check if this map should be resized, given the new virtual map size. If the new map size
889
- * exceeds 80% of the current number of buckets times {@link #GOOD_AVERAGE_BUCKET_ENTRY_COUNT },
890
+ * exceeds 80% of the current number of buckets times {@link #goodAverageBucketEntryCount },
890
891
* the map is resized by doubling the number of buckets.
891
892
*
892
893
* @param firstLeafPath The first leaf virtual path
893
894
* @param lastLeafPath The last leaf virtual path
894
895
*/
895
896
public void resizeIfNeeded (final long firstLeafPath , final long lastLeafPath ) {
896
897
final long currentSize = lastLeafPath - firstLeafPath + 1 ;
897
- if (currentSize / numOfBuckets .get () <= GOOD_AVERAGE_BUCKET_ENTRY_COUNT * 80 / 100 ) {
898
+ if (currentSize / numOfBuckets .get () <= goodAverageBucketEntryCount * 80 / 100 ) {
898
899
// No need to resize yet
899
900
return ;
900
901
}
@@ -928,10 +929,10 @@ public void printStats() {
928
929
"""
929
930
HalfDiskHashMap Stats {
930
931
numOfBuckets = {}
931
- GOOD_AVERAGE_BUCKET_ENTRY_COUNT = {}
932
+ goodAverageBucketEntryCount = {}
932
933
}""" ,
933
934
numOfBuckets ,
934
- GOOD_AVERAGE_BUCKET_ENTRY_COUNT );
935
+ goodAverageBucketEntryCount );
935
936
}
936
937
937
938
public DataFileCollection getFileCollection () {
@@ -954,6 +955,11 @@ private void setNumberOfBuckets(final int newValue) {
954
955
bucketMaskBits .set (trailingZeroes );
955
956
}
956
957
958
+ // For testing purposes
959
+ int getNumOfBuckets () {
960
+ return numOfBuckets .get ();
961
+ }
962
+
957
963
/**
958
964
* Computes which bucket a key with the given hash falls. Depends on the fact the numOfBuckets
959
965
* is a power of two. Based on same calculation that is used in java HashMap.
0 commit comments