Beispiel #1
0
static void * node_contains(comparer c, node n, void * e) {
    if (n == NULL)
        return NULL;
    else if (c(e, n->data) < 0)
        return node_contains(c,n->left,e);
    else if (c(e, n->data) > 0) {
        return node_contains(c,n->right,e);
    } else {
        return n->data;
    }
}
Beispiel #2
0
bool node_contains(list_node_t *n, uint64_t v) {
  if(n == NULL) {
    return false;
  } else if(n->value == v) {
    return true;
  } else {
    return node_contains(n->next, v);
  }
}
Beispiel #3
0
/// Uppgift #2
bool list_contains_rec(list_t *l, uint64_t v)
{
  return node_contains(l->first, v);
}
Beispiel #4
0
void * tree_get(tree t, void * e)
{
    return node_contains(t->comp, t->header, e);
}
Beispiel #5
0
void seek_live(term_t *tp, apr_memnode_t *newest, heap_t *hp)
{
	term_t t = *tp;
	apr_memnode_t *node;
	term_box_t *ptr;

	// newest node - the node last generation the term may belong to
	// the node chain starts with the newest and goes to hp->gc_spot

	if (is_immed(t))
		return;
	ptr = peel(t);

	node = newest;
	while (node != hp->gc_spot)
	{
		if (node_contains(node, ptr))
		{
			// the term belongs to the newer generation
			// of terms; recurse to find possible references
			// to live terms in hp->gc_spot

			// only tuples, conses, funs (frozen)
			// and binaries (data, parent) contain references

			// order of popularity:
			// cons - tuple - binary - fun

			if (is_cons(t))
			{
				seek_live(&ptr->cons.head, node, hp);
				seek_live(&ptr->cons.tail, node, hp);
			}
			else if (is_tuple(t))
			{
				int i;
				int n = ptr->tuple.size;
				for (i = 0; i < n; i++)
					seek_live(&ptr->tuple.elts[i], node, hp);
			}
			else if (is_binary(t))
			{
				if (ptr->binary.parent != noval)
				{
					term_box_t *parent;
					seek_live(&ptr->binary.parent, node, hp);
					parent = peel(ptr->binary.parent);
					ptr->binary.data = parent->binary.data + ptr->binary.offset;
				}
			}
			else if (is_fun(t))
			{
				seek_live(&ptr->fun.frozen, node, hp);
			}

			return;
		}
		node = node->next;
	}

	if (node_contains(hp->gc_spot, ptr))
	{
		// the term should be recreated

		// the term may have already been moved
		// and the term value has been replaced with
		// the buried reference to the new location

		if (is_grave(t))
		{
			*tp = ptr->grave.skeleton;
			return;
		}

		// list - tuple - binary - fun - bignum - pid - float

		if (is_list(t))
		{
			term_t cons = heap_cons2(hp, ptr->cons.head, ptr->cons.tail);
			term_box_t *box = peel(cons);
			seek_live(&box->cons.head, hp->gc_spot, hp);
			seek_live(&box->cons.tail, hp->gc_spot, hp);
			*tp = cons;
		}
		else if (is_tuple(t))
		{
			term_t tuple = heap_tuple(hp, ptr->tuple.size);
			term_box_t *box = peel(tuple);
			int i;
			for (i = 0; i < ptr->tuple.size; i++)
			{
				box->tuple.elts[i] = ptr->tuple.elts[i];
				seek_live(&box->tuple.elts[i], hp->gc_spot, hp);
			}
			*tp = tuple;
		}
		else if (is_binary(t))
		{
			term_t parent = ptr->binary.parent;
			term_t b;
			if (parent == noval)
				b = heap_binary(hp, ptr->binary.bit_size, ptr->binary.data);
			else
			{
				apr_byte_t *data;
				seek_live(&parent, hp->gc_spot, hp);
				data = peel(parent)->binary.data + ptr->binary.offset;
				b = heap_binary_shared(hp, ptr->binary.bit_size, data, parent);
			}
			*tp = b;
		}
		else if (is_fun(t))
		{
			term_t f = heap_fun(hp,
				ptr->fun.module, ptr->fun.function, ptr->fun.arity,
				ptr->fun.uniq, ptr->fun.index, ptr->fun.frozen);
			seek_live(&peel(f)->fun.frozen, hp->gc_spot, hp);
			*tp = f;
		}
		else if (is_bignum(t))
		{
			mp_int ma = bignum_to_mp(t);
			*tp = heap_bignum(hp, SIGN(&ma), USED(&ma), DIGITS(&ma));
		}
		else if (is_long_id(t))
		{
			*tp = heap_long_id(hp,
				ptr->long_id.node,
				ptr->long_id.serial,
				ptr->long_id.tag_creation);
		}
		else	// if (is_float(t))
		{
			assert(is_float(t));
			*tp = heap_float(hp, float_value(t));
		}

		// bury the term
		ptr->grave.cross = MAGIC_CROSS;
		ptr->grave.skeleton = *tp;

		return;
	}
	else
	{
		// the term belong to the older generation or
		// to the literal pool of the module -- ignore

		return;
	}
}