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; }
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; }