Refactor rtree to always use base_alloc() for node allocation.

This commit is contained in:
Jason Evans 2016-04-16 00:36:11 -07:00
parent db72272bef
commit 8c9be3e837
15 changed files with 315 additions and 217 deletions

View file

@ -23,13 +23,6 @@ typedef struct rtree_s rtree_t;
/* Used for two-stage lock-free node initialization. */
#define RTREE_NODE_INITIALIZING ((rtree_elm_t *)0x1)
/*
* The node allocation callback function's argument is the number of contiguous
* rtree_elm_t structures to allocate, and the resulting memory must be zeroed.
*/
typedef rtree_elm_t *(rtree_node_alloc_t)(size_t);
typedef void (rtree_node_dalloc_t)(rtree_elm_t *);
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
@ -79,8 +72,6 @@ struct rtree_level_s {
};
struct rtree_s {
rtree_node_alloc_t *alloc;
rtree_node_dalloc_t *dalloc;
unsigned height;
/*
* Precomputed table used to convert from the number of leading 0 key
@ -94,12 +85,18 @@ struct rtree_s {
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
bool rtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc,
rtree_node_dalloc_t *dalloc);
void rtree_delete(rtree_t *rtree);
rtree_elm_t *rtree_subtree_read_hard(rtree_t *rtree, unsigned level);
rtree_elm_t *rtree_child_read_hard(rtree_t *rtree, rtree_elm_t *elm,
bool rtree_new(rtree_t *rtree, unsigned bits);
#ifdef JEMALLOC_JET
typedef rtree_elm_t *(rtree_node_alloc_t)(tsdn_t *, rtree_t *, size_t);
extern rtree_node_alloc_t *rtree_node_alloc;
typedef void (rtree_node_dalloc_t)(tsdn_t *, rtree_t *, rtree_elm_t *);
extern rtree_node_dalloc_t *rtree_node_dalloc;
void rtree_delete(tsdn_t *tsdn, rtree_t *rtree);
#endif
rtree_elm_t *rtree_subtree_read_hard(tsdn_t *tsdn, rtree_t *rtree,
unsigned level);
rtree_elm_t *rtree_child_read_hard(tsdn_t *tsdn, rtree_t *rtree,
rtree_elm_t *elm, unsigned level);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
@ -111,25 +108,27 @@ uintptr_t rtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level);
bool rtree_node_valid(rtree_elm_t *node);
rtree_elm_t *rtree_child_tryread(rtree_elm_t *elm, bool dependent);
rtree_elm_t *rtree_child_read(rtree_t *rtree, rtree_elm_t *elm,
rtree_elm_t *rtree_child_read(tsdn_t *tsdn, rtree_t *rtree, rtree_elm_t *elm,
unsigned level, bool dependent);
extent_t *rtree_elm_read(rtree_elm_t *elm, bool dependent);
void rtree_elm_write(rtree_elm_t *elm, const extent_t *extent);
rtree_elm_t *rtree_subtree_tryread(rtree_t *rtree, unsigned level,
bool dependent);
rtree_elm_t *rtree_subtree_read(rtree_t *rtree, unsigned level,
bool dependent);
rtree_elm_t *rtree_elm_lookup(rtree_t *rtree, uintptr_t key,
rtree_elm_t *rtree_subtree_read(tsdn_t *tsdn, rtree_t *rtree,
unsigned level, bool dependent);
rtree_elm_t *rtree_elm_lookup(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key,
bool dependent, bool init_missing);
bool rtree_write(rtree_t *rtree, uintptr_t key, const extent_t *extent);
extent_t *rtree_read(rtree_t *rtree, uintptr_t key, bool dependent);
rtree_elm_t *rtree_elm_acquire(rtree_t *rtree, uintptr_t key,
bool rtree_write(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key,
const extent_t *extent);
extent_t *rtree_read(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key,
bool dependent);
rtree_elm_t *rtree_elm_acquire(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key,
bool dependent, bool init_missing);
extent_t *rtree_elm_read_acquired(rtree_elm_t *elm);
void rtree_elm_write_acquired(rtree_elm_t *elm, const extent_t *extent);
void rtree_elm_release(rtree_elm_t *elm);
void rtree_clear(rtree_t *rtree, uintptr_t key);
void rtree_clear(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_RTREE_C_))
@ -177,14 +176,14 @@ rtree_child_tryread(rtree_elm_t *elm, bool dependent)
}
JEMALLOC_ALWAYS_INLINE rtree_elm_t *
rtree_child_read(rtree_t *rtree, rtree_elm_t *elm, unsigned level,
rtree_child_read(tsdn_t *tsdn, rtree_t *rtree, rtree_elm_t *elm, unsigned level,
bool dependent)
{
rtree_elm_t *child;
child = rtree_child_tryread(elm, dependent);
if (!dependent && unlikely(!rtree_node_valid(child)))
child = rtree_child_read_hard(rtree, elm, level);
child = rtree_child_read_hard(tsdn, rtree, elm, level);
assert(!dependent || child != NULL);
return (child);
}
@ -238,19 +237,19 @@ rtree_subtree_tryread(rtree_t *rtree, unsigned level, bool dependent)
}
JEMALLOC_ALWAYS_INLINE rtree_elm_t *
rtree_subtree_read(rtree_t *rtree, unsigned level, bool dependent)
rtree_subtree_read(tsdn_t *tsdn, rtree_t *rtree, unsigned level, bool dependent)
{
rtree_elm_t *subtree;
subtree = rtree_subtree_tryread(rtree, level, dependent);
if (!dependent && unlikely(!rtree_node_valid(subtree)))
subtree = rtree_subtree_read_hard(rtree, level);
subtree = rtree_subtree_read_hard(tsdn, rtree, level);
assert(!dependent || subtree != NULL);
return (subtree);
}
JEMALLOC_ALWAYS_INLINE rtree_elm_t *
rtree_elm_lookup(rtree_t *rtree, uintptr_t key, bool dependent,
rtree_elm_lookup(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key, bool dependent,
bool init_missing)
{
uintptr_t subkey;
@ -261,8 +260,8 @@ rtree_elm_lookup(rtree_t *rtree, uintptr_t key, bool dependent,
start_level = rtree_start_level(rtree, key);
node = init_missing ? rtree_subtree_read(rtree, start_level, dependent)
: rtree_subtree_tryread(rtree, start_level, dependent);
node = init_missing ? rtree_subtree_read(tsdn, rtree, start_level,
dependent) : rtree_subtree_tryread(rtree, start_level, dependent);
#define RTREE_GET_BIAS (RTREE_HEIGHT_MAX - rtree->height)
switch (start_level + RTREE_GET_BIAS) {
#define RTREE_GET_SUBTREE(level) \
@ -272,7 +271,7 @@ rtree_elm_lookup(rtree_t *rtree, uintptr_t key, bool dependent,
return (NULL); \
subkey = rtree_subkey(rtree, key, level - \
RTREE_GET_BIAS); \
node = init_missing ? rtree_child_read(rtree, \
node = init_missing ? rtree_child_read(tsdn, rtree, \
&node[subkey], level - RTREE_GET_BIAS, dependent) : \
rtree_child_tryread(&node[subkey], dependent); \
/* Fall through. */
@ -346,14 +345,14 @@ rtree_elm_lookup(rtree_t *rtree, uintptr_t key, bool dependent,
}
JEMALLOC_INLINE bool
rtree_write(rtree_t *rtree, uintptr_t key, const extent_t *extent)
rtree_write(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key, const extent_t *extent)
{
rtree_elm_t *elm;
assert(extent != NULL); /* Use rtree_clear() for this case. */
assert(((uintptr_t)extent & (uintptr_t)0x1) == (uintptr_t)0x0);
elm = rtree_elm_lookup(rtree, key, false, true);
elm = rtree_elm_lookup(tsdn, rtree, key, false, true);
if (elm == NULL)
return (true);
assert(rtree_elm_read(elm, false) == NULL);
@ -363,11 +362,11 @@ rtree_write(rtree_t *rtree, uintptr_t key, const extent_t *extent)
}
JEMALLOC_ALWAYS_INLINE extent_t *
rtree_read(rtree_t *rtree, uintptr_t key, bool dependent)
rtree_read(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key, bool dependent)
{
rtree_elm_t *elm;
elm = rtree_elm_lookup(rtree, key, dependent, false);
elm = rtree_elm_lookup(tsdn, rtree, key, dependent, false);
if (elm == NULL)
return (NULL);
@ -375,12 +374,12 @@ rtree_read(rtree_t *rtree, uintptr_t key, bool dependent)
}
JEMALLOC_INLINE rtree_elm_t *
rtree_elm_acquire(rtree_t *rtree, uintptr_t key, bool dependent,
rtree_elm_acquire(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key, bool dependent,
bool init_missing)
{
rtree_elm_t *elm;
elm = rtree_elm_lookup(rtree, key, dependent, init_missing);
elm = rtree_elm_lookup(tsdn, rtree, key, dependent, init_missing);
if (!dependent && elm == NULL)
return (NULL);
{
@ -427,11 +426,11 @@ rtree_elm_release(rtree_elm_t *elm)
}
JEMALLOC_INLINE void
rtree_clear(rtree_t *rtree, uintptr_t key)
rtree_clear(tsdn_t *tsdn, rtree_t *rtree, uintptr_t key)
{
rtree_elm_t *elm;
elm = rtree_elm_acquire(rtree, key, true, false);
elm = rtree_elm_acquire(tsdn, rtree, key, true, false);
rtree_elm_write_acquired(elm, NULL);
rtree_elm_release(elm);
}