Exemplo n.º 1
0
/*
 * Check whether @node is possible vroot of @object.
 */
static void handle_vroot(struct inode *object, znode * node)
{
	file_plugin *fplug;
	coord_t coord;

	fplug = inode_file_plugin(object);
	assert("nikita-3353", fplug != NULL);
	assert("nikita-3354", fplug->owns_item != NULL);

	if (unlikely(node_is_empty(node)))
		return;

	coord_init_first_unit(&coord, node);
	/*
	 * if leftmost item of @node belongs to @object, we cannot be sure
	 * that @node is vroot of @object, because, some items of @object are
	 * probably in the sub-tree rooted at the left neighbor of @node.
	 */
	if (fplug->owns_item(object, &coord))
		return;
	coord_init_last_unit(&coord, node);
	/* mutatis mutandis for the rightmost item */
	if (fplug->owns_item(object, &coord))
		return;
	/* otherwise, @node is possible vroot of @object */
	inode_set_vroot(object, node);
}
Exemplo n.º 2
0
void
test_nodestore ()
{
	gint i;
	NodeStore *store;
	Part *part;
	Wire *wire;
	Node *node;

	Coords p_pos = {111.,22.};
	Coords n_pos = {111.,33.};
	Coords w_pos = {111.,7.};
	Coords w_len = {0.,88.};

	store = node_store_new ();
	part = part_new ();
	wire = wire_new ();

	// add one Pin with a offset that is on the wire when rotation N*Pi times
	Pin *pin = g_new (Pin, 1);
	pin->offset.x = n_pos.x - p_pos.x;
	pin->offset.y = n_pos.y - p_pos.y;
	GSList *list = NULL;
	list = g_slist_prepend (list, pin);
	part_set_pins (part, list);
	g_slist_free (list);

	item_data_set_pos (ITEM_DATA (part), &p_pos);

	item_data_set_pos (ITEM_DATA (wire), &w_pos);
	wire_set_length (wire, &w_len);

	node_store_add_part (store, part);
	node_store_add_wire (store, wire);

	{
		for (i=0; i<11; i++)
			item_data_rotate (ITEM_DATA (part), 90, NULL);
		item_data_set_pos (ITEM_DATA (part), &w_len);
		for (i=0; i<4; i++)
			item_data_rotate (ITEM_DATA (part), 90, NULL);
		item_data_set_pos (ITEM_DATA (part), &n_pos);
		for (i=0; i<7; i++)
			item_data_rotate (ITEM_DATA (part), -90, NULL);
		item_data_set_pos (ITEM_DATA (part), &p_pos);
	}
	g_assert (node_store_is_wire_at_pos (store, n_pos));
	g_assert (node_store_is_pin_at_pos (store, n_pos));

	node = node_store_get_node (store, n_pos);
	g_assert (!node_is_empty (node));
	g_assert (node_needs_dot (node));

	node_store_remove_part (store, part);
	node_store_remove_wire (store, wire);

	g_object_unref (store);
}
Exemplo n.º 3
0
static unsigned
_bdd_mgr_get_free_index (bdd_mgr_t *mgr)
{
    unsigned mask = mgr->capacity - 1;
    unsigned i = (mgr->last_used_alloc_idx + 1) & mask;
    assert (mgr->num_nodes < mgr->capacity - 1);
    while (!node_is_empty (mgr->nodes[i]))
        i = (i + 1) & mask;
    mgr->last_used_alloc_idx = i;
    return i;
}
Exemplo n.º 4
0
int
node_store_remove_part (NodeStore *self, Part *part)
{
	Node *node;
	SheetPos lookup_key;
	SheetPos pos;
	gdouble x, y;
	int i, num_pins;
	Pin *pins;

	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (self), FALSE);
	g_return_val_if_fail (part != NULL, FALSE);
	g_return_val_if_fail (IS_PART (part), FALSE);

	self->parts = g_list_remove (self->parts, part);
	self->items = g_list_remove (self->items, part);

	num_pins = part_get_num_pins (part);
	item_data_get_pos (ITEM_DATA (part), &pos);

	pins = part_get_pins (part);
	for (i = 0; i < num_pins; i++) {
		x = pos.x + pins[i].offset.x;
		y = pos.y + pins[i].offset.y;

		// Use the position of the pin as lookup key.
		lookup_key.x = x;
		lookup_key.y = y;

		node = g_hash_table_lookup (self->nodes, &lookup_key);
		if (node) {
			if (!node_remove_pin (node, &pins[i])) {
				g_warning ("Couldn't remove pin.");
				return FALSE;
			}

			// If the node is empty after removing the pin,
			// remove the node as well.
			if (node_is_empty (node)) {
				g_hash_table_remove (self->nodes, &lookup_key);
				g_object_unref (G_OBJECT (node));
			}
		} 
		else {
			return FALSE;
		}
	}

	return TRUE;
}
Exemplo n.º 5
0
int
node_store_remove_wire (NodeStore *store, Wire *wire)
{
	GSList *list;
	SheetPos lookup_key, pos, length;

	g_return_val_if_fail (store != NULL, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (store), FALSE);
	g_return_val_if_fail (wire != NULL, FALSE);
	g_return_val_if_fail (IS_WIRE (wire), FALSE);

	if (item_data_get_store (ITEM_DATA (wire)) == NULL) {
		g_warning ("Trying to remove non-stored wire.");
		return FALSE;
	}

	wire_get_pos_and_length (wire, &pos, &length);

	store->wires = g_list_remove (store->wires, wire);
	store->items = g_list_remove (store->items, wire);

	// If the nodes that this wire passes through will be
	// empty when the wire is removed, remove the node as well.

	// We must work on a copy of the nodes list, since it
	// changes as we remove nodes.
	list = g_slist_copy (wire_get_nodes (wire));

	for (; list; list = list->next) {
		Node *node = list->data;

		lookup_key = node->key;

		node_remove_wire (node, wire);

		wire_remove_node (wire, node);

		if (node_is_empty (node))
			g_hash_table_remove (store->nodes, &lookup_key);
	}

	g_slist_free (list);

	return TRUE;
}
Exemplo n.º 6
0
/**
 * remove/unregister a part from the nodestore
 * this does _not_ free the part!
 */
