Ejemplo n.º 1
0
extern node_t *
ct_prev_node(node_t *root, PyObject *key)
{
	node_t *prev = NULL;
	node_t *node = root;
	int cval;

	while (node != NULL) {
		cval = ct_compare(key, KEY(node));
		if (cval == 0)
			break;
		else if (cval < 0)
			node = LEFT_NODE(node);
		else {
			if ((prev == NULL) || (ct_compare(KEY(node), KEY(prev)) > 0))
				prev = node;
			node = RIGHT_NODE(node);
		}
	}
	if (node == NULL) 
		return NULL;
	
	if (LEFT_NODE(node) != NULL) {
		
		node = LEFT_NODE(node);
		while (RIGHT_NODE(node) != NULL)
			node = RIGHT_NODE(node);
		if (prev == NULL)
			prev = node;
		else if (ct_compare(KEY(node), KEY(prev)) > 0)
			prev = node;
	}
	return prev;
}
Ejemplo n.º 2
0
node_t *ct_prev_node(node_t *root, node_t *node)
{
	node_t *prev;
	node_t *tmp; 

	if ((prev = LEFT_NODE(node)) != NULL) {
		// find the largest node of left-subtee
		while ( (tmp=RIGHT_NODE(prev)) != NULL) {
			prev = tmp;
		}
		return prev; 
	} else {
		// node has no left sub-tree
		node_t *parent = PARENT_NODE(node); 
		while (1) {
			if (parent == NULL) {
				return NULL; 
			} else if (LEFT_NODE(parent) == node) {
				node = parent; 
				parent = PARENT_NODE(node); 
			} else {
				return parent; 
			}
		}	
	}
}
Ejemplo n.º 3
0
extern node_t *
ct_succ_node(node_t *root, PyObject *key)
{
	node_t *succ = NULL;
	node_t *node = root;
	int cval;

	while (node != NULL) {
		cval = ct_compare(key, KEY(node));
		if (cval == 0)
			break;
		else if (cval < 0) {
			if ((succ == NULL) ||
				(ct_compare(KEY(node), KEY(succ)) < 0))
				succ = node;
			node = LEFT_NODE(node);
		} else
			node = RIGHT_NODE(node);
	}
	if (node == NULL)
		return NULL;
	
	if (RIGHT_NODE(node) != NULL) {
		
		node = RIGHT_NODE(node);
		while (LEFT_NODE(node) != NULL)
			node = LEFT_NODE(node);
		if (succ == NULL)
			succ = node;
		else if (ct_compare(KEY(node), KEY(succ)) < 0)
			succ = node;
	}
	return succ;
}
Ejemplo n.º 4
0
static int ct_validate_range(node_t *root, PyObject *minkey, PyObject *maxkey)
{
	PyObject *key;
	if (root == NULL) return 1;

	if (!(LEFT_NODE(root) == NULL || PARENT_NODE(LEFT_NODE(root)) == root )) {
		PyErr_SetString(PyExc_AssertionError, "left node parent is wrong");
		return 0;
	}
	if (!(RIGHT_NODE(root) == NULL || PARENT_NODE(RIGHT_NODE(root)) == root )) {
		PyErr_SetString(PyExc_AssertionError, "right node parent is wrong");
		return 0;
	}

	key = KEY(root);
	if (minkey != NULL) {
		if (ct_compare(key, minkey) <= 0) {
			PyErr_SetString(PyExc_AssertionError, "key order is wrong");
			return 0;
		}
	}
	if (maxkey != NULL) {
		if (ct_compare(key, maxkey) >= 0) {
			PyErr_SetString(PyExc_AssertionError, "key order is wrong");
			return 0;
		}
	}
	return 1;
}
Ejemplo n.º 5
0
extern int
ct_index_of(node_t *root, PyObject *key)
{
	node_t *node = root;
	int index = 0;
	int go_down = 1;
	node_stack_t *stack;
	stack = stack_init(32);

	for (;;) {
		if ((LEFT_NODE(node) != NULL) && go_down) {
			stack_push(stack, node);
			node = LEFT_NODE(node);
		}
		else {
			if (ct_compare(KEY(node), key) == 0) {
				stack_delete(stack);
				return index;
			}
			index++;
			if (RIGHT_NODE(node) != NULL) {
				node = RIGHT_NODE(node);
				go_down = 1;
			}
			else {
				if (stack_is_empty(stack)) {
					stack_delete(stack);
					return -1;
				}
				node = stack_pop(stack);
				go_down = 0;
			}
		}
	}
}
Ejemplo n.º 6
0
extern node_t *
ct_min_node(node_t *root)
{
	if (root == NULL)
		return NULL;
	while (LEFT_NODE(root) != NULL)
		root = LEFT_NODE(root);
	return root;
}
Ejemplo n.º 7
0
extern int
ct_bintree_remove(node_t **rootaddr, PyObject *key)
{
	node_t *node, *parent, *replacement;
	int direction, cmp_res, down_dir;

	node = *rootaddr;

	if (node == NULL)
		return 0; 
	parent = NULL;
	direction = 0;

	while (1) {
		cmp_res = ct_compare(key, KEY(node));
		if (cmp_res == 0) 
		{
			if ((LEFT_NODE(node) != NULL) && (RIGHT_NODE(node) != NULL)) {
				
				parent = node;
				direction = RIGHT;
				replacement = RIGHT_NODE(node);
				while (LEFT_NODE(replacement) != NULL) {
					parent = replacement;
					direction = LEFT;
					replacement = LEFT_NODE(replacement);
				}
				LINK(parent, direction) = RIGHT_NODE(replacement);
				
				ct_swap_data(node, replacement);
				node = replacement; 
			}
			else {
				down_dir = (LEFT_NODE(node) == NULL) ? RIGHT : LEFT;
				if (parent == NULL) 
				{
					*rootaddr = LINK(node, down_dir);
				}
				else {
					LINK(parent, direction) = LINK(node, down_dir);
				}
			}
			ct_delete_node(node);
			return 1; 
		}
		else {
			direction = (cmp_res < 0) ? LEFT : RIGHT;
			parent = node;
			node = LINK(node, direction);
			if (node == NULL)
				return 0; 
		}
	}
}
Ejemplo n.º 8
0
extern void
ct_delete_tree(node_t *root)
{
	if (root == NULL)
		return;
	if (LEFT_NODE(root) != NULL) {
		ct_delete_tree(LEFT_NODE(root));
	}
	if (RIGHT_NODE(root) != NULL) {
		ct_delete_tree(RIGHT_NODE(root));
	}
	ct_delete_node(root);
}
Ejemplo n.º 9
0
int
ct_bintree_insert(node_t **rootaddr, PyObject *key, PyObject *value)
{
	int cval;
	node_t *parent = NULL;

	while (1) {
		node_t *root = *rootaddr;
		if (root == NULL) {
			node_t *node = ct_new_node(parent, key, value, 0);
			if (node == NULL) return -1;
			*rootaddr = node;
			return 1;
		}

		cval = ct_compare(key, KEY(root));
		if (cval < 0) {
			// use left tree
			rootaddr = &LEFT_NODE(root);
		} else if (cval > 0) {
			rootaddr = &RIGHT_NODE(root);
		} else {
			/* key exists, replace value object? no! */
			// Py_XDECREF(VALUE(root)); /* release old value object */
			// VALUE(root) = value;     /* set new value object     */
			// Py_INCREF(value);     /* take new value object    */
			return 0; 
		}
		parent = root;
	}
}
Ejemplo n.º 10
0
node_t *ct_succ_node(node_t *root, node_t *node)
{
	node_t *succ;
	node_t *tmp; 

	if ( (succ = RIGHT_NODE(node)) != NULL) {
		/* find smallest node of right subtree */
		while ( (tmp=LEFT_NODE(succ)) != NULL) {
			succ = tmp;
		}
		return succ;
	} else {
		// node has no right tree
		node_t *parent = PARENT_NODE(node);
		while (1) {
				if (parent == NULL) {
					return NULL;
				} else if (RIGHT_NODE(parent) == node) {
					node = parent;
					parent = PARENT_NODE(node);
				} else {
					// assert(LEFT_NODE(parent) == node);
					return parent;
				}
		}
	}
}
Ejemplo n.º 11
0
void ct_bintree_keys(node_t *root, PyObject *list)
{
	if (root == NULL) {
		return ;
	}

	ct_bintree_keys(LEFT_NODE(root), list);
	PyList_Append(list, KEY(root)); 
	ct_bintree_keys(RIGHT_NODE(root), list);
}
Ejemplo n.º 12
0
void
ct_delete_tree(node_t *root)
{
	if (root == NULL) return ;

	ct_delete_tree(LEFT_NODE(root));
	ct_delete_tree(RIGHT_NODE(root));

	ct_delete_node(root);
}
Ejemplo n.º 13
0
node_t *ct_min_node(node_t *root)
{
	node_t *left;
	if (root == NULL) return NULL;

	while ((left = LEFT_NODE(root)) != NULL) {
		root = left;
	}
	return root;
}
Ejemplo n.º 14
0
static void
ct_delete_node(node_t *node)
{
	if (node != NULL) {
		Py_XDECREF(KEY(node));
		Py_XDECREF(VALUE(node));
		LEFT_NODE(node) = NULL;
		RIGHT_NODE(node) = NULL;
		PyMem_Free(node);
	}
}
Ejemplo n.º 15
0
int ct_validate(node_t *root)
{
	PyObject *key;
	if (root == NULL) return 1;

	if (PARENT_NODE(root) != NULL) {
		PyErr_SetString(PyExc_AssertionError, "parent of root is not null");
		return 0;
	}
	if (!(LEFT_NODE(root) == NULL || PARENT_NODE(LEFT_NODE(root)) == root )) {
		PyErr_SetString(PyExc_AssertionError, "left node parent is wrong");
		return 0;
	}
	if (!(RIGHT_NODE(root) == NULL || PARENT_NODE(RIGHT_NODE(root)) == root )) {
		PyErr_SetString(PyExc_AssertionError, "right node parent is wrong");
		return 0;
	}

	key = KEY(root);
	return ct_validate_range(LEFT_NODE(root), NULL, key) && ct_validate_range(RIGHT_NODE(root), key, NULL);
}
Ejemplo n.º 16
0
extern node_t *
ct_node_at(node_t *root, int index)
{
	node_t *node = root;
	int counter = 0;
	int go_down = 1;
	node_stack_t *stack;

	if (index < 0) return NULL;

	stack = stack_init(32);

	for(;;) {
		if ((LEFT_NODE(node) != NULL) && go_down) {
			stack_push(stack, node);
			node = LEFT_NODE(node);
		}
		else {
			if (counter == index) {
				
				stack_delete(stack);
				return node;
			}
			counter++;
			if (RIGHT_NODE(node) != NULL) {
				node = RIGHT_NODE(node);
				go_down = 1;
			}
			else {
				if (stack_is_empty(stack)) { 
					stack_delete(stack);
					return NULL;
                }
				node = stack_pop(stack);
				go_down = 0;
			}
		}
    }
}
Ejemplo n.º 17
0
static node_t *
ct_new_node(PyObject *key, PyObject *value, int xdata)
{
	node_t *new_node = PyMem_Malloc(sizeof(node_t));
	if (new_node != NULL) {
		KEY(new_node) = key;
		Py_INCREF(key);
		VALUE(new_node) = value;
		Py_INCREF(value);
		LEFT_NODE(new_node) = NULL;
		RIGHT_NODE(new_node) = NULL;
		XDATA(new_node) = xdata;
	}
	return new_node;
}
Ejemplo n.º 18
0
void
ct_bintree_remove(node_t **rootaddr, node_t *node)
{
	node_t **pnode = NULL; 
	node_t *tmp;

	if (*rootaddr == node) {
		// the node is the root
		pnode = rootaddr;
	} else {
		node_t *parent = PARENT_NODE(node); 
		if (LEFT_NODE(parent) == node) {
			pnode = &LEFT_NODE(parent); 
		} else {
			pnode = &RIGHT_NODE(parent); 
		}
	}

	if (LEFT_NODE(node) == NULL) {
		// replace the root with the right sub-tree
		tmp = *pnode = RIGHT_NODE(node);
		if (tmp != NULL) {
			PARENT_NODE(tmp) = PARENT_NODE(node);
		}
		ct_delete_node(node);
	} else if (RIGHT_NODE(node) == NULL) {
		// replace the node with the left sub-tree
		tmp = *pnode = LEFT_NODE(node);
		PARENT_NODE(tmp) = PARENT_NODE(node);
		ct_delete_node(node);
	} else {
		// both left and right sub-tree is non-null, replace by smallest key in right sub-tree
		node_t **pleftmost = &RIGHT_NODE(node);
		node_t *leftmost = RIGHT_NODE(node); // assert leftmost != NULL
		while ((tmp = LEFT_NODE(leftmost)) != NULL) {
			pleftmost = &LEFT_NODE(leftmost);
			leftmost = tmp;
		}
		// found the leftmost node, copy its data to the root, then remove the left most node
		ct_swap_data(node, leftmost);

		tmp = *pleftmost = RIGHT_NODE(leftmost);
		if (tmp != NULL) {
			PARENT_NODE(tmp) = PARENT_NODE(leftmost);
		}
		ct_delete_node(leftmost);
	}
}
Ejemplo n.º 19
0
extern int
rb_insert(node_t **rootaddr, PyObject *key, PyObject *value)
{
    int new_node = 0;
	node_t *root = *rootaddr;

	if (root == NULL) {
		// case 1, root == NULL
		root = rb_new_node(NULL, key, value);
		new_node = 1;
		if (root == NULL)
			return -1; // got no memory
	}
	else {
		node_t head; /* False tree root */
		node_t *g, *t; /* Grandparent & parent */
		node_t *p, *q; /* Iterator & parent */
		int dir = 0;
		int last = 0;

		/* Set up our helpers */
		t = &head;
		g = NULL;
		p = NULL;
		RIGHT_NODE(t) = root;
		LEFT_NODE(t) = NULL;
		q = RIGHT_NODE(t);

		/* Search down the tree for a place to insert */
		for (;;) {
			int cmp_res;
			if (q == NULL) {
				/* Insert a new node at the first null link */
				q = rb_new_node(p, key, value);
				new_node = 1;
				p->link[dir] = q;
				if (q == NULL)
					return -1; // get no memory
			}
			else if (is_red(q->link[0]) && is_red(q->link[1])) {
				/* Simple red violation: color flip */
				RED(q) = 1;
				RED(q->link[0]) = 0;
				RED(q->link[1]) = 0;
			}

			if (is_red(q) && is_red(p)) {
				/* Hard red violation: rotations necessary */
				int dir2 = (t->link[1] == g);

				if (q == p->link[last]) {
					node_t * tmp = t->link[dir2] = rb_single(g, !last);
					PARENT_NODE(tmp) = t; 
				} else {
					node_t *tmp = t->link[dir2] = rb_double(g, !last);
					PARENT_NODE(tmp) = t; 
				}
			}

			/*  Stop working if we inserted a new node. */
			if (new_node)
				break;

			cmp_res = ct_compare(KEY(q), key);
			if (cmp_res == 0) {       /* if key exists            */
				// Py_XDECREF(VALUE(q)); /* release old value object */
				// VALUE(q) = value;      set new value object     
				// Py_INCREF(value);     /* take new value object    */
				break;
			}
			last = dir;
			dir = (cmp_res < 0);

			/* Move the helpers down */
			if (g != NULL)
				t = g;

			g = p;
			p = q;
			q = q->link[dir];
		}
		/* Update the root (it may be different) */
		root = head.link[1];
	}

	/* Make the root black for simplified logic */
	RED(root) = 0;
	(*rootaddr) = root;
	PARENT_NODE(root) = NULL; 
	return new_node;
}
Ejemplo n.º 20
0
extern int
rb_insert(node_t **rootaddr, PyObject *key, PyObject *value)
{
	node_t *root = *rootaddr;

	if (root == NULL) {
		root = rb_new_node(key, value);
		if (root == NULL)
			return -1; 
	}
	else {
		node_t head; 
		node_t *g, *t; 
		node_t *p, *q; 
		int dir = 0;
		int last = 0;
		int new_node = 0;

		
		t = &head;
		g = NULL;
		p = NULL;
		RIGHT_NODE(t) = root;
		LEFT_NODE(t) = NULL;
		q = RIGHT_NODE(t);

		
		for (;;) {
			int cmp_res;
			if (q == NULL) {
				
				q = rb_new_node(key, value);
				p->link[dir] = q;
				new_node = 1;
				if (q == NULL)
					return -1; 
			}
			else if (is_red(q->link[0]) && is_red(q->link[1])) {
				
				RED(q) = 1;
				RED(q->link[0]) = 0;
				RED(q->link[1]) = 0;
			}

			if (is_red(q) && is_red(p)) {
				
				int dir2 = (t->link[1] == g);

				if (q == p->link[last])
					t->link[dir2] = rb_single(g, !last);
				else
					t->link[dir2] = rb_double(g, !last);
			}

			
			if (new_node)
				break;

			cmp_res = ct_compare(KEY(q), key);
			if (cmp_res == 0) {       
				Py_XDECREF(VALUE(q)); 
				VALUE(q) = value;     
				Py_INCREF(value);     
				return 0;
			}
			last = dir;
			dir = (cmp_res < 0);

			
			if (g != NULL)
				t = g;

			g = p;
			p = q;
			q = q->link[dir];
		}
		
		root = head.link[1];
	}

	
	RED(root) = 0;
	(*rootaddr) = root;
	return 1;
}