diff --git a/include/mhash.h b/include/mhash.h index e6bfc1943896cc35fffa1589125b72cda194803f..1d8c080811ce0bd637498a578315e2f7b813f224 100644 --- a/include/mhash.h +++ b/include/mhash.h @@ -151,6 +151,7 @@ void _mh(reserve)(struct _mh(t) *h, mh_int_t size, mh_arg_t arg); void __attribute__((noinline)) _mh(del_resize)(struct _mh(t) *h, mh_int_t x, mh_arg_t arg); +size_t _mh(memsize)(struct _mh(t) *h); void _mh(dump)(struct _mh(t) *h); #define put_slot(h, node, arg) \ @@ -377,7 +378,7 @@ _mh(new)() h->prime = 0; h->n_buckets = __ac_prime_list[h->prime]; h->p = (mh_node_t *) calloc(h->n_buckets, sizeof(mh_node_t)); - h->b = (mh_int_t *) calloc(h->n_buckets / 16 + 1, sizeof(unsigned)); + h->b = (mh_int_t *) calloc(h->n_buckets / 16 + 1, sizeof(mh_int_t)); h->upper_bound = h->n_buckets * MH_DENSITY; return h; } @@ -401,6 +402,22 @@ _mh(delete)(struct _mh(t) *h) free(h); } +/** Calculate hash size. */ +size_t +_mh(memsize)(struct _mh(t) *h) +{ + size_t sz = 2 * sizeof(struct _mh(t)); + + sz += h->n_buckets * sizeof(mh_node_t); + sz += (h->n_buckets / 16 + 1) * sizeof(mh_int_t); + if (h->resize_position) { + h = h->shadow; + sz += h->n_buckets * sizeof(mh_node_t); + sz += (h->n_buckets / 16 + 1) * sizeof(mh_int_t); + } + return sz; +} + void _mh(resize)(struct _mh(t) *h, mh_arg_t arg) @@ -467,7 +484,7 @@ _mh(start_resize)(struct _mh(t) *h, mh_int_t buckets, mh_int_t batch, s->p = (mh_node_t *) malloc(s->n_buckets * sizeof(mh_node_t)); if (s->p == NULL) return -1; - s->b = (mh_int_t *) calloc(s->n_buckets / 16 + 1, sizeof(unsigned)); + s->b = (mh_int_t *) calloc(s->n_buckets / 16 + 1, sizeof(mh_int_t)); if (s->b == NULL) { free(s->p); s->p = NULL; diff --git a/include/salloc.h b/include/salloc.h index 773bdd08719d5938ff002774a650a4d050e33efd..562df23d08ecca108fdbcc0201712d0738b6c665 100644 --- a/include/salloc.h +++ b/include/salloc.h @@ -49,6 +49,8 @@ struct slab_cache_stats { int64_t items; int64_t bytes_used; int64_t bytes_free; + int64_t bytes_used_real; + int64_t bytes_alloc_real; }; /** Statistics on utilization of the slab allocator. */ diff --git a/src/admin.cc b/src/admin.cc index 308a475d8762430b365f2cfca5e18258b5632587..0bc993d591d5136a79dfca3a5cb2251df2f2e478 100644 --- a/src/admin.cc +++ b/src/admin.cc @@ -57,6 +57,7 @@ extern "C" { #include "lua/init.h" #include "session.h" #include "scoped_guard.h" +#include "box/space.h" static const char *help = "available commands:" CRLF @@ -65,6 +66,7 @@ static const char *help = " - show info" CRLF " - show fiber" CRLF " - show configuration" CRLF + " - show index" CRLF " - show slab" CRLF " - show palloc" CRLF " - show stat" CRLF @@ -79,19 +81,21 @@ static const char *help = static const char *unknown_command = "unknown command. try typing help." CRLF; -#line 83 "src/admin.cc" +#line 85 "src/admin.cc" static const int admin_start = 1; -static const int admin_first_final = 141; +static const int admin_first_final = 145; static const int admin_error = 0; static const int admin_en_main = 1; -#line 82 "src/admin.rl" +#line 84 "src/admin.rl" struct salloc_stat_admin_cb_ctx { int64_t total_used; + int64_t total_used_real; + int64_t total_alloc_real; struct tbuf *out; }; @@ -101,16 +105,20 @@ salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx) struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx; tbuf_printf(ctx->out, - " - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64 - ", bytes_used: %- 12" PRIi64 - ", bytes_free: %- 12" PRIi64 " }" CRLF, + " - { item_size: %6i, slabs: %6i, items: %11" PRIi64 + ", bytes_used: %12" PRIi64 ", waste: %5.2f%%" + ", bytes_free: %12" PRIi64 " }" CRLF, (int)cstat->item_size, (int)cstat->slabs, cstat->items, cstat->bytes_used, + (double)(cstat->bytes_alloc_real - cstat->bytes_used_real)*100 / + (cstat->bytes_alloc_real + 0.001), cstat->bytes_free); ctx->total_used += cstat->bytes_used; + ctx->total_alloc_real += cstat->bytes_alloc_real; + ctx->total_used_real += cstat->bytes_used_real; return 0; } @@ -121,6 +129,8 @@ show_slab(struct tbuf *out) struct slab_arena_stats astat; cb_ctx.total_used = 0; + cb_ctx.total_used_real = 0; + cb_ctx.total_alloc_real = 0; cb_ctx.out = out; tbuf_printf(out, "slab statistics:\n classes:" CRLF); @@ -131,6 +141,11 @@ show_slab(struct tbuf *out) (double)cb_ctx.total_used / astat.size * 100); tbuf_printf(out, " arena_used: %.2f%%" CRLF, (double)astat.used / astat.size * 100); + tbuf_printf(out, " waste: %.2f%%" CRLF, + (double)(cb_ctx.total_alloc_real - cb_ctx.total_used_real) / (cb_ctx.total_alloc_real + 0.001) * 100); + tbuf_printf(out, " bytes_waste: %12" PRIi64 CRLF, + (int64_t)((double)cb_ctx.total_used*(cb_ctx.total_alloc_real - cb_ctx.total_used_real) / + (cb_ctx.total_alloc_real + 0.001))); } static void @@ -161,6 +176,32 @@ fail(struct tbuf *out, struct tbuf *err) end(out); } +static void +index_info(struct tbuf *out) +{ + tbuf_printf(out, "index:" CRLF); + struct space_stat *stat = space_stat(); + int sp_i = 0; + int64_t total_size = 0; + while (stat[sp_i].n >= 0) { + tbuf_printf(out, " - space: %" PRIi32 CRLF, stat[sp_i].n); + int64_t sp_size = 0; + int i; + for (i = 0; stat[sp_i].index[i].n >= 0; ++i) + sp_size += stat[sp_i].index[i].memsize; + + tbuf_printf(out, " memsize: %15" PRIi64 CRLF, sp_size); + total_size += sp_size; + tbuf_printf(out, " index: " CRLF); + for (i = 0; stat[sp_i].index[i].n >= 0; ++i) { + tbuf_printf(out, " - { n: %3d, keys: %15" PRIi64 ", memsize: %15" PRIi64 " }" CRLF, + stat[sp_i].index[i].n, stat[sp_i].index[i].keys, stat[sp_i].index[i].memsize); + } + ++sp_i; + } + tbuf_printf(out, "memsize: %15" PRIi64 CRLF, total_size); +} + static void tarantool_info(struct tbuf *out) { @@ -223,12 +264,12 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) p = in->pos; -#line 227 "src/admin.cc" +#line 268 "src/admin.cc" { cs = admin_start; } -#line 232 "src/admin.cc" +#line 273 "src/admin.cc" { if ( p == pe ) goto _test_eof; @@ -291,47 +332,47 @@ case 6: } goto st0; tr13: -#line 322 "src/admin.rl" +#line 365 "src/admin.rl" {slab_validate(); ok(out);} - goto st141; + goto st145; tr20: -#line 309 "src/admin.rl" +#line 351 "src/admin.rl" {return -1;} - goto st141; + goto st145; tr25: -#line 235 "src/admin.rl" +#line 276 "src/admin.rl" { start(out); tbuf_append(out, help, strlen(help)); end(out); } - goto st141; + goto st145; tr36: -#line 295 "src/admin.rl" +#line 337 "src/admin.rl" {strend = p;} -#line 241 "src/admin.rl" +#line 282 "src/admin.rl" { strstart[strend-strstart]='\0'; start(out); tarantool_lua(L, out, strstart); end(out); } - goto st141; + goto st145; tr43: -#line 248 "src/admin.rl" +#line 289 "src/admin.rl" { if (reload_cfg(err)) fail(out, err); else ok(out); } - goto st141; + goto st145; tr67: -#line 320 "src/admin.rl" +#line 363 "src/admin.rl" {coredump(60); ok(out);} - goto st141; + goto st145; tr76: -#line 255 "src/admin.rl" +#line 296 "src/admin.rl" { int ret = snapshot(); @@ -344,11 +385,11 @@ case 6: fail(out, err); } } - goto st141; + goto st145; tr98: -#line 305 "src/admin.rl" +#line 347 "src/admin.rl" { state = false; } -#line 268 "src/admin.rl" +#line 309 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -358,11 +399,11 @@ case 6: ok(out); } } - goto st141; + goto st145; tr101: -#line 304 "src/admin.rl" +#line 346 "src/admin.rl" { state = true; } -#line 268 "src/admin.rl" +#line 309 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -372,67 +413,71 @@ case 6: ok(out); } } - goto st141; + goto st145; tr117: -#line 223 "src/admin.rl" +#line 264 "src/admin.rl" { start(out); show_cfg(out); end(out); } - goto st141; + goto st145; tr131: -#line 312 "src/admin.rl" +#line 355 "src/admin.rl" {start(out); fiber_info(out); end(out);} - goto st141; -tr137: -#line 311 "src/admin.rl" + goto st145; +tr139: +#line 354 "src/admin.rl" + {start(out); index_info(out); end(out);} + goto st145; +tr141: +#line 353 "src/admin.rl" {start(out); tarantool_info(out); end(out);} - goto st141; -tr146: -#line 229 "src/admin.rl" + goto st145; +tr152: +#line 270 "src/admin.rl" { start(out); errinj_info(out); end(out); } - goto st141; -tr153: -#line 315 "src/admin.rl" + goto st145; +tr159: +#line 358 "src/admin.rl" {start(out); palloc_stat(out); end(out);} - goto st141; -tr164: -#line 217 "src/admin.rl" + goto st145; +tr170: +#line 258 "src/admin.rl" { start(out); show_plugins_stat(out); end(out); } - goto st141; -tr168: -#line 314 "src/admin.rl" + goto st145; +tr174: +#line 357 "src/admin.rl" {start(out); show_slab(out); end(out);} - goto st141; -tr172: -#line 316 "src/admin.rl" + goto st145; +tr178: +#line 359 "src/admin.rl" {start(out); show_stat(out);end(out);} - goto st141; -st141: + goto st145; +st145: if ( ++p == pe ) - goto _test_eof141; -case 141: -#line 425 "src/admin.cc" + goto _test_eof145; +case 145: +#line 470 "src/admin.cc" goto st0; tr14: -#line 322 "src/admin.rl" +#line 365 "src/admin.rl" {slab_validate(); ok(out);} goto st7; tr21: -#line 309 "src/admin.rl" +#line 351 "src/admin.rl" {return -1;} goto st7; tr26: -#line 235 "src/admin.rl" +#line 276 "src/admin.rl" { start(out); tbuf_append(out, help, strlen(help)); @@ -440,9 +485,9 @@ case 141: } goto st7; tr37: -#line 295 "src/admin.rl" +#line 337 "src/admin.rl" {strend = p;} -#line 241 "src/admin.rl" +#line 282 "src/admin.rl" { strstart[strend-strstart]='\0'; start(out); @@ -451,7 +496,7 @@ case 141: } goto st7; tr44: -#line 248 "src/admin.rl" +#line 289 "src/admin.rl" { if (reload_cfg(err)) fail(out, err); @@ -460,11 +505,11 @@ case 141: } goto st7; tr68: -#line 320 "src/admin.rl" +#line 363 "src/admin.rl" {coredump(60); ok(out);} goto st7; tr77: -#line 255 "src/admin.rl" +#line 296 "src/admin.rl" { int ret = snapshot(); @@ -479,9 +524,9 @@ case 141: } goto st7; tr99: -#line 305 "src/admin.rl" +#line 347 "src/admin.rl" { state = false; } -#line 268 "src/admin.rl" +#line 309 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -493,9 +538,9 @@ case 141: } goto st7; tr102: -#line 304 "src/admin.rl" +#line 346 "src/admin.rl" { state = true; } -#line 268 "src/admin.rl" +#line 309 "src/admin.rl" { strstart[strend-strstart] = '\0'; if (errinj_set_byname(strstart, state)) { @@ -507,7 +552,7 @@ case 141: } goto st7; tr118: -#line 223 "src/admin.rl" +#line 264 "src/admin.rl" { start(out); show_cfg(out); @@ -515,48 +560,52 @@ case 141: } goto st7; tr132: -#line 312 "src/admin.rl" +#line 355 "src/admin.rl" {start(out); fiber_info(out); end(out);} goto st7; -tr138: -#line 311 "src/admin.rl" +tr140: +#line 354 "src/admin.rl" + {start(out); index_info(out); end(out);} + goto st7; +tr142: +#line 353 "src/admin.rl" {start(out); tarantool_info(out); end(out);} goto st7; -tr147: -#line 229 "src/admin.rl" +tr153: +#line 270 "src/admin.rl" { start(out); errinj_info(out); end(out); } goto st7; -tr154: -#line 315 "src/admin.rl" +tr160: +#line 358 "src/admin.rl" {start(out); palloc_stat(out); end(out);} goto st7; -tr165: -#line 217 "src/admin.rl" +tr171: +#line 258 "src/admin.rl" { start(out); show_plugins_stat(out); end(out); } goto st7; -tr169: -#line 314 "src/admin.rl" +tr175: +#line 357 "src/admin.rl" {start(out); show_slab(out); end(out);} goto st7; -tr173: -#line 316 "src/admin.rl" +tr179: +#line 359 "src/admin.rl" {start(out); show_stat(out);end(out);} goto st7; st7: if ( ++p == pe ) goto _test_eof7; case 7: -#line 558 "src/admin.cc" +#line 607 "src/admin.cc" if ( (*p) == 10 ) - goto st141; + goto st145; goto st0; st8: if ( ++p == pe ) @@ -707,28 +756,28 @@ case 23: } goto tr33; tr33: -#line 295 "src/admin.rl" +#line 337 "src/admin.rl" {strstart = p;} goto st24; st24: if ( ++p == pe ) goto _test_eof24; case 24: -#line 718 "src/admin.cc" +#line 767 "src/admin.cc" switch( (*p) ) { case 10: goto tr36; case 13: goto tr37; } goto st24; tr34: -#line 295 "src/admin.rl" +#line 337 "src/admin.rl" {strstart = p;} goto st25; st25: if ( ++p == pe ) goto _test_eof25; case 25: -#line 732 "src/admin.cc" +#line 781 "src/admin.cc" switch( (*p) ) { case 10: goto tr36; case 13: goto tr37; @@ -1178,28 +1227,28 @@ case 73: goto tr91; goto st0; tr91: -#line 303 "src/admin.rl" +#line 345 "src/admin.rl" { strstart = p; } goto st74; st74: if ( ++p == pe ) goto _test_eof74; case 74: -#line 1189 "src/admin.cc" +#line 1238 "src/admin.cc" if ( (*p) == 32 ) goto tr92; if ( 33 <= (*p) && (*p) <= 126 ) goto st74; goto st0; tr92: -#line 303 "src/admin.rl" +#line 345 "src/admin.rl" { strend = p; } goto st75; st75: if ( ++p == pe ) goto _test_eof75; case 75: -#line 1203 "src/admin.cc" +#line 1252 "src/admin.cc" switch( (*p) ) { case 32: goto st75; case 111: goto st76; @@ -1316,7 +1365,7 @@ case 87: case 88: switch( (*p) ) { case 32: goto st89; - case 111: goto st139; + case 111: goto st143; } goto st0; st89: @@ -1328,8 +1377,8 @@ case 89: case 99: goto st90; case 102: goto st103; case 105: goto st108; - case 112: goto st120; - case 115: goto st132; + case 112: goto st124; + case 115: goto st136; } goto st0; st90: @@ -1508,29 +1557,25 @@ case 107: if ( ++p == pe ) goto _test_eof108; case 108: - if ( (*p) == 110 ) - goto st109; + switch( (*p) ) { + case 100: goto st109; + case 110: goto st111; + } goto st0; st109: if ( ++p == pe ) goto _test_eof109; case 109: - switch( (*p) ) { - case 10: goto tr137; - case 13: goto tr138; - case 102: goto st110; - case 106: goto st112; - case 115: goto st115; - } + if ( (*p) == 120 ) + goto st110; goto st0; st110: if ( ++p == pe ) goto _test_eof110; case 110: switch( (*p) ) { - case 10: goto tr137; - case 13: goto tr138; - case 111: goto st111; + case 10: goto tr139; + case 13: goto tr140; } goto st0; st111: @@ -1538,8 +1583,12 @@ case 110: goto _test_eof111; case 111: switch( (*p) ) { - case 10: goto tr137; - case 13: goto tr138; + case 10: goto tr141; + case 13: goto tr142; + case 100: goto st112; + case 102: goto st114; + case 106: goto st116; + case 115: goto st119; } goto st0; st112: @@ -1547,8 +1596,9 @@ case 111: goto _test_eof112; case 112: switch( (*p) ) { + case 10: goto tr139; + case 13: goto tr140; case 101: goto st113; - case 115: goto st115; } goto st0; st113: @@ -1556,8 +1606,9 @@ case 112: goto _test_eof113; case 113: switch( (*p) ) { - case 99: goto st114; - case 115: goto st115; + case 10: goto tr139; + case 13: goto tr140; + case 120: goto st110; } goto st0; st114: @@ -1565,8 +1616,9 @@ case 113: goto _test_eof114; case 114: switch( (*p) ) { - case 115: goto st115; - case 116: goto st116; + case 10: goto tr141; + case 13: goto tr142; + case 111: goto st115; } goto st0; st115: @@ -1574,8 +1626,8 @@ case 114: goto _test_eof115; case 115: switch( (*p) ) { - case 10: goto tr146; - case 13: goto tr147; + case 10: goto tr141; + case 13: goto tr142; } goto st0; st116: @@ -1583,8 +1635,8 @@ case 115: goto _test_eof116; case 116: switch( (*p) ) { - case 105: goto st117; - case 115: goto st115; + case 101: goto st117; + case 115: goto st119; } goto st0; st117: @@ -1592,8 +1644,8 @@ case 116: goto _test_eof117; case 117: switch( (*p) ) { - case 111: goto st118; - case 115: goto st115; + case 99: goto st118; + case 115: goto st119; } goto st0; st118: @@ -1601,24 +1653,26 @@ case 117: goto _test_eof118; case 118: switch( (*p) ) { - case 110: goto st119; - case 115: goto st115; + case 115: goto st119; + case 116: goto st120; } goto st0; st119: if ( ++p == pe ) goto _test_eof119; case 119: - if ( (*p) == 115 ) - goto st115; + switch( (*p) ) { + case 10: goto tr152; + case 13: goto tr153; + } goto st0; st120: if ( ++p == pe ) goto _test_eof120; case 120: switch( (*p) ) { - case 97: goto st121; - case 108: goto st126; + case 105: goto st121; + case 115: goto st119; } goto st0; st121: @@ -1626,9 +1680,8 @@ case 120: goto _test_eof121; case 121: switch( (*p) ) { - case 10: goto tr153; - case 13: goto tr154; - case 108: goto st122; + case 111: goto st122; + case 115: goto st119; } goto st0; st122: @@ -1636,29 +1689,24 @@ case 121: goto _test_eof122; case 122: switch( (*p) ) { - case 10: goto tr153; - case 13: goto tr154; - case 108: goto st123; + case 110: goto st123; + case 115: goto st119; } goto st0; st123: if ( ++p == pe ) goto _test_eof123; case 123: - switch( (*p) ) { - case 10: goto tr153; - case 13: goto tr154; - case 111: goto st124; - } + if ( (*p) == 115 ) + goto st119; goto st0; st124: if ( ++p == pe ) goto _test_eof124; case 124: switch( (*p) ) { - case 10: goto tr153; - case 13: goto tr154; - case 99: goto st125; + case 97: goto st125; + case 108: goto st130; } goto st0; st125: @@ -1666,90 +1714,92 @@ case 124: goto _test_eof125; case 125: switch( (*p) ) { - case 10: goto tr153; - case 13: goto tr154; + case 10: goto tr159; + case 13: goto tr160; + case 108: goto st126; } goto st0; st126: if ( ++p == pe ) goto _test_eof126; case 126: - if ( (*p) == 117 ) - goto st127; + switch( (*p) ) { + case 10: goto tr159; + case 13: goto tr160; + case 108: goto st127; + } goto st0; st127: if ( ++p == pe ) goto _test_eof127; case 127: - if ( (*p) == 103 ) - goto st128; + switch( (*p) ) { + case 10: goto tr159; + case 13: goto tr160; + case 111: goto st128; + } goto st0; st128: if ( ++p == pe ) goto _test_eof128; case 128: - if ( (*p) == 105 ) - goto st129; + switch( (*p) ) { + case 10: goto tr159; + case 13: goto tr160; + case 99: goto st129; + } goto st0; st129: if ( ++p == pe ) goto _test_eof129; case 129: - if ( (*p) == 110 ) - goto st130; + switch( (*p) ) { + case 10: goto tr159; + case 13: goto tr160; + } goto st0; st130: if ( ++p == pe ) goto _test_eof130; case 130: - if ( (*p) == 115 ) + if ( (*p) == 117 ) goto st131; goto st0; st131: if ( ++p == pe ) goto _test_eof131; case 131: - switch( (*p) ) { - case 10: goto tr164; - case 13: goto tr165; - } + if ( (*p) == 103 ) + goto st132; goto st0; st132: if ( ++p == pe ) goto _test_eof132; case 132: - switch( (*p) ) { - case 108: goto st133; - case 116: goto st136; - } + if ( (*p) == 105 ) + goto st133; goto st0; st133: if ( ++p == pe ) goto _test_eof133; case 133: - switch( (*p) ) { - case 10: goto tr168; - case 13: goto tr169; - case 97: goto st134; - } + if ( (*p) == 110 ) + goto st134; goto st0; st134: if ( ++p == pe ) goto _test_eof134; case 134: - switch( (*p) ) { - case 10: goto tr168; - case 13: goto tr169; - case 98: goto st135; - } + if ( (*p) == 115 ) + goto st135; goto st0; st135: if ( ++p == pe ) goto _test_eof135; case 135: switch( (*p) ) { - case 10: goto tr168; - case 13: goto tr169; + case 10: goto tr170; + case 13: goto tr171; } goto st0; st136: @@ -1757,9 +1807,8 @@ case 135: goto _test_eof136; case 136: switch( (*p) ) { - case 10: goto tr172; - case 13: goto tr173; - case 97: goto st137; + case 108: goto st137; + case 116: goto st140; } goto st0; st137: @@ -1767,9 +1816,9 @@ case 136: goto _test_eof137; case 137: switch( (*p) ) { - case 10: goto tr172; - case 13: goto tr173; - case 116: goto st138; + case 10: goto tr174; + case 13: goto tr175; + case 97: goto st138; } goto st0; st138: @@ -1777,8 +1826,9 @@ case 137: goto _test_eof138; case 138: switch( (*p) ) { - case 10: goto tr172; - case 13: goto tr173; + case 10: goto tr174; + case 13: goto tr175; + case 98: goto st139; } goto st0; st139: @@ -1786,14 +1836,52 @@ case 138: goto _test_eof139; case 139: switch( (*p) ) { - case 32: goto st89; - case 119: goto st140; + case 10: goto tr174; + case 13: goto tr175; } goto st0; st140: if ( ++p == pe ) goto _test_eof140; case 140: + switch( (*p) ) { + case 10: goto tr178; + case 13: goto tr179; + case 97: goto st141; + } + goto st0; +st141: + if ( ++p == pe ) + goto _test_eof141; +case 141: + switch( (*p) ) { + case 10: goto tr178; + case 13: goto tr179; + case 116: goto st142; + } + goto st0; +st142: + if ( ++p == pe ) + goto _test_eof142; +case 142: + switch( (*p) ) { + case 10: goto tr178; + case 13: goto tr179; + } + goto st0; +st143: + if ( ++p == pe ) + goto _test_eof143; +case 143: + switch( (*p) ) { + case 32: goto st89; + case 119: goto st144; + } + goto st0; +st144: + if ( ++p == pe ) + goto _test_eof144; +case 144: if ( (*p) == 32 ) goto st89; goto st0; @@ -1803,7 +1891,7 @@ case 140: _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; - _test_eof141: cs = 141; goto _test_eof; + _test_eof145: cs = 145; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; @@ -1938,12 +2026,16 @@ case 140: _test_eof138: cs = 138; goto _test_eof; _test_eof139: cs = 139; goto _test_eof; _test_eof140: cs = 140; goto _test_eof; + _test_eof141: cs = 141; goto _test_eof; + _test_eof142: cs = 142; goto _test_eof; + _test_eof143: cs = 143; goto _test_eof; + _test_eof144: cs = 144; goto _test_eof; _test_eof: {} _out: {} } -#line 328 "src/admin.rl" +#line 371 "src/admin.rl" in->pos = pe; diff --git a/src/admin.rl b/src/admin.rl index 59e5e06d3cfc9b68d298323fe1504546561f31aa..073461ec6fd08255c303ca0728612b16deae949c 100644 --- a/src/admin.rl +++ b/src/admin.rl @@ -55,6 +55,7 @@ extern "C" { #include "lua/init.h" #include "session.h" #include "scoped_guard.h" +#include "box/space.h" static const char *help = "available commands:" CRLF @@ -63,6 +64,7 @@ static const char *help = " - show info" CRLF " - show fiber" CRLF " - show configuration" CRLF + " - show index" CRLF " - show slab" CRLF " - show palloc" CRLF " - show stat" CRLF @@ -83,6 +85,8 @@ static const char *unknown_command = "unknown command. try typing help." CRLF; struct salloc_stat_admin_cb_ctx { int64_t total_used; + int64_t total_used_real; + int64_t total_alloc_real; struct tbuf *out; }; @@ -92,16 +96,20 @@ salloc_stat_admin_cb(const struct slab_cache_stats *cstat, void *cb_ctx) struct salloc_stat_admin_cb_ctx *ctx = (struct salloc_stat_admin_cb_ctx *) cb_ctx; tbuf_printf(ctx->out, - " - { item_size: %- 5i, slabs: %- 3i, items: %- 11" PRIi64 - ", bytes_used: %- 12" PRIi64 - ", bytes_free: %- 12" PRIi64 " }" CRLF, + " - { item_size: %6i, slabs: %6i, items: %11" PRIi64 + ", bytes_used: %12" PRIi64 ", waste: %5.2f%%" + ", bytes_free: %12" PRIi64 " }" CRLF, (int)cstat->item_size, (int)cstat->slabs, cstat->items, cstat->bytes_used, + (double)(cstat->bytes_alloc_real - cstat->bytes_used_real)*100 / + (cstat->bytes_alloc_real + 0.001), cstat->bytes_free); ctx->total_used += cstat->bytes_used; + ctx->total_alloc_real += cstat->bytes_alloc_real; + ctx->total_used_real += cstat->bytes_used_real; return 0; } @@ -112,6 +120,8 @@ show_slab(struct tbuf *out) struct slab_arena_stats astat; cb_ctx.total_used = 0; + cb_ctx.total_used_real = 0; + cb_ctx.total_alloc_real = 0; cb_ctx.out = out; tbuf_printf(out, "slab statistics:\n classes:" CRLF); @@ -122,6 +132,11 @@ show_slab(struct tbuf *out) (double)cb_ctx.total_used / astat.size * 100); tbuf_printf(out, " arena_used: %.2f%%" CRLF, (double)astat.used / astat.size * 100); + tbuf_printf(out, " waste: %.2f%%" CRLF, + (double)(cb_ctx.total_alloc_real - cb_ctx.total_used_real) / (cb_ctx.total_alloc_real + 0.001) * 100); + tbuf_printf(out, " bytes_waste: %12" PRIi64 CRLF, + (int64_t)((double)cb_ctx.total_used*(cb_ctx.total_alloc_real - cb_ctx.total_used_real) / + (cb_ctx.total_alloc_real + 0.001))); } static void @@ -152,6 +167,32 @@ fail(struct tbuf *out, struct tbuf *err) end(out); } +static void +index_info(struct tbuf *out) +{ + tbuf_printf(out, "index:" CRLF); + struct space_stat *stat = space_stat(); + int sp_i = 0; + int64_t total_size = 0; + while (stat[sp_i].n >= 0) { + tbuf_printf(out, " - space: %" PRIi32 CRLF, stat[sp_i].n); + int64_t sp_size = 0; + int i; + for (i = 0; stat[sp_i].index[i].n >= 0; ++i) + sp_size += stat[sp_i].index[i].memsize; + + tbuf_printf(out, " memsize: %15" PRIi64 CRLF, sp_size); + total_size += sp_size; + tbuf_printf(out, " index: " CRLF); + for (i = 0; stat[sp_i].index[i].n >= 0; ++i) { + tbuf_printf(out, " - { n: %3d, keys: %15" PRIi64 ", memsize: %15" PRIi64 " }" CRLF, + stat[sp_i].index[i].n, stat[sp_i].index[i].keys, stat[sp_i].index[i].memsize); + } + ++sp_i; + } + tbuf_printf(out, "memsize: %15" PRIi64 CRLF, total_size); +} + static void tarantool_info(struct tbuf *out) { @@ -278,6 +319,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) eol = "\n" | "\r\n"; show = "sh"("o"("w")?)?; info = "in"("f"("o")?)?; + index = ("ind"("e"("x")?)? | "idx"); check = "ch"("e"("c"("k")?)?)?; configuration = "co"("n"("f"("i"("g"("u"("r"("a"("t"("i"("o"("n")?)?)?)?)?)?)?)?)?)?)?; fiber = "fi"("b"("e"("r")?)?)?; @@ -309,6 +351,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) exit %{return -1;} | lua " "+ string %lua | show " "+ info %{start(out); tarantool_info(out); end(out);} | + show " "+ index %{start(out); index_info(out); end(out);} | show " "+ fiber %{start(out); fiber_info(out); end(out);} | show " "+ configuration %show_configuration | show " "+ slab %{start(out); show_slab(out); end(out);} | diff --git a/src/box/bitset_index.cc b/src/box/bitset_index.cc index c22b209661322a40f834b9898e38bb4815c6b5ac..9c780a307c4d5acd002ff5d89a0a517678feae21 100644 --- a/src/box/bitset_index.cc +++ b/src/box/bitset_index.cc @@ -146,6 +146,12 @@ BitsetIndex::size() const return bitset_index_size(&index); } +size_t +BitsetIndex::memsize() const +{ + return 0; +} + struct tuple * BitsetIndex::min() const { diff --git a/src/box/bitset_index.h b/src/box/bitset_index.h index f78236f5ff50642935f77b862784173541d9ae06..163ea52599d45d46d2c70d5f71d9f6974e5fe8ce 100644 --- a/src/box/bitset_index.h +++ b/src/box/bitset_index.h @@ -60,6 +60,7 @@ class BitsetIndex: public Index { struct tuple *new_tuple, enum dup_replace_mode mode); + virtual size_t memsize() const; virtual struct iterator *allocIterator() const; virtual void initIterator(struct iterator *iterator, enum iterator_type type, diff --git a/src/box/hash_index.cc b/src/box/hash_index.cc index c5f3277cdf9e877602a712d3331e783a6d36bdbd..e076f4633f10487979dd7b546c005464d7dd52f0 100644 --- a/src/box/hash_index.cc +++ b/src/box/hash_index.cc @@ -237,6 +237,11 @@ HashIndex::size() const return mh_size(hash); } +size_t +HashIndex::memsize() const +{ + return mh_index_memsize(hash); +} struct tuple * HashIndex::min() const diff --git a/src/box/hash_index.h b/src/box/hash_index.h index 3fdb7d54f78841ec7197009a46b920bf43e2fb71..5fb09a02923d7dc11b0531fcc61dea11a7982e35 100644 --- a/src/box/hash_index.h +++ b/src/box/hash_index.h @@ -57,6 +57,7 @@ class HashIndex: public Index { const char *key, uint32_t part_count) const; virtual void reserve(uint32_t n_tuples); + virtual size_t memsize() const; protected: struct mh_index_t *hash; diff --git a/src/box/index.h b/src/box/index.h index 646562b84fec215097c3133d372369cf5fe2f964..67cfc0eb0a41e44598700e9c3ddbd14b5bbf468b 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -177,6 +177,7 @@ class Index: public Object { virtual struct tuple *replace(struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode) = 0; + virtual size_t memsize() const = 0; /** * Create a structure to represent an iterator. Must be * initialized separately. diff --git a/src/box/space.cc b/src/box/space.cc index fbff6095e91c71368684d31944a08b3a96067ce6..bbf8a5a7bb756ebddb79ab92b749524d8082221c 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -55,6 +55,34 @@ static bool secondary_indexes_enabled = false; */ static bool primary_indexes_enabled = false; +struct space_stat * +space_stat() +{ + static __thread struct space_stat space_stat[SPACE_STAT_MAX]; + + int sp_i = 0; + mh_int_t i; + mh_foreach(spaces, i) { + struct space *sp = (struct space *) + mh_i32ptr_node(spaces, i)->val; + space_stat[sp_i].n = space_n(sp); + int n = sp->key_count; + int i = 0; + for (; i < n; i++) { + Index *index = sp->index[i]; + space_stat[sp_i].index[i].n = i; + space_stat[sp_i].index[i].keys = index->size(); + space_stat[sp_i].index[i].memsize = index->memsize(); + } + space_stat[sp_i].index[i].n = -1; + ++sp_i; + if (sp_i + 1 >= SPACE_STAT_MAX) + break; + } + space_stat[sp_i].n = -1; + return space_stat; +} + static void space_create(struct space *space, uint32_t space_no, diff --git a/src/box/space.h b/src/box/space.h index 8bd6aff5f5a649c09413275b133ce8c67f2b9639..abe8eae101a607fa74f2314d3a03e4465acdb0b8 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -246,4 +246,20 @@ index_find(struct space *sp, uint32_t index_no) return idx; } +#define SPACE_STAT_MAX 256 + +struct index_stat { + int32_t n; + int64_t keys; + int64_t memsize; +}; + +struct space_stat { + int32_t n; + struct index_stat index[SPACE_STAT_MAX]; +}; + +struct space_stat * +space_stat(); + #endif /* TARANTOOL_BOX_SPACE_H_INCLUDED */ diff --git a/src/box/tree_index.cc b/src/box/tree_index.cc index b5a4df66eb8323a8c93f5e40cfe8961bd449e079..30842b49721bdc580dc4e14ed0f51dd14109ba68 100644 --- a/src/box/tree_index.cc +++ b/src/box/tree_index.cc @@ -224,6 +224,12 @@ TreeIndex::size() const return tree.size; } +size_t +TreeIndex::memsize() const +{ + return tree.size * (8 + sizeof(struct sptree_index_node)); +} + struct tuple * TreeIndex::min() const { diff --git a/src/box/tree_index.h b/src/box/tree_index.h index c19380303fddaa3d3594bd61e8d6381e675147ed..04a4a9dd603dda49013764b63edc62b1b350542e 100644 --- a/src/box/tree_index.h +++ b/src/box/tree_index.h @@ -56,6 +56,7 @@ class TreeIndex: public Index { struct tuple *new_tuple, enum dup_replace_mode mode); + virtual size_t memsize() const; virtual struct iterator *allocIterator() const; virtual void initIterator(struct iterator *iterator, enum iterator_type type, diff --git a/src/salloc.cc b/src/salloc.cc index 14108bf31c7f02647062523d83256ec989d055de..8f48002e1ae94cd25f8b373149103d1d269f27b6 100644 --- a/src/salloc.cc +++ b/src/salloc.cc @@ -75,6 +75,8 @@ struct slab { uint32_t magic; size_t used; size_t items; + size_t used_real; + size_t alloc_real; struct item_slist_head free; struct slab_cache *cache; void *brk; @@ -396,6 +398,8 @@ salloc(size_t size, const char *what) if (fully_formatted(slab) && SLIST_EMPTY(&slab->free)) TAILQ_REMOVE(&cache->free_slabs, slab, cache_free_link); + slab->used_real += size + sizeof(red_zone); + slab->alloc_real += cache->item_size + sizeof(red_zone); slab->used += cache->item_size + sizeof(red_zone); slab->items += 1; @@ -475,6 +479,8 @@ salloc_stat(salloc_stat_cb cb, struct slab_arena_stats *astat, void *cb_ctx) st.bytes_free -= sizeof(struct slab); st.bytes_used += sizeof(struct slab); st.bytes_used += slab->used; + st.bytes_alloc_real += slab->alloc_real + sizeof(struct slab); + st.bytes_used_real += slab->used_real + sizeof(struct slab); } st.item_size = slab_caches[i].item_size; diff --git a/test/box/admin.result b/test/box/admin.result index 5e9a0f43e4c6ab651ce7c3f1beb1b13e11a4aa26..ee4390105a19c74ea33c142962006d72b87fcc61 100644 --- a/test/box/admin.result +++ b/test/box/admin.result @@ -17,6 +17,7 @@ available commands: - show info - show fiber - show configuration + - show index - show slab - show palloc - show stat