gboolean node_store_remove_part (NodeStore *self, Part *part)
{
	Node *node;
	Coords pin_pos;
	Coords part_pos;
	int i, num_pins;
	Pin *pins;

	g_return_val_if_fail (self, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (self), FALSE);
	g_return_val_if_fail (part, FALSE);
	g_return_val_if_fail (IS_PART (part), FALSE);

	self->parts = g_list_remove (self->parts, part);
	self->items = g_list_remove (self->items, part);

	num_pins = part_get_num_pins (part);
	item_data_get_pos (ITEM_DATA (part), &part_pos);

	pins = part_get_pins (part);
	for (i = 0; i < num_pins; i++) {
		pin_pos.x = part_pos.x + pins[i].offset.x;
		pin_pos.y = part_pos.y + pins[i].offset.y;

		node = g_hash_table_lookup (self->nodes, &pin_pos);
		if (node) {
			if (!node_remove_pin (node, &pins[i])) {
				g_warning ("Could not remove pin[%i] from node %p.", i, node);
				return FALSE;
			}

			// If the node is empty after removing the pin,
			// remove the node as well.
			if (node_is_empty (node)) {
				g_hash_table_remove (self->nodes, &pin_pos);
				g_object_unref (G_OBJECT (node));
			}
		} else {
			return FALSE;
		}
	}

	return TRUE;
}
Exemplo n.º 7
0
/**
 * removes/unregisters a wire from the nodestore
 * this does _not_ free the wire itself!
 */
gboolean node_store_remove_wire (NodeStore *store, Wire *wire)
{
	GSList *copy, *iter;
	Coords lookup_key;

	g_return_val_if_fail (store, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (store), FALSE);
	g_return_val_if_fail (wire, FALSE);
	g_return_val_if_fail (IS_WIRE (wire), FALSE);

	if (item_data_get_store (ITEM_DATA (wire)) == NULL) {
		g_warning ("Trying to remove not-stored wire %p.", wire);
		return FALSE;
	}

	store->wires = g_list_remove (store->wires, wire);
	store->items = g_list_remove (store->items, wire);

	// If the nodes that this wire passes through will be
	// empty when the wire is removed, remove the node as well.

	// FIXME if done properly, a list copy is _not_ necessary
	copy = g_slist_copy (wire_get_nodes (wire));
	for (iter = copy; iter; iter = iter->next) {
		Node *node = iter->data;

		lookup_key = node->key;

		node_remove_wire (node, wire);
		wire_remove_node (wire, node);

		if (node_is_empty (node))
			g_hash_table_remove (store->nodes, &lookup_key);
	}

	g_slist_free (copy);

	return TRUE;
}
Exemplo n.º 8
0
/* main function that handles common parts of tree traversal: starting
    (fake znode handling), restarts, error handling, completion */
