mirror of
https://github.com/redis/redis.git
synced 2026-01-14 08:27:58 -05:00
All the defrag allocations API expects to get a value and replace it, leaving the old value untouchable. In some cases a value might be shared between multiple keys, in such cases we can not simply replace it when the defrag callback is called. To allow support such use cases, the PR adds two new API's to the defrag API: 1. `RM_DefragAllocRaw` - allocate memory base on a given size. 2. `RM_DefragFreeRaw` - Free the given pointer. Those API's avoid using tcache so they operate just like `RM_DefragAlloc` but allows the user to split the allocation and the memory free operations into two stages and control when those happen. In addition the PR adds new API to allow the module to receive notifications when defrag start and end: `RM_RegisterDefragCallbacks` Those callbacks are the same as `RM_RegisterDefragFunc` but promised to be called and the start and the end of the defrag process.
55 lines
2.2 KiB
Tcl
55 lines
2.2 KiB
Tcl
set testmodule [file normalize tests/modules/defragtest.so]
|
|
|
|
start_server {tags {"modules"} overrides {{save ""}}} {
|
|
r module load $testmodule 10000
|
|
r config set hz 100
|
|
r config set active-defrag-ignore-bytes 1
|
|
r config set active-defrag-threshold-lower 0
|
|
r config set active-defrag-cycle-min 99
|
|
|
|
# try to enable active defrag, it will fail if redis was compiled without it
|
|
catch {r config set activedefrag yes} e
|
|
if {[r config get activedefrag] eq "activedefrag yes"} {
|
|
|
|
test {Module defrag: simple key defrag works} {
|
|
r frag.create key1 1 1000 0
|
|
|
|
after 2000
|
|
set info [r info defragtest_stats]
|
|
assert {[getInfoProperty $info defragtest_datatype_attempts] > 0}
|
|
assert_equal 0 [getInfoProperty $info defragtest_datatype_resumes]
|
|
assert_morethan [getInfoProperty $info defragtest_datatype_raw_defragged] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_started] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_ended] 0
|
|
}
|
|
|
|
test {Module defrag: late defrag with cursor works} {
|
|
r flushdb
|
|
r frag.resetstats
|
|
|
|
# key can only be defragged in no less than 10 iterations
|
|
# due to maxstep
|
|
r frag.create key2 10000 100 1000
|
|
|
|
after 2000
|
|
set info [r info defragtest_stats]
|
|
assert {[getInfoProperty $info defragtest_datatype_resumes] > 10}
|
|
assert_equal 0 [getInfoProperty $info defragtest_datatype_wrong_cursor]
|
|
assert_morethan [getInfoProperty $info defragtest_datatype_raw_defragged] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_started] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_ended] 0
|
|
}
|
|
|
|
test {Module defrag: global defrag works} {
|
|
r flushdb
|
|
r frag.resetstats
|
|
|
|
after 2000
|
|
set info [r info defragtest_stats]
|
|
assert {[getInfoProperty $info defragtest_global_attempts] > 0}
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_started] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_ended] 0
|
|
}
|
|
}
|
|
}
|