From f3ca517dd59ad9ceff8216147507ca2a3f4bc03f Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov.dev@gmail.com> Date: Sun, 11 Feb 2018 13:51:10 +0300 Subject: [PATCH] vinyl: implement space.bsize, index.bsize, and index.len - space.bsize returns the size of user data stored in the space. It is the sum of memory.bytes and disk.bytes as reported by the primary index. - index.bsize returns the size of memory used for indexing data. It is the sum of memory.index_size, disk.index_size, and disk.bloom_size as reported by index.info. For secondary indexes we also add the size of binary data stored on disk (disk.bytes), because it is only needed to build the index. - index.len returns the total number of rows stored in the index. It is the sum of memory.rows and disk.rows as reported by index.info. Note, it may be greater than the number of tuples stored in the space, because it includes DELETE and UPDATE statements. Closes #2863 Closes #3056 --- src/box/vinyl.c | 42 ++++++- test/vinyl/constraint.result | 16 --- test/vinyl/constraint.test.lua | 9 -- test/vinyl/ddl.result | 30 ----- test/vinyl/ddl.test.lua | 15 --- test/vinyl/info.result | 219 +++++++++++++++++++++++++++++++++ test/vinyl/info.test.lua | 67 ++++++++++ 7 files changed, 324 insertions(+), 74 deletions(-) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 568ca17eeb..94d0d038a2 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -1200,15 +1200,49 @@ vinyl_space_build_secondary_key(struct space *old_space, static size_t vinyl_space_bsize(struct space *space) { - (void)space; - return 0; + /* + * Return the sum size of user data this space + * accommodates. Since full tuples are stored in + * primary indexes, it is basically the size of + * binary data stored in this space's primary index. + */ + struct index *pk_base = space_index(space, 0); + if (pk_base == NULL) + return 0; + struct vy_index *pk = vy_index(pk_base); + return pk->stat.memory.count.bytes + pk->stat.disk.count.bytes; +} + +static ssize_t +vinyl_index_size(struct index *base) +{ + /* + * Return the total number of statements in the index. + * Note, it may be greater than the number of tuples + * actually stored in the space, but it should be a + * fairly good estimate. + */ + struct vy_index *index = vy_index(base); + return index->stat.memory.count.rows + index->stat.disk.count.rows; } static ssize_t vinyl_index_bsize(struct index *base) { + /* + * Return the cost of indexing user data. For both + * primary and secondary indexes, this includes the + * size of page index, bloom filter, and memory tree + * extents. For secondary indexes, we also add the + * total size of statements stored on disk, because + * they are only needed for building the index. + */ struct vy_index *index = vy_index(base); - return index->stat.memory.count.bytes; + ssize_t bsize = vy_index_mem_tree_size(index) + + index->page_index_size + index->bloom_size; + if (index->id > 0) + bsize += index->stat.disk.count.bytes; + return bsize; } /* {{{ Public API of transaction control: start/end transaction, @@ -4001,7 +4035,7 @@ static const struct index_vtab vinyl_index_vtab = { /* .commit_create = */ vinyl_index_commit_create, /* .commit_drop = */ vinyl_index_commit_drop, /* .update_def = */ generic_index_update_def, - /* .size = */ generic_index_size, + /* .size = */ vinyl_index_size, /* .bsize = */ vinyl_index_bsize, /* .min = */ generic_index_min, /* .max = */ generic_index_max, diff --git a/test/vinyl/constraint.result b/test/vinyl/constraint.result index 4c9807b852..46ed1c9ebf 100644 --- a/test/vinyl/constraint.result +++ b/test/vinyl/constraint.result @@ -142,19 +142,3 @@ space = nil pk = nil --- ... -------------------------------------------------------------------------------- --- space:len() is unsupported -------------------------------------------------------------------------------- -space = box.schema.space.create('test_len', { engine = 'vinyl' }) ---- -... -_ = space:create_index('primary', { type = 'tree', parts = {1, 'string'}}) ---- -... -space:len() ---- -- error: Index 'primary' (TREE) of space 'test_len' (vinyl) does not support size() -... -space:drop() ---- -... diff --git a/test/vinyl/constraint.test.lua b/test/vinyl/constraint.test.lua index bdfa378015..4a785f7bf9 100644 --- a/test/vinyl/constraint.test.lua +++ b/test/vinyl/constraint.test.lua @@ -49,12 +49,3 @@ t3 = space:insert({string.rep('x', 102200)}) space:drop() space = nil pk = nil - -------------------------------------------------------------------------------- --- space:len() is unsupported -------------------------------------------------------------------------------- - -space = box.schema.space.create('test_len', { engine = 'vinyl' }) -_ = space:create_index('primary', { type = 'tree', parts = {1, 'string'}}) -space:len() -space:drop() diff --git a/test/vinyl/ddl.result b/test/vinyl/ddl.result index 9fa3504cdf..45a383442b 100644 --- a/test/vinyl/ddl.result +++ b/test/vinyl/ddl.result @@ -229,36 +229,6 @@ space:drop() --- ... -- --- gh-1632: index:bsize() --- -space = box.schema.space.create('test', { engine = 'vinyl' }) ---- -... -pk = space:create_index('primary', { type = 'tree', parts = {1, 'unsigned'} }) ---- -... -for i=1,10 do box.space.test:replace({i}) end ---- -... -box.space.test.index.primary:bsize() > 0 ---- -- true -... -box.snapshot() ---- -- ok -... -while space.index.primary:info().run_count ~= 1 do fiber.sleep(0.01) end ---- -... -box.space.test.index.primary:bsize() == 0 ---- -- true -... -space:drop() ---- -... --- -- gh-1709: need error on altering space -- space = box.schema.space.create('test', {engine='vinyl'}) diff --git a/test/vinyl/ddl.test.lua b/test/vinyl/ddl.test.lua index bb9e559688..53205df994 100644 --- a/test/vinyl/ddl.test.lua +++ b/test/vinyl/ddl.test.lua @@ -84,21 +84,6 @@ space.index.primary:alter({parts = {1, 'unsigned', 2, 'unsigned'}}) space:drop() --- --- gh-1632: index:bsize() --- -space = box.schema.space.create('test', { engine = 'vinyl' }) -pk = space:create_index('primary', { type = 'tree', parts = {1, 'unsigned'} }) -for i=1,10 do box.space.test:replace({i}) end -box.space.test.index.primary:bsize() > 0 - -box.snapshot() -while space.index.primary:info().run_count ~= 1 do fiber.sleep(0.01) end - -box.space.test.index.primary:bsize() == 0 - -space:drop() - -- -- gh-1709: need error on altering space -- diff --git a/test/vinyl/info.result b/test/vinyl/info.result index 2724cc3d94..35404f9d98 100644 --- a/test/vinyl/info.result +++ b/test/vinyl/info.result @@ -912,6 +912,225 @@ stat_diff(gstat(), st, 'tx') --- - commit: 1 ... +s:drop() +--- +... +-- +-- space.bsize, index.len, index.bsize +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +--- +... +s:bsize() +--- +- 0 +... +i1 = s:create_index('i1', {parts = {1, 'unsigned'}, run_count_per_level = 1}) +--- +... +i2 = s:create_index('i2', {parts = {2, 'unsigned'}, run_count_per_level = 1}) +--- +... +s:bsize() +--- +- 0 +... +i1:len(), i2:len() +--- +- 0 +- 0 +... +i1:bsize(), i2:bsize() +--- +- 0 +- 0 +... +for i = 1, 100, 2 do s:replace{i, i, pad()} end +--- +... +st1 = i1:info() +--- +... +st2 = i2:info() +--- +... +s:bsize() +--- +- 53300 +... +i1:len(), i2:len() +--- +- 50 +- 50 +... +i1:bsize(), i2:bsize() +--- +- 49152 +- 49152 +... +s:bsize() == st1.memory.bytes +--- +- true +... +i1:len() == st1.memory.rows +--- +- true +... +i2:len() == st2.memory.rows +--- +- true +... +i1:bsize() == st1.memory.index_size +--- +- true +... +i2:bsize() == st2.memory.index_size +--- +- true +... +box.snapshot() +--- +- ok +... +st1 = i1:info() +--- +... +st2 = i2:info() +--- +... +s:bsize() +--- +- 52199 +... +i1:len(), i2:len() +--- +- 50 +- 50 +... +i1:bsize(), i2:bsize() +--- +- 4390 +- 4946 +... +s:bsize() == st1.disk.bytes +--- +- true +... +i1:len() == st1.disk.rows +--- +- true +... +i2:len() == st2.disk.rows +--- +- true +... +i1:bsize() == st1.disk.index_size + st1.disk.bloom_size +--- +- true +... +i2:bsize() == st2.disk.index_size + st2.disk.bloom_size + st2.disk.bytes +--- +- true +... +for i = 1, 100, 2 do s:delete(i) end +--- +... +for i = 2, 100, 2 do s:replace{i, i, pad()} end +--- +... +st1 = i1:info() +--- +... +st2 = i2:info() +--- +... +s:bsize() +--- +- 107449 +... +i1:len(), i2:len() +--- +- 150 +- 150 +... +i1:bsize(), i2:bsize() +--- +- 53542 +- 54098 +... +s:bsize() == st1.memory.bytes + st1.disk.bytes +--- +- true +... +i1:len() == st1.memory.rows + st1.disk.rows +--- +- true +... +i2:len() == st2.memory.rows + st2.disk.rows +--- +- true +... +i1:bsize() == st1.memory.index_size + st1.disk.index_size + st1.disk.bloom_size +--- +- true +... +i2:bsize() == st2.memory.index_size + st2.disk.index_size + st2.disk.bloom_size + st2.disk.bytes +--- +- true +... +box.snapshot() +--- +- ok +... +wait(function() return i1:info() end, st1, 'disk.compact.count', 1) +--- +... +wait(function() return i2:info() end, st2, 'disk.compact.count', 1) +--- +... +st1 = i1:info() +--- +... +st2 = i2:info() +--- +... +s:bsize() +--- +- 52199 +... +i1:len(), i2:len() +--- +- 50 +- 50 +... +i1:bsize(), i2:bsize() +--- +- 4390 +- 4946 +... +s:bsize() == st1.disk.bytes +--- +- true +... +i1:len() == st1.disk.rows +--- +- true +... +i2:len() == st2.disk.rows +--- +- true +... +i1:bsize() == st1.disk.index_size + st1.disk.bloom_size +--- +- true +... +i2:bsize() == st2.disk.index_size + st2.disk.bloom_size + st2.disk.bytes +--- +- true +... +s:drop() +--- +... test_run:cmd('switch default') --- - true diff --git a/test/vinyl/info.test.lua b/test/vinyl/info.test.lua index b1c9bd5f3c..1da74ca963 100644 --- a/test/vinyl/info.test.lua +++ b/test/vinyl/info.test.lua @@ -309,6 +309,73 @@ stat_diff(gstat(), st, 'tx') box.commit() stat_diff(gstat(), st, 'tx') +s:drop() + +-- +-- space.bsize, index.len, index.bsize +-- + +s = box.schema.space.create('test', {engine = 'vinyl'}) +s:bsize() +i1 = s:create_index('i1', {parts = {1, 'unsigned'}, run_count_per_level = 1}) +i2 = s:create_index('i2', {parts = {2, 'unsigned'}, run_count_per_level = 1}) +s:bsize() +i1:len(), i2:len() +i1:bsize(), i2:bsize() + +for i = 1, 100, 2 do s:replace{i, i, pad()} end +st1 = i1:info() +st2 = i2:info() +s:bsize() +i1:len(), i2:len() +i1:bsize(), i2:bsize() +s:bsize() == st1.memory.bytes +i1:len() == st1.memory.rows +i2:len() == st2.memory.rows +i1:bsize() == st1.memory.index_size +i2:bsize() == st2.memory.index_size + +box.snapshot() +st1 = i1:info() +st2 = i2:info() +s:bsize() +i1:len(), i2:len() +i1:bsize(), i2:bsize() +s:bsize() == st1.disk.bytes +i1:len() == st1.disk.rows +i2:len() == st2.disk.rows +i1:bsize() == st1.disk.index_size + st1.disk.bloom_size +i2:bsize() == st2.disk.index_size + st2.disk.bloom_size + st2.disk.bytes + +for i = 1, 100, 2 do s:delete(i) end +for i = 2, 100, 2 do s:replace{i, i, pad()} end +st1 = i1:info() +st2 = i2:info() +s:bsize() +i1:len(), i2:len() +i1:bsize(), i2:bsize() +s:bsize() == st1.memory.bytes + st1.disk.bytes +i1:len() == st1.memory.rows + st1.disk.rows +i2:len() == st2.memory.rows + st2.disk.rows +i1:bsize() == st1.memory.index_size + st1.disk.index_size + st1.disk.bloom_size +i2:bsize() == st2.memory.index_size + st2.disk.index_size + st2.disk.bloom_size + st2.disk.bytes + +box.snapshot() +wait(function() return i1:info() end, st1, 'disk.compact.count', 1) +wait(function() return i2:info() end, st2, 'disk.compact.count', 1) +st1 = i1:info() +st2 = i2:info() +s:bsize() +i1:len(), i2:len() +i1:bsize(), i2:bsize() +s:bsize() == st1.disk.bytes +i1:len() == st1.disk.rows +i2:len() == st2.disk.rows +i1:bsize() == st1.disk.index_size + st1.disk.bloom_size +i2:bsize() == st2.disk.index_size + st2.disk.bloom_size + st2.disk.bytes + +s:drop() + test_run:cmd('switch default') test_run:cmd('stop server test') test_run:cmd('cleanup server test') -- GitLab