Exemple #1
0
/**
 * Add new child node after given node
 */
static Node *_build_node(Node *node, unsigned char *string, unsigned short length)
{
	Node *next_node;
	if (length >= 1) {
		Node new_node;

		_node_init(&new_node, (BMapNode){(BMap){NULL, 0}}, NULL);
		_node_array_init(&new_node);

		//TODO: If key length <= sizeof(ptr) don't malloc,
		// Just turn pointer into a union and store the array inline.
		if(length > 1) {
			_node_set_array(&new_node, length-1);
			memcpy(new_node.array, string+1, length-1);
		}
		Result(BMapEntryNodePtr) result = bmap_node_insert(&node->children, string[0], new_node);
		if(TypeOf(result) == Type(Result, Ok)) {
			next_node = &result.data->node;
		}
		trace_node("BUILD-NODE", next_node);
	} else {
		next_node = node;
		trace_node("REUSE-NODE", next_node);
	}
	return next_node;
}
Exemple #2
0
void rtree_remove(RTree *tree, unsigned char *string, unsigned short length)
{
	trace("RTREE-REMOVE(%p)", &tree->root);

	Scan scan;
	_scan_init(&scan, string, length, &tree->root, S_DEFAULT);

	Node * node = _tree_seek(&tree->root, &scan);

	trace_node("ROOT", &tree->root);
	trace_node("NODE", node);
	trace("STATUS %i, %i, %p", scan.index, length, node->data);
	if(scan.found == 1 && node->data) {
		node->data = NULL;
		_pluck_node(node, &scan);
	}
}
PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace() const
{
    std::cerr << std::endl;
    trace_node(m_p_root, 0);
    std::cerr << std::endl;
}
Exemple #4
0
PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace() const
{
  std::cerr << std::endl;
  if (m_p_head->m_p_parent == NULL)
    return;
  trace_node(m_p_head->m_p_parent, 0);
  std::cerr << std::endl;
}
Exemple #5
0
/**
 * create split array node in two using a tree node
 * TODO: Verify tests manage all cases.
 */
static Node * _split_node_array(Node *node, Scan *scan)
{
	unsigned subindex = scan->subindex;

	Node *data_node;
	Node old = *node;

	unsigned char *old_suffix = old.array+subindex;
	unsigned char *new_suffix = scan->key + scan->index;
	unsigned int old_suffix_size = old.size - subindex;
	unsigned int new_suffix_size = scan->size - scan->index;

	if (new_suffix_size == 0) {
                //No new suffix, we add data to current node
		_node_init(node, (BMapNode){(BMap){NULL, 0}}, NULL);

		data_node = node;

                //After the data node we append the old suffix
		Node *branch = _build_node(node, old_suffix, old_suffix_size);
		_node_init(branch, old.children, old.data);
	} else {
		//make node point to new tree node
		_node_init(node, (BMapNode){(BMap){NULL, 0}}, NULL);

		//add branch to hold old suffix and delete old data
		Node *branch1 = _build_node(node, old_suffix, old_suffix_size);
		_node_init(branch1, old.children, old.data);
		trace_node("OLD-BRANCH", branch1);

		//add branch to hold new suffix and return new node
		Node *branch2 = _build_node(node, new_suffix, new_suffix_size);

		data_node = branch2;
	}

	_node_set_array(node, subindex);
	trace_node("PREFIX", node);

	return data_node;
}
Exemple #6
0
/**
 * Remove dangling node and compact tree
 */
static void _pluck_node(Node *node, Scan *scan)
{
	Node *previous = scan->previous;
	trace_node("CLEAN", node);

	if(bmap_node_count(&node->children) == 0 && previous) {
		trace_node("PREVIOUS", previous);

		if(node->array) {
			free(node->array);
			set_null(node->array);
		}

		char bkey = scan->key[scan->index - scan->subindex - 1];
		bmap_node_delete(&previous->children, bkey);

		if(previous != scan->root) {
			_compact_nodes(previous);
		}

	} else {
		_compact_nodes(node);
	}
}
Exemple #7
0
static void _node_dispose(Node *node)
{
	trace_node("DISPOSE", node);
	if(node->array) {
		free(node->array);
		set_null(node->array);
	}
	BMapCursorNode cur;
	bmap_cursor_node_init(&cur, &node->children);
	while(bmap_cursor_node_next(&cur)) {
		BMapEntryNode *entry = bmap_cursor_node_current(&cur);
		_node_dispose(&entry->node);
	}
	bmap_cursor_node_dispose(&cur);
	bmap_node_dispose(&node->children);
}
Exemple #8
0
/**
 * Seek the node for the given key either for setting or getting a value
 * If the key is not found it returns the closest matching node.
 */
static Node *_tree_seek(Node *tree, Scan *scan)
{
	Node *current = tree;

	//Move to the next node within the tree
	BMapEntryNode *entry = bmap_node_get(&current->children, scan->key[scan->index]);
	//Break if there is no node to move to
	if(entry == NULL) {
		scan->found = -1;
		return current;
	}
	current = &entry->node;
	scan->index++;

	trace_node("SEEK-ARRAY", current);
	int j = 0;
	unsigned int i = scan->index;

	for (; j < current->size && i < scan->size; j++, i++) {
		//Break if a character does not match
		trace("[%c-%c]", current->array[j], scan->key[i]);
		if(current->array[j] != scan->key[i]) {
			scan->subindex = j;
			scan->index = i;
			scan->found = -1;
			return current;
		}
	}
	scan->subindex = j;
	scan->index = i;

	//Break if it didn't match the whole array
	if(j < current->size) {
		scan->found = -1;
		return current;
	}

	scan->previous = tree;

	if(scan->index == scan->size) {
		scan->found = 1;
		return current;
	}
	return _tree_seek(current, scan);
}
Exemple #9
0
PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace_node(const_node_pointer p_nd, size_type level)
{
  for (size_type i = 0; i < level; ++i)
    std::cerr << ' ';
  std::cerr << p_nd << " ";
  std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i ");

  trace_node_metadata(p_nd, type_to_type<typename node::metadata_type>());
  typename e_access_traits::const_iterator el_it = pref_begin(p_nd);
  while (el_it != pref_end(p_nd))
    {
      std::cerr <<* el_it;
      ++el_it;
    }

  if (p_nd->m_type == pat_trie_leaf_node_type)
    {
      std::cerr << std::endl;
      return;
    }

  const_internal_node_pointer p_internal =
    static_cast<const_internal_node_pointer>(p_nd);

  std::cerr << " " <<
    static_cast<unsigned long>(p_internal->get_e_ind()) << std::endl;

  const size_type num_children = std::distance(p_internal->begin(),
					       p_internal->end());

  for (size_type child_i = 0; child_i < num_children; ++child_i)
    {
      typename internal_node::const_iterator child_it =
	p_internal->begin();
      std::advance(child_it, num_children - child_i - 1);
      trace_node(*child_it, level + 1);
    }
}
PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace_node(node_const_pointer p_nd, size_type level)
{
    while (p_nd != 0)
    {
        for (size_type i = 0; i < level; ++i)
            std::cerr << ' ';

        std::cerr << p_nd <<
                  " prev = " << p_nd->m_p_prev_or_parent <<
                  " next " << p_nd->m_p_next_sibling <<
                  " left = " << p_nd->m_p_l_child << " ";

        trace_node_metadata(p_nd, type_to_type<node_metadata>());
        std::cerr << p_nd->m_value << std::endl;
        trace_node(p_nd->m_p_l_child, level + 1);
        p_nd = p_nd->m_p_next_sibling;
    }
}