コード例 #1
0
ファイル: tree_vrbtree.c プロジェクト: oscarlab/versioning
static int
rbtree_check(node_t *node, node_t *parent, int parent_color,
             vtree_pthread_data_t *vtree_data)
{
	int ln, rn;
	int color;
	vtree_slot_t *slot;

	if (node == NULL)
		return 0;
	slot = read_slot(node, vtree_data);
	assert(parent == get_node_parent(slot->parent));
	color = get_node_color(slot->parent);
	assert(color == RB_BLACK || parent_color == RB_BLACK);

	assert(slot->child[0] == NULL || slot->child[0]->value < node->value);
	assert(slot->child[1] == NULL || slot->child[1]->value > node->value);
	ln = rbtree_check(slot->child[0], node, color, vtree_data);
	rn = rbtree_check(slot->child[1], node, color, vtree_data);
	assert(ln == rn);
	if (color == RB_BLACK)
		return 1 + ln;
	return ln;
}
コード例 #2
0
 // Print the node color.
 void idaapi cfunc_graph_t::print_node_attributes(FILE *fp, int n)
 {
   bgcolor_t c = get_node_color(n);
   if ( c != DEFCOLOR )
     qfprintf(fp, " color: %s", get_color_name(c));
 }
コード例 #3
0
ファイル: tree_vrbtree.c プロジェクト: oscarlab/versioning
void *list_global_init(int init_size, int value_range)
{
	vtree_tree_t *tree;
	node_t *prev, *cur, *node, *gprev, *prev_sib;
	vtree_slot_t *slot, *prev_slot, *gprev_slot, *prev_sib_slot;
	vtree_record_t *rec;
	int i, key, val, direction, prev_direction;

	rec = (vtree_record_t *)malloc(sizeof(vtree_record_t));
	if (rec == NULL)
		return NULL;
	rec->epoch = STARTING_EPOCH;
	rec->rec_next = NULL;
	rec->count = 0;
	g_committed_rec = rec;

	tree = (vtree_tree_t *)malloc(sizeof(vtree_tree_t));
	if (tree == NULL)
		return NULL;
	tree->root = vtree_new_node(INT_MAX);
	if (tree->root == NULL)
		return NULL;

	i = 0;
	while (i < init_size) {
		key = rand() % value_range;

		prev = tree->root;
		cur = prev->slots->child[0];
		direction = 0;
		while (cur != NULL) {
			prev = cur;
			val = cur->value;
			if (val > key) {
				direction = 0;
				cur = cur->slots->child[0];
			} else if (val < key) {
				direction = 1;
				cur = cur->slots->child[1];
			} else
				break;
		}
		if (cur != NULL)
			continue;
		node = vtree_new_node(key);
		if (node == NULL)
			return NULL;
		prev->slots->child[direction] = node;
		if (prev == tree->root) {
			node->slots->parent = set_node_black(NULL);
			goto cont;
		}
		slot = node->slots;
		slot->parent = set_node_red(prev);
loop:
		if (prev == NULL) {
			slot->parent = set_node_black(slot->parent);
			goto cont;
		}
		prev_slot = prev->slots;
		if (get_node_color(prev_slot->parent) == RB_BLACK)
			goto cont;

		gprev = get_node_parent(prev_slot->parent);
		gprev_slot = gprev->slots;
		prev_direction = (gprev_slot->child[1] == prev);
		prev_sib = gprev_slot->child[!prev_direction];
		if (prev_sib) {
			prev_sib_slot = prev_sib->slots;
			if (get_node_color(prev_sib_slot->parent) == RB_RED) {
				prev_slot->parent = set_node_black(prev_slot->parent);
				prev_sib_slot->parent = set_node_black(prev_sib_slot->parent);
				prev = get_node_parent(gprev_slot->parent);
				gprev_slot->parent = set_node_red(prev);
				node = gprev;
				slot = gprev_slot;
				if (prev) {
					prev_slot = prev->slots;
					direction = (prev_slot->child[1] == node);
				}
				goto loop;
			}
		}
		if (prev_direction == 0) {
			if (direction == 1) {
				rot_left_init(tree->root, prev, prev_slot);
				gprev_slot = gprev->slots;
				prev = node;
				prev_slot = prev->slots;
			}
			rot_right_init(tree->root, gprev, gprev_slot);
			gprev_slot = gprev->slots;
			gprev_slot->parent = set_node_red(gprev_slot->parent);
			prev_slot->parent = set_node_black(prev_slot->parent);
		} else {
			if (direction == 0) {
				rot_right_init(tree->root, prev, prev_slot);
				gprev_slot = gprev->slots;
				prev = node;
				prev_slot = prev->slots;
			}
			rot_left_init(tree->root, gprev, gprev_slot);
			gprev_slot = gprev->slots;
			gprev_slot->parent = set_node_red(gprev_slot->parent);
			prev_slot->parent = set_node_black(prev_slot->parent);
		}
cont:
		i++;
	}

	qsbr_init();

	return tree;
}
コード例 #4
0
ファイル: tree_vrbtree.c プロジェクト: oscarlab/versioning
int list_del(int key, pthread_data_t *data)
{
	vtree_tree_t *tree = (vtree_tree_t *)data->list;
	vtree_pthread_data_t *vtree_data = (vtree_pthread_data_t *)data->ds_data;
	node_t *prev, *node, *succ, *succ_prev, *succ_right, *node_child, *rebalance_node;
	vtree_slot_t *slot, *prev_slot, *succ_slot, *succ_prev_slot, *node_child_slot, *rebalance_slot, *tmp_slot;
	int direction, rebalance_direction, ret, val;

	vtree_write_cs_enter(vtree_data);
	do {
		data->nr_txn++;
		prev = tree->root;
		slot = read_slot(prev, vtree_data);
		node = slot->child[0];
		rbtree_check(node, NULL, RB_RED, vtree_data);
		direction = 0;
		while (node != NULL) {
			val = node->value;
			if (val > key) {
				slot = read_slot(node, vtree_data);
				direction = 0;
				prev = node;
				node = slot->child[0];
			} else if (val < key) {
				slot = read_slot(node, vtree_data);
				direction = 1;
				prev = node;
				node = slot->child[1];
			} else
				break;
		}

		ret = (node != NULL);
		if (!ret)
			goto out;

		prev_slot = slot;
		slot = read_slot(node, vtree_data);
		rebalance_node = NULL;
		if (slot->child[0] == NULL) {
			if ((succ = slot->child[1]) != NULL) {
				// only right, right is red and node is black, no rebalance required
				rebalance_node = NULL;
				succ_slot = read_slot(succ, vtree_data);
				add_slot(succ, succ_slot->child[0], succ_slot->child[1],
				         slot->parent, vtree_data);
			} else {
				if (get_node_color(slot->parent) == RB_BLACK && prev != tree->root)
					rebalance_node = prev;
				else
					rebalance_node = NULL;
			}
		} else {
			if ((succ = slot->child[1]) != NULL) {
				// both left and right
				succ_prev = NULL;
				succ_prev_slot = NULL;
				succ_slot = read_slot(succ, vtree_data);
				node_child = succ;
				node_child_slot = succ_slot;
				while (succ_slot->child[0]) {
					succ_prev = succ;
					succ_prev_slot = succ_slot;
					succ = succ_slot->child[0];
					succ_slot = read_slot(succ, vtree_data);
				}
				if (succ_prev) {
					// move succ to node
					add_slot(succ, slot->child[0], slot->child[1], slot->parent, vtree_data);
					succ_right = succ_slot->child[1];
					// succ has no left child, if succ is red, no rebalance is required
					if (get_node_color(succ_slot->parent) == RB_BLACK) {
						rebalance_node = succ_prev;
						rebalance_direction = 0;
					}
					if (succ_prev != node_child) {
						add_slot(node_child,
						         node_child_slot->child[0],
						         node_child_slot->child[1],
						         change_node_parent(node_child_slot->parent, succ),
						         vtree_data);
						rebalance_slot = add_slot(succ_prev,
						                          succ_right,
						                          succ_prev_slot->child[1],
						                          succ_prev_slot->parent,
						                          vtree_data);
					} else {
						rebalance_slot = add_slot(succ_prev,
						                          succ_right,
						                          succ_prev_slot->child[1],
						                          change_node_parent(succ_prev_slot->parent,
						                                             succ),
						                          vtree_data);
					}
					if (succ_right != NULL) {
						// if succ has right, it must be a red node with no child
						add_slot(succ_right, NULL, NULL, set_node_red(succ_prev), vtree_data);
					}
				} else {
					// succ is right child of node
					if (get_node_color(succ_slot->parent) == RB_BLACK) {
						rebalance_node = succ;
						rebalance_direction = 1;
					}
					rebalance_slot = add_slot(succ,
					                          slot->child[0],
					                          succ_slot->child[1],
					                          slot->parent,
					                          vtree_data);
				}
				node_child = slot->child[0];
				node_child_slot = read_slot(node_child, vtree_data);
				add_slot(node_child,
				         node_child_slot->child[0],
				         node_child_slot->child[1],
			                 change_node_parent(node_child_slot->parent, succ),
				         vtree_data);
			} else {
				// only left, left is red and node is black, no rebalance required
				succ = slot->child[0];
				rebalance_node = NULL;
				succ_slot = read_slot(succ, vtree_data);
				add_slot(succ, succ_slot->child[0], succ_slot->child[1],
				         slot->parent, vtree_data);
			}
		}

		if (prev == tree->root) {
			add_slot(tree->root, succ, NULL, NULL, vtree_data);
		} else {
			if (direction == 0) {
				tmp_slot = add_slot(prev, succ, prev_slot->child[1],
				                    prev_slot->parent,
				                    vtree_data);
			} else {
				tmp_slot = add_slot(prev, prev_slot->child[0], succ,
				                    prev_slot->parent,
				                    vtree_data);
			}
			if (rebalance_node == prev) {
				rebalance_slot = tmp_slot;
				rebalance_direction = direction;
			}
		}
		add_slot(node, node, node, node, vtree_data);

		if (rebalance_node)
			vtree_rebalance(tree->root, rebalance_node, rebalance_slot, rebalance_direction,
			                vtree_data);
out:
		;
	} while (vtree_write_cs_exit(vtree_data));

	if (ret == 1)
		vtree_free_node_later(node, vtree_data);

	vtree_maybe_quiescent(vtree_data);

	return ret;
}
コード例 #5
0
ファイル: tree_vrbtree.c プロジェクト: oscarlab/versioning
static void
vtree_rebalance(node_t *root, node_t *prev, vtree_slot_t *prev_slot, int direction, vtree_pthread_data_t *vtree_data)
{
	node_t *node, *sib_node, *tmp1_node, *tmp2_node;
	vtree_slot_t *sib_slot, *tmp1_slot, *tmp2_slot;

	node = NULL;
loop:
	/*
	 * loop invariants:
	 * - node is black (or NULL on 1st iteration)
	 * - node is not roiot (parent is not NULL)
	 * -ALL leaf paths going through parent and node have
	 * black node count is 1 lower than other leaf path
	 */
	sib_node = prev_slot->child[!direction];
	if ((sib_slot = get_slot_from_rec_new(sib_node, vtree_data)) == NULL)
		sib_slot = read_slot(sib_node, vtree_data);
	if (get_node_color(sib_slot->parent) == RB_RED) {
		if (direction == 0) {
			tmp1_node = sib_slot->child[0];
			rot_left(root, prev, prev_slot, vtree_data);
		} else {
			tmp1_node = sib_slot->child[1];
			rot_right(root, prev, prev_slot, vtree_data);
		}
		tmp1_slot = get_slot_from_rec_new(tmp1_node, vtree_data);
		prev_slot->parent = set_node_red(prev_slot->parent);
		sib_slot = get_slot_from_rec_new(sib_node, vtree_data);
		sib_slot->parent = set_node_black(sib_slot->parent);
		sib_node = tmp1_node;
		sib_slot = tmp1_slot;
	}
	// now node and sib are both black
	tmp1_node = sib_slot->child[!direction];
	if (tmp1_node != NULL)
		if ((tmp1_slot = get_slot_from_rec_new(tmp1_node, vtree_data)) == NULL)
			tmp1_slot = read_slot(tmp1_node, vtree_data);
	if (tmp1_node == NULL || get_node_color(tmp1_slot->parent) == RB_BLACK) {
		tmp2_node = sib_slot->child[direction];
		if (tmp2_node != NULL)
			if ((tmp2_slot = get_slot_from_rec_new(tmp2_node, vtree_data)) == NULL)
				tmp2_slot = read_slot(tmp2_node, vtree_data);
		if (tmp2_node == NULL || get_node_color(tmp2_slot->parent) == RB_BLACK) {
			// sibling color flip to red
			// this violate rbtree variant, flip parent to black if it was red, or recurse
			add_or_change_slot(sib_node, sib_slot->child[0], sib_slot->child[1],
			                   set_node_red(sib_slot->parent), vtree_data);
			if (get_node_color(prev_slot->parent) == RB_RED)
				prev_slot->parent = set_node_black(prev_slot->parent);
			else {
				node = prev;
				prev = get_node_parent(prev_slot->parent);
				if (prev) {
					if ((prev_slot = get_slot_from_rec_new(prev, vtree_data)) == NULL) {
						prev_slot = read_slot(prev, vtree_data);
						prev_slot = add_slot(prev,
						                     prev_slot->child[0],
						                     prev_slot->child[1],
						                     prev_slot->parent,
						                     vtree_data);
					}
					direction = (prev_slot->child[1] == node);
					goto loop;
				}
			}
			goto out;
		}
		if (direction == 0) {
			rot_right(root, sib_node, sib_slot, vtree_data);
		} else {
			rot_left(root, sib_node, sib_slot, vtree_data);
		}
		sib_slot = get_slot_from_rec_new(sib_node, vtree_data);
		sib_slot->parent = set_node_red(sib_slot->parent);
		tmp2_slot = get_slot_from_rec_new(tmp2_node, vtree_data);
		tmp2_slot->parent = set_node_black(tmp2_slot->parent);
		tmp1_node = sib_node;
		tmp1_slot = sib_slot;
		sib_node = tmp2_node;
	}
	if (direction == 0) {
		rot_left(root, prev, prev_slot, vtree_data);
	} else {
		rot_right(root, prev, prev_slot, vtree_data);
	}
	sib_slot = get_slot_from_rec_new(sib_node, vtree_data);
	sib_slot->parent = change_node_parent(prev_slot->parent, get_node_parent(sib_slot->parent));
	prev_slot->parent = set_node_black(prev_slot->parent);
	add_or_change_slot(tmp1_node, tmp1_slot->child[0], tmp1_slot->child[1],
	                   set_node_black(tmp1_slot->parent), vtree_data);
out:
	return;
}
コード例 #6
0
ファイル: tree_vrbtree.c プロジェクト: oscarlab/versioning
int list_ins(int key, pthread_data_t *data)
{
	vtree_tree_t *tree = (vtree_tree_t *)data->list;
	vtree_pthread_data_t *vtree_data = (vtree_pthread_data_t *)data->ds_data;
	node_t *prev, *cur, *node, *new_node, *gprev, *prev_sib;
	vtree_slot_t *slot, *prev_slot, *gprev_slot, *prev_sib_slot;
	int prev_direction, direction, ret, val;

	new_node = vtree_new_node(key);
	assert(new_node != NULL);

	vtree_write_cs_enter(vtree_data);
	do {
		data->nr_txn++;
		prev = tree->root;
		prev_slot = read_slot(prev, vtree_data);
		cur = prev_slot->child[0];
		rbtree_check(cur, NULL, RB_RED, vtree_data);
		direction = 0;
		while (cur != NULL) {
			val = cur->value;
			if (val > key) {
				prev_slot = read_slot(cur, vtree_data);
				direction = 0;
				prev = cur;
				cur = prev_slot->child[0];
			} else if (val < key) {
				prev_slot = read_slot(cur, vtree_data);
				direction = 1;
				prev = cur;
				cur = prev_slot->child[1];
			} else
				break;
		}
		ret = (cur == NULL);
		if (!ret)
			goto out;
		node = new_node;
		if (direction == 0)
			prev_slot = add_slot(prev, node, prev_slot->child[1],
			                     prev_slot->parent, vtree_data);
		else
			prev_slot = add_slot(prev, prev_slot->child[0], node,
			                     prev_slot->parent, vtree_data);
		if (prev == tree->root) {
			slot = add_slot(node, NULL, NULL, set_node_black(NULL), vtree_data);
			goto out;
		}
		// newly inserted node is red to maintain invariant
		slot = add_slot(node, NULL, NULL, set_node_red(prev), vtree_data);
loop:
		if (prev == NULL) {
			// we can always set root to black
			slot->parent = set_node_black(slot->parent);
			goto out;
		}
		if (get_node_color(prev_slot->parent) == RB_BLACK) {
			// parent is black, no invariant violated
			goto out;
		}

		// now both node and parent are red, check grandparent,
		// since parent is red, there must be grandparent and it is black
		gprev = get_node_parent(prev_slot->parent);
		gprev_slot = read_slot(gprev, vtree_data);
		prev_direction = (gprev_slot->child[1] == prev);
		prev_sib = gprev_slot->child[!prev_direction];
		if (prev_sib) {
			prev_sib_slot = read_slot(prev_sib, vtree_data);
			if (get_node_color(prev_sib_slot->parent) == RB_RED) {
				// if sib is red, change parent and sib to black
				// and move upwards
				prev_slot->parent = set_node_black(prev_slot->parent);
				add_slot(prev_sib,
				         prev_sib_slot->child[0],
				         prev_sib_slot->child[1],
				         set_node_black(prev_sib_slot->parent),
				         vtree_data);
				prev = get_node_parent(gprev_slot->parent);
				slot = add_slot(gprev,
				                gprev_slot->child[0],
				                gprev_slot->child[1],
				                set_node_red(prev),
				                vtree_data);
				node = gprev;
				if (prev) {
					prev_slot = read_slot(prev, vtree_data);
					direction = (prev_slot->child[1] == node);
					prev_slot = add_slot(prev,
					                     prev_slot->child[0],
					                     prev_slot->child[1],
					                     prev_slot->parent,
					                     vtree_data);
				}
				goto loop;
			}
		}
		// now, either there is no sib of parent or it is black
		if (prev_direction == 0) {
			if (direction == 1) {
				rot_left(tree->root, prev, prev_slot, vtree_data);
				gprev_slot = get_slot_from_rec_new(gprev, vtree_data);
				prev = node;
				prev_slot = get_slot_from_rec_new(node, vtree_data);
			}
			rot_right(tree->root, gprev, gprev_slot, vtree_data);
			gprev_slot = get_slot_from_rec_new(gprev, vtree_data);
			gprev_slot->parent = set_node_red(gprev_slot->parent);
			prev_slot->parent = set_node_black(prev_slot->parent);
		} else {
			if (direction == 0) {
				rot_right(tree->root, prev, prev_slot, vtree_data);
				gprev_slot = get_slot_from_rec_new(gprev, vtree_data);
				prev = node;
				prev_slot = get_slot_from_rec_new(node, vtree_data);
			}
			rot_left(tree->root, gprev, gprev_slot, vtree_data);
			gprev_slot = get_slot_from_rec_new(gprev, vtree_data);
			gprev_slot->parent = set_node_red(gprev_slot->parent);
			prev_slot->parent = set_node_black(prev_slot->parent);
		}
out:
		;
	} while (vtree_write_cs_exit(vtree_data));

	if (ret == 0)
		vtree_free_node_later(new_node, vtree_data);

	vtree_maybe_quiescent(vtree_data);

	return ret;
}
コード例 #7
0
ファイル: ConstraintGraph.cpp プロジェクト: iveney/drouting
COLOR ConstraintGraph::get_node_color(NType type,int idx){
	GNode nd(type,idx);
	return get_node_color(nd);
}