Skip to content

Commit

Permalink
lib: refactore tree to avoid the use of memset
Browse files Browse the repository at this point in the history
  • Loading branch information
franku committed Nov 5, 2019
1 parent 22589f1 commit 116ff6d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 59 deletions.
1 change: 1 addition & 0 deletions core/src/lib/htable.h
Expand Up @@ -109,6 +109,7 @@ class htable {
void grow_table(); /* Grow the table */

public:
htable() = default;
htable(void* item,
void* link,
int tsize = 31,
Expand Down
30 changes: 14 additions & 16 deletions core/src/lib/rblist.h
Expand Up @@ -57,34 +57,35 @@ struct rblink {
};

class rblist {
public:
rblist() = default;
rblist(void* item, rblink* link);
~rblist(void) { destroy(); }
void* insert(void* item, int compare(void* item1, void* item2));
int size(void) const;
bool empty(void) const;
void* first(void);
void* next(void* item);
void* search(void* item, int compare(void* item1, void* item2));
void remove(void* item);

private:
void* head = nullptr;
int16_t loffset = 0;
uint32_t num_items = 0;
bool down = false;
void LeftRotate(void* item);
void RightRotate(void* item);

public:
rblist(void* item, rblink* link);
rblist(void);
~rblist(void) { destroy(); }
void init(void* item, rblink* link);
void SetParent(void* item, void* parent);
void init(void* item, rblink* link);
void SetLeft(void* item, void* left);
void SetRight(void* item, void* right);
void SetRed(void* item, bool red);
void* parent(const void* item) const;
void* left(const void* item) const;
void* right(const void* item) const;
bool red(const void* item) const;
void* insert(void* item, int compare(void* item1, void* item2));
void* search(void* item, int compare(void* item1, void* item2));
void* first(void);
void* next(void* item);
void* any(void* item);
void remove(void* item);
bool empty(void) const;
int size(void) const;
void destroy(void);
};

Expand All @@ -106,9 +107,6 @@ inline void rblist::init(void* item, rblink* link)

inline rblist::rblist(void* item, rblink* link) { init(item, link); }

/* Constructor with link at head of item */
inline rblist::rblist(void) : head(0), loffset(0), num_items(0) {}

inline void rblist::SetParent(void* item, void* parent)
{
((rblink*)(((char*)item) + loffset))->parent = parent;
Expand Down
30 changes: 16 additions & 14 deletions core/src/lib/tree.cc
Expand Up @@ -37,7 +37,8 @@ static TREE_NODE* search_and_insert_tree_node(char* fname,
int type,
TREE_ROOT* root,
TREE_NODE* parent);
static char* tree_alloc(TREE_ROOT* root, int size);
template <typename T>
static T* tree_alloc(TREE_ROOT* root, int size);

/*
* NOTE !!!!! we turn off Debug messages for performance reasons.
Expand All @@ -64,7 +65,7 @@ static void MallocBuf(TREE_ROOT* root, int size)
mem->next = root->mem;
root->mem = mem;
mem->mem = mem->first;
mem->rem = (char*)mem + size - mem->mem;
mem->rem = (char*)mem + size - (char*)mem->mem;
Dmsg2(200, "malloc buf size=%d rem=%d\n", size, mem->rem);
}

Expand All @@ -82,8 +83,8 @@ TREE_ROOT* new_tree(int count)
if (count < 1000) { /* minimum tree size */
count = 1000;
}
root = (TREE_ROOT*)malloc(sizeof(TREE_ROOT));
memset(root, 0, sizeof(TREE_ROOT));
root = static_cast<TREE_ROOT*>(malloc(sizeof(TREE_ROOT)));
root = new (root) TREE_ROOT();

/*
* Assume filename + node = 40 characters average length
Expand All @@ -108,8 +109,8 @@ static TREE_NODE* new_tree_node(TREE_ROOT* root)
{
TREE_NODE* node;
int size = sizeof(TREE_NODE);
node = (TREE_NODE*)tree_alloc(root, size);
memset(node, 0, size);
node = tree_alloc<TREE_NODE>(root, size);
node = new (node) TREE_NODE();
node->delta_seq = -1;
return node;
}
Expand All @@ -121,14 +122,14 @@ static void FreeTreeNode(TREE_ROOT* root)
{
int asize = BALIGN(sizeof(TREE_NODE));
root->mem->rem += asize;
root->mem->mem -= asize;
root->mem->mem = (char*)root->mem->mem - asize;
}

void TreeRemoveNode(TREE_ROOT* root, TREE_NODE* node)
{
int asize = BALIGN(sizeof(TREE_NODE));
node->parent->child.remove(node);
if ((root->mem->mem - asize) == (char*)node) {
if (((char*)root->mem->mem - asize) == (char*)node) {
FreeTreeNode(root);
} else {
Dmsg0(0, "Can't release tree node\n");
Expand All @@ -140,9 +141,10 @@ void TreeRemoveNode(TREE_ROOT* root, TREE_NODE* node)
* Keep the pointers properly aligned by allocating
* sizes that are aligned.
*/
static char* tree_alloc(TREE_ROOT* root, int size)
template <typename T>
static T* tree_alloc(TREE_ROOT* root, int size)
{
char* buf;
T* buf;
int asize = BALIGN(size);

if (root->mem->rem < asize) {
Expand All @@ -155,8 +157,8 @@ static char* tree_alloc(TREE_ROOT* root, int size)
MallocBuf(root, mb_size);
}
root->mem->rem -= asize;
buf = root->mem->mem;
root->mem->mem += asize;
buf = static_cast<T*>(root->mem->mem);
root->mem->mem = (char*)root->mem->mem + asize;
return buf;
}

Expand Down Expand Up @@ -195,7 +197,7 @@ void TreeAddDeltaPart(TREE_ROOT* root,
int32_t FileIndex)
{
struct delta_list* elt =
(struct delta_list*)tree_alloc(root, sizeof(struct delta_list));
tree_alloc<delta_list>(root, sizeof(struct delta_list));

elt->next = node->delta_list;
elt->JobId = JobId;
Expand Down Expand Up @@ -356,7 +358,7 @@ static TREE_NODE* search_and_insert_tree_node(char* fname,
* It was not found, but is now inserted
*/
node->fname_len = strlen(fname);
node->fname = tree_alloc(root, node->fname_len + 1);
node->fname = tree_alloc<char>(root, node->fname_len + 1);
strcpy(node->fname, fname);
node->parent = parent;
node->type = type;
Expand Down
77 changes: 48 additions & 29 deletions core/src/lib/tree.h
Expand Up @@ -42,7 +42,7 @@
struct s_mem {
struct s_mem* next; /* next buffer */
int rem; /* remaining bytes */
char* mem; /* memory pointer */
void* mem; /* memory pointer */
char first[1]; /* first byte */
};

Expand All @@ -68,60 +68,79 @@ struct delta_list {
* there is one for each file.
*/
struct s_tree_node {
s_tree_node()
: type{false}
, extract{false}
, extract_dir{false}
, hard_link{false}
, soft_link{false}
, inserted{false}
, loaded{false}
{
}
/* KEEP sibling as the first member to avoid having to
* do initialization of child */
rblink sibling;
rblist child;
char* fname; /* file name */
int32_t FileIndex; /* file index */
uint32_t JobId; /* JobId */
int32_t delta_seq; /* current delta sequence */
uint16_t fname_len; /* filename length */
char* fname{}; /* file name */
int32_t FileIndex{}; /* file index */
uint32_t JobId{}; /* JobId */
int32_t delta_seq{}; /* current delta sequence */
uint16_t fname_len{}; /* filename length */
unsigned int type : 8; /* node type */
unsigned int extract : 1; /* extract item */
unsigned int extract_dir : 1; /* extract dir entry only */
unsigned int hard_link : 1; /* set if have hard link */
unsigned int soft_link : 1; /* set if is soft link */
unsigned int inserted : 1; /* set when node newly inserted */
unsigned int loaded : 1; /* set when the dir is in the tree */
struct s_tree_node* parent;
struct s_tree_node* next; /* next hash of FileIndex */
struct delta_list* delta_list; /* delta parts for this node */
uint64_t fhinfo; /* NDMP Fh_info */
uint64_t fhnode; /* NDMP Fh_node */
struct s_tree_node* parent{};
struct s_tree_node* next{}; /* next hash of FileIndex */
struct delta_list* delta_list{}; /* delta parts for this node */
uint64_t fhinfo{}; /* NDMP Fh_info */
uint64_t fhnode{}; /* NDMP Fh_node */
};
typedef struct s_tree_node TREE_NODE;

struct s_tree_root {
s_tree_root()
: type{false}
, extract{false}
, extract_dir{false}
, have_link{false}
, inserted{false}
, loaded{false}
{
}
/* KEEP sibling as the first member to avoid having to
* do initialization of child */
rblink sibling;
rblink sibling{};
rblist child;
const char* fname; /* file name */
int32_t FileIndex; /* file index */
uint32_t JobId; /* JobId */
int32_t delta_seq; /* current delta sequence */
uint16_t fname_len; /* filename length */
const char* fname{}; /* file name */
int32_t FileIndex{}; /* file index */
uint32_t JobId{}; /* JobId */
int32_t delta_seq{}; /* current delta sequence */
uint16_t fname_len{}; /* filename length */
unsigned int type : 8; /* node type */
unsigned int extract : 1; /* extract item */
unsigned int extract_dir : 1; /* extract dir entry only */
unsigned int have_link : 1; /* set if have hard link */
unsigned int inserted : 1; /* set when newly inserted */
unsigned int loaded : 1; /* set when the dir is in the tree */
struct s_tree_node* parent;
struct s_tree_node* next; /* next hash of FileIndex */
struct delta_list* delta_list; /* delta parts for this node */
struct s_tree_node* parent{};
struct s_tree_node* next{}; /* next hash of FileIndex */
struct delta_list* delta_list{}; /* delta parts for this node */

/* The above ^^^ must be identical to a TREE_NODE structure */
struct s_tree_node* first; /* first entry in the tree */
struct s_tree_node* last; /* last entry in tree */
struct s_mem* mem; /* tree memory */
uint32_t total_size; /* total bytes allocated */
uint32_t blocks; /* total mallocs */
int cached_path_len; /* length of cached path */
char* cached_path; /* cached current path */
TREE_NODE* cached_parent; /* cached parent for above path */
htable hardlinks; /* references to first occurence of hardlinks */
struct s_tree_node* first{}; /* first entry in the tree */
struct s_tree_node* last{}; /* last entry in tree */
struct s_mem* mem{}; /* tree memory */
uint32_t total_size{}; /* total bytes allocated */
uint32_t blocks{}; /* total mallocs */
int cached_path_len{}; /* length of cached path */
char* cached_path{}; /* cached current path */
TREE_NODE* cached_parent{}; /* cached parent for above path */
htable hardlinks; /* references to first occurence of hardlinks */
};
typedef struct s_tree_root TREE_ROOT;

Expand Down

0 comments on commit 116ff6d

Please sign in to comment.