mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix(level-hash): allow configuring load factor threshold for auto expand
This commit is contained in:
@@ -39,7 +39,7 @@ import androidx.annotation.FloatRange
|
||||
* as well. This results in decreased access performance and insertion failures.
|
||||
* It is **recommended** to enable [AbstractLevelHashBuilder.autoExpand] which
|
||||
* will automatically expand the level hash when the load factor reaches a certain
|
||||
* threshold (specifically, when the top level is full).
|
||||
* threshold ([LevelHash.loadFactor]).
|
||||
*
|
||||
* @param K The key type.
|
||||
* @param V The value type.
|
||||
@@ -164,6 +164,11 @@ interface LevelHash<K : Any, V : Any?> : AutoCloseable {
|
||||
*/
|
||||
const val BUCKET_SIZE_DEFAULT = 4
|
||||
|
||||
/**
|
||||
* Default load factor threshold for auto expand.
|
||||
*/
|
||||
const val AUTO_EXPAND_LOAD_FACTOR_THRESHOLD: Float = 0.92f
|
||||
|
||||
/**
|
||||
* Build an in-memory level hash.
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,7 @@ abstract class AbstractLevelHashBuilder<K : Any, V : Any?> {
|
||||
protected var hashFn: LevelHashFn<K>? = null
|
||||
protected var uniqueKeys = false
|
||||
protected var autoExpand = true
|
||||
protected var loadFactorForAutoExpand = LevelHash.AUTO_EXPAND_LOAD_FACTOR_THRESHOLD
|
||||
protected var seedGenerator: SeedGeneratorFn = ::levelHashDefaultSeeds
|
||||
|
||||
/**
|
||||
@@ -112,7 +113,8 @@ class InMemoryHashBuilder<K : Any, V : Any?> :
|
||||
levelHashFn = hashFn!!,
|
||||
seeds = seedGenerator(),
|
||||
uniqueKeys = uniqueKeys,
|
||||
autoExpand = autoExpand
|
||||
autoExpand = autoExpand,
|
||||
loadFactorForAutoExpand = loadFactorForAutoExpand,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -170,6 +172,7 @@ class PersistentHashBuilder<K : Any, V : Any?> :
|
||||
bucketSize = bucketSize,
|
||||
uniqueKeys = uniqueKeys,
|
||||
autoExpand = autoExpand,
|
||||
loadFactorForAutoExpand = loadFactorForAutoExpand,
|
||||
levelHashFn = hashFn!!,
|
||||
seeds = seeds,
|
||||
keyExternalizer = keyExternalizer,
|
||||
|
||||
+2
-1
@@ -38,6 +38,7 @@ internal abstract class AbstractLevelHash<K : Any, V : Any?> internal constructo
|
||||
final override val bucketSize: Int,
|
||||
protected val uniqueKeys: Boolean,
|
||||
protected val autoExpand: Boolean,
|
||||
protected val loadFactorForAutoExpand: Float,
|
||||
protected val levelHashFn: LevelHashFn<K>,
|
||||
protected val seeds: Pair<HashT, HashT>,
|
||||
) : LevelHash<K, V> {
|
||||
@@ -123,7 +124,7 @@ internal abstract class AbstractLevelHash<K : Any, V : Any?> internal constructo
|
||||
|
||||
override fun insert(key: K, value: V): Boolean {
|
||||
|
||||
if (loadFactor() >= 0.92 && autoExpand) {
|
||||
if (loadFactor() >= loadFactorForAutoExpand && autoExpand) {
|
||||
check(expand()) {
|
||||
"Failed to expand the level hash"
|
||||
}
|
||||
|
||||
+10
-2
@@ -34,10 +34,18 @@ internal class InMemoryLevelHash<K : Any, V : Any?>(
|
||||
bucketSize: Int,
|
||||
uniqueKeys: Boolean,
|
||||
autoExpand: Boolean,
|
||||
loadFactorForAutoExpand: Float,
|
||||
levelHashFn: LevelHashFn<K>,
|
||||
seeds: Pair<HashT, HashT>,
|
||||
) : AbstractLevelHash<K, V>(levelSize, bucketSize, uniqueKeys, autoExpand,
|
||||
levelHashFn, seeds) {
|
||||
) : AbstractLevelHash<K, V>(
|
||||
levelSize,
|
||||
bucketSize,
|
||||
uniqueKeys,
|
||||
autoExpand,
|
||||
loadFactorForAutoExpand,
|
||||
levelHashFn,
|
||||
seeds
|
||||
) {
|
||||
|
||||
private val levels = Array(LEVEL_COUNT) { levelIndex ->
|
||||
allocateLevel(levelSize, levelIndex, bucketSize)
|
||||
|
||||
+10
-3
@@ -34,14 +34,21 @@ internal class PersistentLevelHash<K : Any, V : Any?>(
|
||||
bucketSize: Int,
|
||||
uniqueKeys: Boolean,
|
||||
autoExpand: Boolean,
|
||||
loadFactorForAutoExpand: Float,
|
||||
levelHashFn: LevelHashFn<K>,
|
||||
seeds: Pair<HashT, HashT>,
|
||||
keyExternalizer: DataExternalizer<K>,
|
||||
valueExternalizer: DataExternalizer<V>,
|
||||
indexFile: File,
|
||||
) : AbstractLevelHash<K, V>(levelSize = levelSize, bucketSize = bucketSize,
|
||||
uniqueKeys = uniqueKeys, autoExpand = autoExpand, levelHashFn = levelHashFn,
|
||||
seeds = seeds) {
|
||||
) : AbstractLevelHash<K, V>(
|
||||
levelSize = levelSize,
|
||||
bucketSize = bucketSize,
|
||||
uniqueKeys = uniqueKeys,
|
||||
autoExpand = autoExpand,
|
||||
loadFactorForAutoExpand = loadFactorForAutoExpand,
|
||||
levelHashFn = levelHashFn,
|
||||
seeds = seeds
|
||||
) {
|
||||
|
||||
@VisibleForTesting
|
||||
internal val io = PersistentLevelHashIO(indexFile, levelSize, bucketSize, keyExternalizer,
|
||||
|
||||
+1
@@ -42,6 +42,7 @@ private val logger = LoggerFactory.getLogger(PersistentLevelHashIO::class.java)
|
||||
// improved performance when seeking through the file.
|
||||
// TODO: The above is also applicable for the keymap file when the level hash is
|
||||
// expanded and new regions for the levels are allocated.
|
||||
// TODO: Allow concurrent access to the level hash.
|
||||
|
||||
/**
|
||||
* This class is responsible for performing the IO operations for the level hash
|
||||
|
||||
Reference in New Issue
Block a user