Exemplo n.º 1
0
/* recursive to search the matched record */
static void _xdb_rec_get(xdb_t x, xrec_t rec, const char *key, int len)
{
	unsigned char buf[XDB_MAXKLEN + 2];	// greater than: 255
	int cmp;

	if (rec->me.len == 0)
		return;

	// [left][right] = 16\0
	_xdb_read_data(x, buf, rec->me.off + 16, len + 1);
	cmp = memcmp(key, buf+1, len);
	if (!cmp)
		cmp = len - buf[0];	
	if (cmp > 0)
	{
		// right
		rec->poff = rec->me.off + sizeof(xptr_st);
		_xdb_read_data(x, &rec->me, rec->me.off + sizeof(xptr_st), sizeof(xptr_st));
		_xdb_rec_get(x, rec, key, len);
	}
	else if (cmp < 0)
	{
		// left
		rec->poff = rec->me.off;
		_xdb_read_data(x, &rec->me, rec->me.off, sizeof(xptr_st));
		_xdb_rec_get(x, rec, key, len);
	}
	else
	{
		// found!
		rec->value.off = rec->me.off + 17 + len;
		rec->value.len = rec->me.len - 17 - len;
	}
}
Exemplo n.º 2
0
static void _xdb_count_nodes(xdb_t x, xptr_t ptr, int *count)
{
	int off;
	if (ptr->len == 0)
		return;

	*count += 1;
	off = ptr->off;

	/* left & right */
	_xdb_read_data(x, ptr, off, sizeof(xptr_st));
	_xdb_count_nodes(x, ptr, count);

	_xdb_read_data(x, ptr, off + sizeof(xptr_st), sizeof(xptr_st));
	_xdb_count_nodes(x, ptr, count);
}
Exemplo n.º 3
0
static void _xdb_load_nodes(xdb_t x, xptr_t ptr, xcmper_st *nodes, int *count)
{
	int i;
	unsigned char buf[XDB_MAXKLEN + 18];

	if (ptr->len == 0)
		return;

	i = sizeof(buf)-1;
	if (i > (int)ptr->len)
		i = ptr->len;

	_xdb_read_data(x, buf, ptr->off, i);

	i = *count;
	nodes[i].ptr.off = ptr->off;
	nodes[i].ptr.len = ptr->len;
	nodes[i].key = (char *) _mem_ndup(buf + 17, buf[16]);
	*count = i+1;

	/* left & right */
	memcpy(ptr, buf, sizeof(xptr_st));
	_xdb_load_nodes(x, ptr, nodes, count);

	memcpy(ptr, buf + sizeof(xptr_st), sizeof(xptr_st));
	_xdb_load_nodes(x, ptr, nodes, count);
}
Exemplo n.º 4
0
static void _xdb_draw_node(xdb_t x, xptr_t ptr, struct draw_arg *arg, int depth, char *icon1)
{
	char *icon2;
	
	icon2 = malloc(strlen(icon1) + 4);
	strcpy(icon2, icon1);

	// output the flag & icon
	if (arg->flag == 'T')	
		printf("(T) ");	
	else
	{
		printf("%s", icon2);
		if (arg->flag  == 'L')
		{
			strcat(icon2, " ┃");
			printf(" ┟(L) ");
		}
		else
		{
			strcat(icon2, "  ");
			printf(" └(R) ");
		}
	}

	// draw the node data
	if (ptr->len == 0)
		printf("<NULL>\n");	
	else
	{
		unsigned char buf[XDB_MAXKLEN + 18];		// greater than 18 = sizeof(xptr_st)*2+1
		int vlen, voff;

		vlen = sizeof(buf) - 1;
		if (vlen > ptr->len)
			vlen = ptr->len;

		_xdb_read_data(x, buf, ptr->off, vlen);
		vlen = ptr->len - buf[16] - 17;
		voff = ptr->off + buf[16] + 17;

		printf("%.*s (vlen=%d, voff=%d)\n", buf[16], buf+17, vlen, voff);

		arg->count++;
		depth++;
		if (depth > arg->depth)
			arg->depth = depth;

		// draw the left & right;
		arg->flag = 'L';
		memcpy(ptr, buf, sizeof(xptr_st));
		_xdb_draw_node(x, ptr, arg, depth, icon2);

		arg->flag = 'R';
		memcpy(ptr, buf + sizeof(xptr_st), sizeof(xptr_st));
		_xdb_draw_node(x, ptr, arg, depth, icon2);
	}
	free(icon2);
}
Exemplo n.º 5
0
/* write mode */
void xdb_nput(xdb_t x, void *value, unsigned int vlen, const char *key, int len)
{
	xrec_st rec;

	if (x == NULL || x->fd < 0 || key == NULL || len > XDB_MAXKLEN)
		return;

	/* not found, return the poff(for write) */	
	_xdb_rec_find(x, key, len, &rec);
	if (rec.value.len > 0 && vlen <= rec.value.len)
	{
		/* just replace */
		if (vlen > 0)
		{		
			lseek(x->fd, rec.value.off, SEEK_SET);
			write(x->fd, value, vlen);
		}
		if (vlen < rec.value.len)
		{
			vlen += rec.me.len - rec.value.len;
			lseek(x->fd, rec.poff + 4, SEEK_SET);
			write(x->fd, &vlen, sizeof(vlen));
		}
	}
	else if (vlen > 0)
	{
		/* insert for new data */
		unsigned char buf[512];
		xptr_st pnew;

		pnew.off = x->fsize;		
		memset(buf, 0, sizeof(buf));
		pnew.len = rec.me.len - rec.value.len;
		if (pnew.len > 0)
		{
			_xdb_read_data(x, buf, rec.me.off, pnew.len);
		}
		else
		{
			buf[16] = len;	// key len
			strncpy(buf + 17, key, len);
			pnew.len = 17 + len;
		}
		lseek(x->fd, pnew.off, SEEK_SET);
		write(x->fd, buf, pnew.len);
		write(x->fd, value, vlen);
		pnew.len += vlen;
		x->fsize += pnew.len;

		/* update noff & vlen -> poff */
		lseek(x->fd, rec.poff, SEEK_SET);
		write(x->fd, &pnew, sizeof(pnew));
	}
}
Exemplo n.º 6
0
static xrec_t _xdb_rec_find(xdb_t x, const char *key, int len, xrec_t rec)
{	
	int i;
	
	if (rec == NULL)
		rec = (xrec_t) malloc(sizeof(xrec_st));

	memset(rec, 0, sizeof(xrec_st));
	i = (x->prime > 1 ? _xdb_hasher(x, key, len) : 0);
	rec->poff = i * sizeof(xptr_st) + sizeof(struct xdb_header);

	_xdb_read_data(x, &rec->me, rec->poff, sizeof(xptr_st));
	_xdb_rec_get(x, rec, key, len);
	return rec;
}
Exemplo n.º 7
0
/* read mode (value require free by user) */
void *xdb_nget(xdb_t x, const char *key, int len, unsigned int *vlen)
{
	xrec_st rec;
	void *value = NULL;

	if (x == NULL || key == NULL || len > XDB_MAXKLEN)
		return NULL;

	/* not found, return the poff(for write) */
	_xdb_rec_find(x, key, len, &rec);
	if (rec.value.len > 0)
	{
		/* auto append one byte with '\0' */		
		value = malloc(rec.value.len + 1);
		if (vlen != NULL)		
			*vlen = rec.value.len;
		_xdb_read_data(x, value, rec.value.off, rec.value.len);
	}	
	return value;
}
Exemplo n.º 8
0
void xdb_draw(xdb_t x)
{
	int i;
	struct draw_arg arg;
	xptr_st ptr;

	if (!x) return;

	xdb_version(x);
	for (i = 0; i < x->prime; i++)
	{		
		arg.depth = 0;
		arg.count = 0;
		arg.flag = 'T';

		_xdb_read_data(x, &ptr, i * sizeof(xptr_st) + sizeof(struct xdb_header), sizeof(xptr_st));
		_xdb_draw_node(x, &ptr, &arg, 0, "");

		printf("-----------------------------------------\n");
		printf("Tree(xdb) [%d] max_depth: %d nodes_num: %d\n", i, arg.depth, arg.count);
	}
}