Skip to content

Commit 30b4cc0

Browse files
Add OffHeapDemoWithEvictionAndOperationCounters.
1 parent 73fb900 commit 30b4cc0

File tree

3 files changed

+109
-3
lines changed

3 files changed

+109
-3
lines changed

examples/map/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
* Put 20,000 CacheObject instances into a ConcurrentHashMap.
66
* Each CacheObject instance contains a random string of length 500KB.
77
* This is a total of 10 GB of data stored on the normal Java heap.
8-
* This application does not make use of any features of the native_memory_allocator library. It is provided for comparison with NativeMemoryMap demos using off-heap storage.
8+
* This application does not make use of any features of the native_memory_allocator library. It is provided for
9+
comparison with NativeMemoryMap demos using off-heap storage.
910

1011
## OffHeapDemo
1112

@@ -17,4 +18,8 @@
1718
## OffHeapDemoWithEviction
1819

1920
* Same as OffHeapDemo but uses the Caffeine backend with maximumSize of 10,000 entries.
20-
* Expect 10,000 entries at end of run with 10,000 total evictions.
21+
* Expect 10,000 entries at end of run with 10,000 total evictions.
22+
23+
## OffHeapDemoWithEvictionAndOperationCounters
24+
25+
* Same as OffHeapDemoWithEviction but enables operation counters and logs them at the end of the demo.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.target.nativememoryallocator.examples.map
2+
3+
import com.target.nativememoryallocator.allocator.NativeMemoryAllocatorBuilder
4+
import com.target.nativememoryallocator.examples.map.utils.CacheObject
5+
import com.target.nativememoryallocator.examples.map.utils.CacheObjectSerializer
6+
import com.target.nativememoryallocator.examples.map.utils.buildRandomString
7+
import com.target.nativememoryallocator.map.NativeMemoryMapBackend
8+
import com.target.nativememoryallocator.map.NativeMemoryMapBuilder
9+
import kotlinx.coroutines.*
10+
import mu.KotlinLogging
11+
import kotlin.random.Random
12+
13+
private val logger = KotlinLogging.logger {}
14+
15+
16+
/**
17+
* Same as [OffHeapDemoWithEviction] but enables operation counters
18+
*/
19+
class OffHeapDemoWithEvictionAndOperationCounters {
20+
21+
private val numEntries = 20_000
22+
23+
private val randomIndex = Random.nextInt(0, numEntries)
24+
25+
private val nativeMemoryAllocator = NativeMemoryAllocatorBuilder(
26+
pageSizeBytes = 4_096, // 4 KB
27+
nativeMemorySizeBytes = (20L * 1_024L * 1_024L * 1_024L), // 20 GB
28+
).build()
29+
30+
private val nativeMemoryMap = NativeMemoryMapBuilder<Int, CacheObject>(
31+
valueSerializer = CacheObjectSerializer(),
32+
nativeMemoryAllocator = nativeMemoryAllocator,
33+
backend = NativeMemoryMapBackend.CAFFEINE,
34+
caffeineConfigFunction = { caffeineConfigBuilder ->
35+
caffeineConfigBuilder
36+
.maximumSize(10_000)
37+
.recordStats()
38+
},
39+
enableOperationCounters = true
40+
).build()
41+
42+
private fun putValueIntoMap(i: Int) {
43+
if ((i % 100) == 0) {
44+
logger.info { "put i = $i" }
45+
}
46+
val value = buildRandomString(length = 500 * 1_024)
47+
if (i == randomIndex) {
48+
logger.info { "put randomIndex = $randomIndex value.length = ${value.length}" }
49+
logger.info { "value.substring(0,20) = ${value.substring(0, 20)}" }
50+
}
51+
nativeMemoryMap.put(
52+
key = i,
53+
value = CacheObject(
54+
s = value,
55+
),
56+
)
57+
}
58+
59+
suspend fun run() {
60+
logger.info { "begin run randomIndex = $randomIndex" }
61+
62+
coroutineScope {
63+
(0 until numEntries).forEach { i ->
64+
launch {
65+
putValueIntoMap(i = i)
66+
}
67+
}
68+
}
69+
70+
logger.info { "nativeMemoryMap.size = ${nativeMemoryMap.size}" }
71+
logger.info { "nativeMemoryAllocator.nativeMemoryAllocatorMetadata = ${nativeMemoryAllocator.nativeMemoryAllocatorMetadata}" }
72+
73+
val randomIndexValue = nativeMemoryMap.get(key = randomIndex)
74+
randomIndexValue?.let {
75+
logger.info { "get randomIndex = $randomIndex" }
76+
logger.info { "randomIndexValue.s.length = ${it.s.length}" }
77+
logger.info { "randomIndexValue.s.substring(0,20) = ${it.s.substring(0, 20)}" }
78+
}
79+
80+
logger.info { "caffeine eviction count = ${nativeMemoryMap.stats.caffeineStats?.evictionCount()}" }
81+
82+
logger.info { "nativeMemoryMap.operationCounters = ${nativeMemoryMap.operationCounters}" }
83+
84+
while (true) {
85+
delay(1_000)
86+
}
87+
}
88+
89+
}
90+
91+
suspend fun main() {
92+
withContext(Dispatchers.Default) {
93+
OffHeapDemoWithEvictionAndOperationCounters().run()
94+
}
95+
}

src/main/kotlin/com/target/nativememoryallocator/map/impl/OperationCountedNativeMemoryMapImpl.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ internal class OperationCountersImpl(
1818
override val numDeletesNoChange: AtomicLong = AtomicLong(0),
1919
override val numGetsNullValue: AtomicLong = AtomicLong(0),
2020
override val numGetsNonNullValue: AtomicLong = AtomicLong(0),
21-
) : NativeMemoryMapOperationCounters
21+
) : NativeMemoryMapOperationCounters {
22+
23+
override fun toString(): String {
24+
return "OperationCountersImpl(numPutsNoChange=$numPutsNoChange, numPutsFreedBuffer=$numPutsFreedBuffer, numPutsReusedBuffer=$numPutsReusedBuffer, numPutsNewBuffer=$numPutsNewBuffer, numDeletesFreedBuffer=$numDeletesFreedBuffer, numDeletesNoChange=$numDeletesNoChange, numGetsNullValue=$numGetsNullValue, numGetsNonNullValue=$numGetsNonNullValue)"
25+
}
26+
27+
}
2228

2329
/**
2430
* Implementation of [NativeMemoryMap] supporting operation counters.

0 commit comments

Comments
 (0)