Skip to content

Commit 22fa88a

Browse files
committed
tree: compact the node's parent and extra fields into one
This shrinks the tree node to just 3*sizeof(void *). Running perf_tree yields (times in seconds): | 32-bit | 64-bit | non-c | comp | non-c | comp -----------+-------+-------+-------+------- insertions | 0.529 | 0.631 | 0.525 | 0.649 finds | 5.655 | 6.515 | 5.523 | 6.362 deletions | 0.334 | 0.310 | 0.260 | 0.328 Because the compacting slows down the tree operations 15-20%, the non-compacted layout is still supported by rebuilding the library without JEFFPC_TREE_COMPACT defined. Signed-off-by: Josef 'Jeff' Sipek <[email protected]>
1 parent 756f0a9 commit 22fa88a

File tree

4 files changed

+34
-0
lines changed

4 files changed

+34
-0
lines changed

cmake/config.cmake

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ endif()
9393
set(JEFFPC_LOCK_DEP_COUNT 16)
9494
set(JEFFPC_LOCK_STACK_DEPTH 32)
9595

96+
set(JEFFPC_TREE_COMPACT 1)
97+
9698
include("${CMAKE_DIR}/config-errno.cmake")
9799

98100
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/include/jeffpc/config.h.in"

include/jeffpc/config.h.in

+2
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,6 @@
4848
#cmakedefine JEFFPC_LOCK_DEP_COUNT ${JEFFPC_LOCK_DEP_COUNT}
4949
#cmakedefine JEFFPC_LOCK_STACK_DEPTH ${JEFFPC_LOCK_STACK_DEPTH}
5050

51+
#cmakedefine JEFFPC_TREE_COMPACT ${JEFFPC_TREE_COMPACT}
52+
5153
#endif

include/jeffpc/tree_private.h

+12
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,23 @@
2626
#include <stdbool.h>
2727

2828
#include <jeffpc/int.h>
29+
#include <jeffpc/config.h>
2930

3031
struct tree_node {
3132
struct tree_node *children[2];
33+
#ifdef JEFFPC_TREE_COMPACT
34+
/*
35+
* The following field encodes both the parent pointer and the 2-bit
36+
* extra field.
37+
*
38+
* The extra field uses the 2 least significant bits. The remainder
39+
* of the value is the parent pointer.
40+
*/
41+
uintptr_t _parent_and_extra;
42+
#else
3243
struct tree_node *_parent;
3344
unsigned int _extra:2;
45+
#endif
3446
};
3547

3648
struct tree_tree {

tree_impl.h

+18
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,40 @@ static inline struct tree_node *obj2node(struct tree_tree *tree, void *obj)
4343

4444
static inline struct tree_node *get_parent(struct tree_node *node)
4545
{
46+
#ifdef JEFFPC_TREE_COMPACT
47+
return (void *) (node->_parent_and_extra & ~0x3ul);
48+
#else
4649
return node->_parent;
50+
#endif
4751
}
4852

4953
static inline void set_parent(struct tree_node *node, struct tree_node *parent)
5054
{
55+
#ifdef JEFFPC_TREE_COMPACT
56+
node->_parent_and_extra = (node->_parent_and_extra & 0x3ul) |
57+
(((uintptr_t) parent) & ~0x3ul);
58+
#else
5159
node->_parent = parent;
60+
#endif
5261
}
5362

5463
static inline unsigned int get_extra(struct tree_node *node)
5564
{
65+
#ifdef JEFFPC_TREE_COMPACT
66+
return node->_parent_and_extra & 0x3;
67+
#else
5668
return node->_extra;
69+
#endif
5770
}
5871

5972
static inline void set_extra(struct tree_node *node, unsigned int extra)
6073
{
74+
#ifdef JEFFPC_TREE_COMPACT
75+
node->_parent_and_extra = (node->_parent_and_extra & ~0x3ul) |
76+
(extra & 0x3);
77+
#else
6178
node->_extra = extra;
79+
#endif
6280
}
6381

6482
static inline enum tree_dir which_dir(struct tree_node *parent,

0 commit comments

Comments
 (0)