Skip to content
Snippets Groups Projects
Commit 52672a7d authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Merge remote-tracking branch 'origin/fix-662-rtree-index-common-arena'

parents 5f72a3b8 848f7712
No related branches found
No related tags found
No related merge requests found
......@@ -29,14 +29,15 @@
#include "memtx_rtree.h"
#include "tuple.h"
#include "space.h"
#include "memtx_engine.h"
#include "errinj.h"
#include "fiber.h"
#include "small/small.h"
/** For all memory used by all rtree indexes. */
static struct mempool rtree_page_pool;
/** Number of allocated pages. */
static int rtree_page_pool_initialized = 0;
/**
* Single-linked list of free rtree pages
*/
static void *rtree_free_pages = 0;
/* {{{ Utilities. *************************************************/
......@@ -125,17 +126,40 @@ static void *
rtree_page_alloc()
{
ERROR_INJECT(ERRINJ_INDEX_ALLOC, return 0);
return mempool_alloc(&rtree_page_pool);
if (!rtree_free_pages) {
/**
* No free pages in list - let's allocate new extent, split it
* into pages and add them to the list.
*/
char *extent = (char *)memtx_index_extent_alloc();
if (!extent) {
panic("%s", "Memory allocation failed in rtree");
return 0;
}
assert(MEMTX_EXTENT_SIZE % RTREE_PAGE_SIZE == 0);
assert(RTREE_PAGE_SIZE >= sizeof(void *));
for (size_t i = 0; i < MEMTX_EXTENT_SIZE; i += RTREE_PAGE_SIZE) {
*(void **)(extent + i) = rtree_free_pages;
rtree_free_pages = (void *)(extent + i);
}
}
/* Now we surely have a free page in free list */
void *res = rtree_free_pages;
rtree_free_pages = *(void **)rtree_free_pages;
return res;
}
static void
rtree_page_free(void *page)
{
return mempool_free(&rtree_page_pool, page);
/* Just add to free list. */
*(void **)page = rtree_free_pages;
rtree_free_pages = page;
}
MemtxRTree::~MemtxRTree()
{
// Iterator has to be destroye prior to tree
// Iterator has to be destroyed prior to tree
if (m_position != NULL) {
index_rtree_iterator_free(m_position);
m_position = NULL;
......@@ -150,11 +174,7 @@ MemtxRTree::MemtxRTree(struct key_def *key_def)
assert(key_def->parts[0].type = ARRAY);
assert(key_def->is_unique == false);
if (rtree_page_pool_initialized == 0) {
mempool_create(&rtree_page_pool, &cord()->slabc,
RTREE_PAGE_SIZE);
rtree_page_pool_initialized = 1;
}
memtx_index_arena_init();
rtree_init(&tree, rtree_page_alloc, rtree_page_free);
}
......
errinj = require('box.error.injection')
s = box.schema.create_space('spatial')
s:create_index('primary')
s:create_index('spatial', { type = 'rtree', unique = false, parts = {2, 'array'}})
errinj.set("ERRINJ_INDEX_ALLOC", true)
s:insert{1,{0,0}}
s:insert{2,{0,10}}
s:insert{3,{0,50}}
s:insert{4,{10,0}}
s:insert{5,{50,0}}
s:insert{6,{10,10}}
s:insert{7,{10,50}}
s:insert{8,{50,10}}
s:insert{9,{50,50}}
errinj.set("ERRINJ_INDEX_ALLOC", false)
s:drop()
......@@ -2,8 +2,8 @@
core = tarantool
description = tarantool/box, minimal configuration
script = box.lua
disabled =
disabled = rtree_errinj.test.lua
valgrind_disabled = admin_coredump.test.lua
release_disabled = errinj.test.lua errinj_index.test.lua cmdline.test.lua
release_disabled = errinj.test.lua errinj_index.test.lua rtree_errinj.test.lua cmdline.test.lua
lua_libs = lua/fiber.lua lua/fifo.lua
use_unix_sockets = True
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment