diff --git a/engines/default/slabs.c b/engines/default/slabs.c index 98031281d..06448ebfd 100644 --- a/engines/default/slabs.c +++ b/engines/default/slabs.c @@ -748,15 +748,18 @@ static void do_smmgr_01pct_check_and_move_left(void) assert(smid <= sm_anchor.used_maxid); sm_anchor.used_01pct_clsid = smid; } else { - assert(sm_anchor.used_01pct_space == 0); - sm_anchor.used_01pct_clsid = sm_anchor.used_maxid; - sm_anchor.used_01pct_space = sm_anchor.used_slist[sm_anchor.used_maxid].space; + assert(sm_anchor.used_01pct_clsid > sm_anchor.used_maxid && + sm_anchor.used_01pct_space == 0); + /* go downward */ } } - if (sm_anchor.used_01pct_space < space_standard) { + if (sm_anchor.used_01pct_space < space_standard || + sm_anchor.used_01pct_space == 0) { int old_used_01pct_clsid = sm_anchor.used_01pct_clsid; - for (smid = old_used_01pct_clsid-1; smid >= sm_anchor.used_minid; smid--) { + smid = sm_anchor.used_maxid < old_used_01pct_clsid + ? sm_anchor.used_maxid : (old_used_01pct_clsid-1); + for (; smid >= sm_anchor.used_minid; smid--) { if (sm_anchor.used_slist[smid].space > 0) { sm_anchor.used_01pct_space += sm_anchor.used_slist[smid].space; if (sm_anchor.used_01pct_space >= space_standard) { diff --git a/t/issue_ee_599.t b/t/issue_ee_599.t new file mode 100644 index 000000000..74170d81b --- /dev/null +++ b/t/issue_ee_599.t @@ -0,0 +1,81 @@ +#!/usr/bin/perl + +use strict; +use Test::More tests => 27; +use FindBin qw($Bin); +use lib "$Bin/lib"; +use MemcachedTest; + +my $engine = shift; +my $server = get_memcached($engine); +my $sock = $server->sock; +my $cmd; +my $val; +my $rst; +my $size; +my $stats; + +$size = 10; +$cmd = "set key1 1 0 $size"; $val = "x"x$size; $rst = "STORED"; +mem_cmd_is($sock, $cmd, $val, $rst); + +sleep(0.01); +$stats = mem_stats($sock, "slabs"); +is ($stats->{"SM:used_min_classid"}, 12, "$cmd confirm used_min_classid"); +is ($stats->{"SM:used_max_classid"}, 12, "$cmd confirm used_max_classid"); +is ($stats->{"SM:used_01pct_classid"}, 12, "$cmd confirm used_01pct_classid"); +is ($stats->{"SM:free_min_classid"}, 709, "$cmd confirm free_min_classid"); +is ($stats->{"SM:free_max_classid"}, -1, "$cmd confirm free_max_classid"); +is ($stats->{"SM:free_small_space"}, 0, "$cmd confirm free_small_space"); + +$size = 3; +$cmd = "set key2 1 0 $size"; $val = "x"x$size; $rst = "STORED"; +mem_cmd_is($sock, $cmd, $val, $rst); + +sleep(0.01); +$stats = mem_stats($sock, "slabs"); +is ($stats->{"SM:used_min_classid"}, 11, "$cmd confirm used_min_classid"); +is ($stats->{"SM:used_max_classid"}, 12, "$cmd confirm used_max_classid"); + +$size = 20; +$cmd = "set key3 1 0 $size"; $val = "x"x$size; $rst = "STORED"; +mem_cmd_is($sock, $cmd, $val, $rst); + +sleep(0.01); +$stats = mem_stats($sock, "slabs"); +is ($stats->{"SM:used_min_classid"}, 11, "$cmd confirm used_min_classid"); +is ($stats->{"SM:used_max_classid"}, 13, "$cmd confirm used_max_classid"); + +$size = 3; +$cmd = "set key4 1 0 $size"; $val = "x"x$size; $rst = "STORED"; +mem_cmd_is($sock, $cmd, $val, $rst); + + +# make free space +$cmd = "delete key1"; $rst = "DELETED"; +mem_cmd_is($sock, $cmd, "", $rst); + +sleep(0.01); +$stats = mem_stats($sock, "slabs"); +is ($stats->{"SM:used_min_classid"}, 11, "$cmd confirm used_min_classid"); +is ($stats->{"SM:used_max_classid"}, 13, "$cmd confirm used_max_classid"); +is ($stats->{"SM:used_01pct_classid"}, 13, "$cmd confirm used_01pct_classid"); +is ($stats->{"SM:free_min_classid"}, 12, "$cmd confirm free_min_classid"); +is ($stats->{"SM:free_max_classid"}, 12, "$cmd confirm free_max_classid"); + +$cmd = "delete key3"; $rst = "DELETED"; +mem_cmd_is($sock, $cmd, "", $rst); + +sleep(0.01); +$stats = mem_stats($sock, "slabs"); +is ($stats->{"SM:used_min_classid"}, 11, "$cmd confirm used_min_classid"); +is ($stats->{"SM:used_max_classid"}, 11, "$cmd confirm used_max_classid"); +is ($stats->{"SM:used_01pct_classid"}, 11, "$cmd confirm used_01pct_classid"); +is ($stats->{"SM:free_min_classid"}, 12, "$cmd confirm free_min_classid"); +is ($stats->{"SM:free_max_classid"}, 13, "$cmd confirm free_max_classid"); +# Previously, there was a phenomenon in +# which free_small_space was calculated to be larger than 0 +is ($stats->{"SM:free_small_space"}, 0, "$cmd confirm free_small_space"); + +# after test +release_memcached($engine, $server); diff --git a/t/tlist/engine_default_b.txt b/t/tlist/engine_default_b.txt index f5dba4733..eb0322b51 100644 --- a/t/tlist/engine_default_b.txt +++ b/t/tlist/engine_default_b.txt @@ -70,6 +70,7 @@ ./t/issue_68.t ./t/issue_70.t ./t/issue_arcus_151.t +./t/issue_ee_599.t ./t/item_size_max.t ./t/line-lengths.t ./t/longkey.t diff --git a/t/tlist/engine_default_s.txt b/t/tlist/engine_default_s.txt index 8f15c1f18..82af99655 100644 --- a/t/tlist/engine_default_s.txt +++ b/t/tlist/engine_default_s.txt @@ -66,6 +66,7 @@ ./t/issue_68.t ./t/issue_70.t ./t/issue_arcus_151.t +./t/issue_ee_599.t ./t/item_size_max.t ./t/line-lengths.t ./t/longkey.t