示例#1
0
文件: tree.c 项目: nabeken/bird
/**
 * find_tree
 * @t: tree to search in
 * @val: value to find
 *
 * Search for given value in the tree. I relies on fact that sorted tree is populated
 * by &f_val structures (that can be compared by val_compare()). In each node of tree,
 * either single value (then t->from==t->to) or range is present.
 *
 * Both set matching and |switch() { }| construction is implemented using this function,
 * thus both are as fast as they can be.
 */
struct f_tree *
find_tree(struct f_tree *t, struct f_val val)
{
    if (!t)
        return NULL;
    if ((val_compare(t->from, val) != 1) &&
            (val_compare(t->to, val) != -1))
        return t;
    if (val_compare(t->from, val) == -1)
        return find_tree(t->right, val);
    else
        return find_tree(t->left, val);
}
示例#2
0
static void cache_module( const char *filename, aptime time, value main ) {
	cache *c = (cache*)local_get(cache_root), *prev = NULL;
	value fname = alloc_string(filename);
	while( c != NULL ) {
		if( val_compare(fname,c->file) == 0 ) {
			if( main == NULL ) {
				if( prev == NULL )
					local_set(cache_root,c->next);
				else
					prev->next = c->next;
				free_root((value*)c);
			} else {
				c->main = main;
				c->time = time;
			}
			return;
		}
		prev = c;
		c = c->next;
	}
	c = (cache*)alloc_root(sizeof(struct cache) / sizeof(value));
	c->file = fname;
	c->main = main;
	c->time = time;
	c->hits = 0;
	c->next = (cache*)local_get(cache_root);
	local_set(cache_root,c);
}
示例#3
0
static value cache_find( request_rec *r ) {
	cache *c = (cache*)local_get(cache_root);
	cache *prev = NULL;
	value fname = alloc_string(r->filename);
	while( c != NULL ) {
		if( val_compare(fname,c->file) == 0 ) {
			if( config.use_cache && FTIME(r) == c->time ) {
				c->hits++;
				return c->main;
			}
			if( prev == NULL )
				local_set(cache_root,c->next);
			else
				prev->next = c->next;
			free_root((value*)c);
			// try to lower memory partitioning
			// when a module is updated
			c = NULL;
			gc_major();
			break;
		}
		prev = c;
		c = c->next;
	}
	return NULL;
}
示例#4
0
文件: tree.c 项目: nabeken/bird
/**
 * same_tree
 * @t1: first tree to be compared
 * @t2: second one
 *
 * Compares two trees and returns 1 if they are same
 */
int
same_tree(struct f_tree *t1, struct f_tree *t2)
{
    if ((!!t1) != (!!t2))
        return 0;
    if (!t1)
        return 1;
    if (val_compare(t1->from, t2->from))
        return 0;
    if (val_compare(t1->to, t2->to))
        return 0;
    if (!same_tree(t1->left, t2->left))
        return 0;
    if (!same_tree(t1->right, t2->right))
        return 0;
    if (!i_same(t1->data, t2->data))
        return 0;
    return 1;
}
示例#5
0
文件: builtins.c 项目: ConstNW/neko
/**
	$hset : 'hash -> k:any -> v:any -> cmp:function:2? -> bool
	<doc>
	Set the value bound to key [k] to [v] or add it to the hashtable if not found.
	Return true if the value was added to the hashtable.
	</doc>
**/
static value builtin_hset( value vh, value key, value val, value cmp ) {
	vhash *h;
	hcell *c;
	int hkey;
	if( !val_is_null(cmp) )
		val_check_function(cmp,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	hkey = val_hash(key);
	c = h->cells[hkey % h->ncells];
	if( val_is_null(cmp) ) {
		while( c != NULL ) {
			if( val_compare(key,c->key) == 0 ) {
				c->val = val;
				return val_false;
			}
			c = c->next;
		}
	} else {
		while( c != NULL ) {
			if( val_call2(cmp,key,c->key) == alloc_int(0) ) {
				c->val = val;
				return val_false;
			}
			c = c->next;
		}
	}
	if( h->nitems >= (h->ncells << 1) )
		builtin_hresize(vh,alloc_int(h->ncells << 1));
	c = (hcell*)alloc(sizeof(hcell));
	c->hkey = hkey;
	c->key = key;
	c->val = val;
	hkey %= h->ncells;
	c->next = h->cells[hkey];
	h->cells[hkey] = c;
	h->nitems++;
	return val_true;
}
示例#6
0
文件: builtins.c 项目: ConstNW/neko
/**
	$hremove : 'hash -> k:any -> cmp:function:2? -> bool
	<doc>
		Look for the value bound to the key [k] in the hashtable.
		Use the comparison function [cmp] or [$compare] if [null].
		Return true if such value exists and remove it from the hash, false either.
	</doc>
**/
static value builtin_hremove( value vh, value key, value cmp ) {
	vhash *h;
	hcell *c, *prev = NULL;
	int hkey;
	if( !val_is_null(cmp) )
		val_check_function(cmp,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	hkey = val_hash(key) % h->ncells;
	c = h->cells[hkey];
	if( val_is_null(cmp) ) {
		while( c != NULL ) {
			if( val_compare(key,c->key) == 0 ) {
				if( prev == NULL )
					h->cells[hkey] = c->next;
				else
					prev->next = c->next;
				h->nitems--;
				return val_true;
			}
			prev = c;
			c = c->next;
		}
	} else {
		while( c != NULL ) {
			if( val_call2(cmp,key,c->key) == alloc_int(0) ) {
				if( prev == NULL )
					h->cells[hkey] = c->next;
				else
					prev->next = c->next;
				h->nitems--;
				return val_true;
			}
			prev = c;
			c = c->next;
		}
	}
	return val_false;
}
示例#7
0
文件: builtins.c 项目: ConstNW/neko
/**
	$hmem : 'hash -> k:any -> cmp:function:2? -> bool
	<doc>
		Look for the value bound to the key [k] in the hashtable.
		Use the comparison function [cmp] or [$compare] if [null].
		Return true if such value exists, false either.
	</doc>
**/
static value builtin_hmem( value vh, value key, value cmp ) {
	vhash *h;
	hcell *c;
	if( !val_is_null(cmp) )
		val_check_function(cmp,2);
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	c = h->cells[val_hash(key) % h->ncells];
	if( val_is_null(cmp) ) {
		while( c != NULL ) {
			if( val_compare(key,c->key) == 0 )
				return val_true;
			c = c->next;
		}
	} else {
		while( c != NULL ) {
			if( val_call2(cmp,key,c->key) == alloc_int(0) )
				return val_true;
			c = c->next;
		}
	}
	return val_false;
}
示例#8
0
文件: builtins.c 项目: ConstNW/neko
/**
	$compare : any -> any -> int?
	<doc>Compare two values and return 1, -1 or 0. Return [null] if comparison is not possible</doc>
**/
static value builtin_compare( value a, value b ) {
	int r = val_compare(a,b);
	return (r == invalid_comparison)?val_null:alloc_int(r);
}