static lookup_result traverse_tree(cbk_handle * h/* search handle */)
{
	int done;
	int iterations;
	int vroot_used;

	assert("nikita-365", h != NULL);
	assert("nikita-366", h->tree != NULL);
	assert("nikita-367", h->key != NULL);
	assert("nikita-368", h->coord != NULL);
	assert("nikita-369", (h->bias == FIND_EXACT)
	       || (h->bias == FIND_MAX_NOT_MORE_THAN));
	assert("nikita-370", h->stop_level >= LEAF_LEVEL);
	assert("nikita-2949", !(h->flags & CBK_DKSET));
	assert("zam-355", lock_stack_isclean(get_current_lock_stack()));

	done = 0;
	iterations = 0;
	vroot_used = 0;

	/* loop for restarts */
restart:

	assert("nikita-3024", reiser4_schedulable());

	h->result = CBK_COORD_FOUND;
	/* connect_znode() needs it */
	h->ld_key = *reiser4_min_key();
	h->rd_key = *reiser4_max_key();
	h->flags |= CBK_DKSET;
	h->error = NULL;

	if (!vroot_used && h->object != NULL) {
		vroot_used = 1;
		done = prepare_object_lookup(h);
		if (done == LOOKUP_REST)
			goto restart;
		else if (done == LOOKUP_DONE)
			return h->result;
	}
	if (h->parent_lh->node == NULL) {
		done =
		    get_uber_znode(h->tree, ZNODE_READ_LOCK, ZNODE_LOCK_LOPRI,
				   h->parent_lh);

		assert("nikita-1637", done != -E_DEADLOCK);

		h->block = h->tree->root_block;
		h->level = h->tree->height;
		h->coord->node = h->parent_lh->node;

		if (done != 0)
			return done;
	}

	/* loop descending a tree */
	while (!done) {

		if (unlikely((iterations > REISER4_CBK_ITERATIONS_LIMIT) &&
			     IS_POW(iterations))) {
			warning("nikita-1481", "Too many iterations: %i",
				iterations);
			reiser4_print_key("key", h->key);
			++iterations;
		} else if (unlikely(iterations > REISER4_MAX_CBK_ITERATIONS)) {
			h->error =
			    "reiser-2018: Too many iterations. Tree corrupted, or (less likely) starvation occurring.";
			h->result = RETERR(-EIO);
			break;
		}
		switch (cbk_level_lookup(h)) {
		case LOOKUP_CONT:
			move_lh(h->parent_lh, h->active_lh);
			continue;
		default:
			wrong_return_value("nikita-372", "cbk_level");
		case LOOKUP_DONE:
			done = 1;
			break;
		case LOOKUP_REST:
			hput(h);
			/* deadlock avoidance is normal case. */
			if (h->result != -E_DEADLOCK)
				++iterations;
			reiser4_preempt_point();
			goto restart;
		}
	}
	/* that's all. The rest is error handling */
	if (unlikely(h->error != NULL)) {
		warning("nikita-373", "%s: level: %i, "
			"lock_level: %i, stop_level: %i "
			"lock_mode: %s, bias: %s",
			h->error, h->level, h->lock_level, h->stop_level,
			lock_mode_name(h->lock_mode), bias_name(h->bias));
		reiser4_print_address("block", &h->block);
		reiser4_print_key("key", h->key);
		print_coord_content("coord", h->coord);
	}
	/* `unlikely' error case */
	if (unlikely(IS_CBKERR(h->result))) {
		/* failure. do cleanup */
		hput(h);
	} else {
		assert("nikita-1605", WITH_DATA_RET
		       (h->coord->node, 1,
			ergo((h->result == CBK_COORD_FOUND) &&
			     (h->bias == FIND_EXACT) &&
			     (!node_is_empty(h->coord->node)),
			     coord_is_existing_item(h->coord))));
	}
	return h->result;
}
Exemplo n.º 9
0
/* Execute actor for each item (or unit, depending on @through_units_p),
   starting from @coord, right-ward, until either:

   - end of the tree is reached
   - unformatted node is met
   - error occurred
   - @actor returns 0 or less

   Error code, or last actor return value is returned.

   This is used by plugin/dir/hashe_dir.c:reiser4_find_entry() to move through
   sequence of entries with identical keys and alikes.
*/
int reiser4_iterate_tree(reiser4_tree * tree /* tree to scan */ ,
			 coord_t *coord /* coord to start from */ ,
			 lock_handle * lh /* lock handle to start with and to
					   * update along the way */ ,
			 tree_iterate_actor_t actor /* function to call on each
						     * item/unit */ ,
			 void *arg /* argument to pass to @actor */ ,
			 znode_lock_mode mode /* lock mode on scanned nodes */ ,
			 int through_units_p /* call @actor on each item or on
					      *	each unit */ )
{
	int result;

	assert("nikita-1143", tree != NULL);
	assert("nikita-1145", coord != NULL);
	assert("nikita-1146", lh != NULL);
	assert("nikita-1147", actor != NULL);

	result = zload(coord->node);
	coord_clear_iplug(coord);
	if (result != 0)
		return result;
	if (!coord_is_existing_unit(coord)) {
		zrelse(coord->node);
		return -ENOENT;
	}
	while ((result = actor(tree, coord, lh, arg)) > 0) {
		/* move further  */
		if ((through_units_p && coord_next_unit(coord)) ||
		    (!through_units_p && coord_next_item(coord))) {
			do {
				lock_handle couple;

				/* move to the next node  */
				init_lh(&couple);
				result =
				    reiser4_get_right_neighbor(&couple,
							       coord->node,
							       (int)mode,
							       GN_CAN_USE_UPPER_LEVELS);
				zrelse(coord->node);
				if (result == 0) {

					result = zload(couple.node);
					if (result != 0) {
						done_lh(&couple);
						return result;
					}

					coord_init_first_unit(coord,
							      couple.node);
					done_lh(lh);
					move_lh(lh, &couple);
				} else
					return result;
			} while (node_is_empty(coord->node));
		}

		assert("nikita-1149", coord_is_existing_unit(coord));
	}
	zrelse(coord->node);
	return result;
}