mirror of
https://github.com/moparisthebest/spdylay
synced 2024-11-14 21:45:13 -05:00
Get rid of flags member in spdylay_map
This commit is contained in:
parent
24e932dfa2
commit
46e7da2166
@ -24,12 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "spdylay_map.h"
|
#include "spdylay_map.h"
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SUB_LEFT = 1,
|
|
||||||
SUB_RIGHT = 1 << 1,
|
|
||||||
SUB_ALL = (1 << 2) - 1
|
|
||||||
} spdylay_map_subtr;
|
|
||||||
|
|
||||||
void spdylay_map_init(spdylay_map *map)
|
void spdylay_map_init(spdylay_map *map)
|
||||||
{
|
{
|
||||||
map->root = NULL;
|
map->root = NULL;
|
||||||
@ -41,31 +35,102 @@ void spdylay_map_free(spdylay_map *map)
|
|||||||
map->root = NULL;
|
map->root = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find left most node, which is not necessarily a leaf. */
|
||||||
|
static spdylay_map_entry* find_left_most(spdylay_map_entry *entry)
|
||||||
|
{
|
||||||
|
while(entry->left) {
|
||||||
|
entry = entry->left;
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find left most leaf. */
|
||||||
|
static spdylay_map_entry* find_left_most_leaf(spdylay_map_entry *entry)
|
||||||
|
{
|
||||||
|
for(;;) {
|
||||||
|
entry = find_left_most(entry);
|
||||||
|
if(entry->right) {
|
||||||
|
entry = entry->right;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns next node in postorder traversal. Returns NULL if there is
|
||||||
|
no next node. */
|
||||||
|
static spdylay_map_entry* traverse_postorder(spdylay_map_entry *parent,
|
||||||
|
spdylay_map_entry *entry)
|
||||||
|
{
|
||||||
|
if(!parent) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(parent->left == entry) {
|
||||||
|
if(parent->right) {
|
||||||
|
return find_left_most_leaf(parent->right);
|
||||||
|
} else {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void spdylay_map_each_free(spdylay_map *map,
|
void spdylay_map_each_free(spdylay_map *map,
|
||||||
int (*func)(spdylay_map_entry *entry, void *ptr),
|
int (*func)(spdylay_map_entry *entry, void *ptr),
|
||||||
void *ptr)
|
void *ptr)
|
||||||
{
|
{
|
||||||
spdylay_map_entry *entry = map->root;
|
spdylay_map_entry *entry;
|
||||||
|
if(!map->root) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entry = find_left_most_leaf(map->root);
|
||||||
while(entry) {
|
while(entry) {
|
||||||
if(entry->flags == SUB_ALL) {
|
|
||||||
spdylay_map_entry *parent = entry->parent;
|
spdylay_map_entry *parent = entry->parent;
|
||||||
|
/* Ignore return value. */
|
||||||
func(entry, ptr);
|
func(entry, ptr);
|
||||||
entry = parent;
|
/* entry has been deleted. */
|
||||||
} else if(entry->flags == SUB_LEFT) {
|
entry = traverse_postorder(parent, entry);
|
||||||
entry->flags |= SUB_RIGHT;
|
|
||||||
if(entry->right) {
|
|
||||||
entry = entry->right;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
entry->flags |= SUB_LEFT;
|
|
||||||
if(entry->left) {
|
|
||||||
entry = entry->left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
map->root = NULL;
|
map->root = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns next node in inorder traversal. Returns NULL if there is no
|
||||||
|
next node. */
|
||||||
|
static spdylay_map_entry* traverse_inorder(spdylay_map_entry *entry)
|
||||||
|
{
|
||||||
|
spdylay_map_entry *parent;
|
||||||
|
if(entry->right) {
|
||||||
|
return find_left_most(entry->right);
|
||||||
|
}
|
||||||
|
parent = entry->parent;
|
||||||
|
while(parent && parent->right == entry) {
|
||||||
|
entry = entry->parent;
|
||||||
|
parent = parent->parent;
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spdylay_map_each(spdylay_map *map,
|
||||||
|
int (*func)(spdylay_map_entry *entry, void *ptr),
|
||||||
|
void *ptr)
|
||||||
|
{
|
||||||
|
spdylay_map_entry *entry;
|
||||||
|
if(!map->root) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
entry = find_left_most(map->root);
|
||||||
|
while(entry) {
|
||||||
|
int rv = func(entry, ptr);
|
||||||
|
if(rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
entry = traverse_inorder(entry);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 32 bit Mix Functions by Thomas Wang
|
* 32 bit Mix Functions by Thomas Wang
|
||||||
*
|
*
|
||||||
@ -87,7 +152,6 @@ void spdylay_map_entry_init(spdylay_map_entry *entry, key_type key)
|
|||||||
entry->key = key;
|
entry->key = key;
|
||||||
entry->parent = entry->left = entry->right = NULL;
|
entry->parent = entry->left = entry->right = NULL;
|
||||||
entry->priority = hash32shift(key);
|
entry->priority = hash32shift(key);
|
||||||
entry->flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static spdylay_map_entry* rotate_left(spdylay_map_entry *entry)
|
static spdylay_map_entry* rotate_left(spdylay_map_entry *entry)
|
||||||
@ -270,36 +334,3 @@ size_t spdylay_map_size(spdylay_map *map)
|
|||||||
{
|
{
|
||||||
return map->size;
|
return map->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spdylay_map_each(spdylay_map *map,
|
|
||||||
int (*func)(spdylay_map_entry *entry, void *ptr),
|
|
||||||
void *ptr)
|
|
||||||
{
|
|
||||||
spdylay_map_entry *entry = map->root;
|
|
||||||
while(entry) {
|
|
||||||
if(entry->flags == SUB_ALL) {
|
|
||||||
entry->flags = 0;
|
|
||||||
entry = entry->parent;
|
|
||||||
} else if(entry->flags == SUB_LEFT) {
|
|
||||||
int rv;
|
|
||||||
rv = func(entry, ptr);
|
|
||||||
if(rv != 0) {
|
|
||||||
while(entry) {
|
|
||||||
entry->flags = 0;
|
|
||||||
entry = entry->parent;
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
entry->flags |= SUB_RIGHT;
|
|
||||||
if(entry->right) {
|
|
||||||
entry = entry->right;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
entry->flags |= SUB_LEFT;
|
|
||||||
if(entry->left) {
|
|
||||||
entry = entry->left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -41,7 +41,6 @@ typedef struct spdylay_map_entry {
|
|||||||
key_type key;
|
key_type key;
|
||||||
struct spdylay_map_entry *parent, *left, *right;
|
struct spdylay_map_entry *parent, *left, *right;
|
||||||
pri_type priority;
|
pri_type priority;
|
||||||
uint8_t flags;
|
|
||||||
} spdylay_map_entry;
|
} spdylay_map_entry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -125,7 +125,7 @@ void test_spdylay_map_functional(void)
|
|||||||
// insertion
|
// insertion
|
||||||
shuffle(order, NUM_ENT);
|
shuffle(order, NUM_ENT);
|
||||||
for(i = 0; i < NUM_ENT; ++i) {
|
for(i = 0; i < NUM_ENT; ++i) {
|
||||||
CU_ASSERT(0 == spdylay_map_insert(&map, &arr[i].map_entry));
|
CU_ASSERT(0 == spdylay_map_insert(&map, &arr[order[i] - 1].map_entry));
|
||||||
}
|
}
|
||||||
// traverse
|
// traverse
|
||||||
spdylay_map_each(&map, eachfun, NULL);
|
spdylay_map_each(&map, eachfun, NULL);
|
||||||
@ -140,7 +140,15 @@ void test_spdylay_map_functional(void)
|
|||||||
CU_ASSERT(0 == spdylay_map_remove(&map, order[i]));
|
CU_ASSERT(0 == spdylay_map_remove(&map, order[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
spdylay_map_free(&map);
|
// each_free (but no op function for testing purpose)
|
||||||
|
for(i = 0; i < NUM_ENT; ++i) {
|
||||||
|
strentry_init(&arr[i], i + 1, "foo");
|
||||||
|
}
|
||||||
|
// insert once again
|
||||||
|
for(i = 0; i < NUM_ENT; ++i) {
|
||||||
|
CU_ASSERT(0 == spdylay_map_insert(&map, &arr[i].map_entry));
|
||||||
|
}
|
||||||
|
spdylay_map_each_free(&map, eachfun, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int entry_free(spdylay_map_entry *entry, void *ptr)
|
static int entry_free(spdylay_map_entry *entry, void *ptr)
|
||||||
|
Loading…
Reference in New Issue
Block a user