Ejemplo n.º 1
0
int main(int argc,char *argv[])
{
	struct freemap *fm;
	int fd;
	off_t offset;
	unsigned int size;
	FILE *f;
	struct freemap *newfm;

	fm = freemap_new();
	if(fm == NULL)
		return -1;
	if(freemap_add(fm,NULL,FREEMAP_CREAT) != 0)
		return -1;
	size = 4096;
	if(freemap_malloc(fm,&size,&fd,&offset) != 0)
		return -1;

	f = fopen("test","w+");
	if(freemap_dump(fm,f) != 0)
		return -1;
	if(fseek(f,SEEK_SET,0L) != 0)
		return -1;
	newfm = freemap_load(f);
	if(newfm == NULL)
		return -1;
	freemap_free(fm);
	freemap_free(newfm);
	return 0;
}
Ejemplo n.º 2
0
static int merge_invertedlist_page(struct posting *p,struct bucket *bkt, struct cache *cache,struct freemap *freemap)
{
	unsigned int docnum;
	unsigned int lastdoc;
	unsigned int firstdoc;
	int len_firstdoc;
	int fd;
	off_t offset;
	unsigned int size;
	unsigned short invertedlen;
	unsigned int add_size;
	struct vector *v;
	struct bucket tmp;
	struct page *page;
	int page_data_size;
	int available_size;
	char *ptr;

	assert(p);
	v = p->invertedlist;
	len_firstdoc = vbyte_decompress(v->vector,v->vector+v->len,&firstdoc);
	if(len_firstdoc <= 0)
		goto exit;
	docnum = *((unsigned int*)bkt->record);
	lastdoc = *((unsigned int*)((char*)bkt->record+sizeof(unsigned int)));
	assert(firstdoc > lastdoc);
	page_data_size =  PAGE_SIZE - sizeof(struct HEAD);
	invertedlen = bkt->head->num; /* special use for such kind of page,bkt->head->num
				         no longer store the number of records, it stores
				         invertedlen instead. */ 
	add_size = v->len - len_firstdoc;
	bkt->head->num += (v->len-len_firstdoc+vbyte_len(firstdoc-lastdoc));
	*((unsigned int*)bkt->record) += p->count;
	((unsigned int*)bkt->record)[1] = p->lastdoc;

	/* switch to the last page */
	tmp = *bkt;
	while(tmp.head->next.fd != 0)
	{
		fd = tmp.head->next.fd;
		offset = tmp.head->next.offset;
		page = cache_pagein(cache,fd,offset);
		if(page == NULL)
			goto exit;
		bucket_load(&tmp,page);
	}
	/* add invertedlist in the page */
	if((char*)tmp.record+tmp.head->ptr + vbyte_len(firstdoc-lastdoc) < (char*)tmp.head + PAGE_SIZE)
		tmp.head->ptr += vbyte_compress((char*)tmp.record+tmp.head->ptr,(char*)tmp.head+PAGE_SIZE,firstdoc-lastdoc);
	else
	{
		size = PAGE_SIZE;
		if(freemap_malloc(freemap,&size,&fd,&offset) != 0)
			goto exit;
		page = cache_newpage(cache,fd,offset);
		if(page == NULL)
			goto exit;
		bucket_init(&tmp,page,0);
		tmp.head->next.fd = fd;
		tmp.head->next.offset = offset;
		tmp.head->ptr = 0;
		tmp.head->ptr += vbyte_compress((char*)tmp.record+tmp.head->ptr,(char*)tmp.head+PAGE_SIZE,firstdoc-lastdoc);
	}	
	ptr = v->vector+len_firstdoc;
	while(add_size > 0)
	{
		if((char*)tmp.record + tmp.head->ptr + add_size < (char*)tmp.head + PAGE_SIZE)
		{
			memcpy((char*)tmp.record+tmp.head->ptr,ptr,add_size);
			tmp.head->ptr += add_size;
			add_size = 0;
		}
		else
		{
			available_size = PAGE_SIZE-sizeof(struct HEAD)-tmp.head->ptr;
			memcpy((char*)tmp.record+tmp.head->ptr,ptr,available_size);
			ptr += available_size;
			tmp.head->ptr += available_size;
			add_size -= available_size;

			size = PAGE_SIZE;
			if(freemap_malloc(freemap,&size,&fd,&offset) != 0)
				goto exit;
			page = cache_newpage(cache,fd,offset);
			if(page == NULL)
				goto exit;
			tmp.head->next.fd = fd;
			tmp.head->next.offset = offset;
			bucket_init(&tmp,page,0);
			tmp.head->ptr = 0;
		}
	}
	return 0;
exit:
	return -1;
}