void *dict_find(dict_t *dict, void *key, size_t bytes) { unsigned int index = _dict_index(dict, key, bytes); /* not founded in the index-th bucket, then insert */ bucket_elem_t *elem = _bucket_find(&dict->table[index], key, bytes); return elem == NULL ? NULL : elem->value; }
int bucket_remove(struct bucket *bkt,char *term) { unsigned short pos; unsigned int len; char *posptr; int size; unsigned short i; unsigned short true_invertedlen; if(_bucket_find(bkt,term,&pos) != 0) return -1; /* remove inverted list */ true_invertedlen = (bkt->record[pos].invertedlen==USHRT_MAX) ? (sizeof(int)+sizeof(off_t)):bkt->record[pos].invertedlen; len = bkt->record[pos].termlen + true_invertedlen; posptr = (char*)bkt->head+bkt->record[pos].offset; size = posptr - START_OF_INVERTEDLIST; memmove(START_OF_INVERTEDLIST+len,START_OF_INVERTEDLIST,size); bkt->head->ptr += len; /* remove entry in record */ memmove(&bkt->record[pos],&bkt->record[pos+1],(bkt->head->num-pos-1)*sizeof(struct RECORD)); bkt->head->num--; /* update entry's offset in record */ for(i=0; i<bkt->head->num; i++) { if((char*)bkt->head+bkt->record[i].offset < posptr) bkt->record[i].offset += len; } bkt->page->dirty = true; return 0; }
char* bucket_find(struct bucket *bkt,const char *term,unsigned int *invertedlen) { unsigned short pos; if(_bucket_find(bkt,term,&pos) != 0) return NULL; *invertedlen = bkt->record[pos].invertedlen; return (char*)bkt->head + bkt->record[pos].offset + bkt->record[pos].termlen; }
/* NOTE:assume the term isn't in bucket,otherwise you must remove it before insert!!! */ int bucket_insert(struct bucket *bkt,char *term,void *invertedlist,unsigned short invertedlen) { unsigned short pos; int termlen; int big; char string[256]; unsigned short true_invertedlen; true_invertedlen = (invertedlen==USHRT_MAX) ? (sizeof(int)+sizeof(off_t)):invertedlen; if(bkt->head->num == 0) { termlen = strlen(term); if((char*)&bkt->record[1] > START_OF_INVERTEDLIST-true_invertedlen-termlen) return -2; bkt->head->ptr = bkt->head->ptr-true_invertedlen-termlen; memcpy(START_OF_INVERTEDLIST,term,termlen); memcpy(START_OF_INVERTEDLIST+termlen,invertedlist,true_invertedlen); bkt->record[0].offset = bkt->head->ptr; bkt->record[0].termlen = termlen; bkt->record[0].invertedlen = invertedlen; bkt->head->num++; bkt->page->dirty = true; return 0; } if(_bucket_find(bkt,term,&pos) == 0) return -1; termlen = bkt->record[pos].termlen; memcpy(string,(char*)bkt->head+bkt->record[pos].offset,termlen); string[termlen] = '\0'; termlen = strlen(term); if(START_OF_INVERTEDLIST-true_invertedlen-termlen < (char*)&bkt->record[bkt->head->num]+sizeof(struct RECORD)) /* not enough space */ return -2; big = strcmp(term,string); if(big < 0) /* insert before pos */ { /* modify for record */ memmove(&bkt->record[pos+1],&bkt->record[pos],(bkt->head->num-pos)*sizeof(struct RECORD)); bkt->record[pos].termlen = termlen; bkt->record[pos].invertedlen = invertedlen; bkt->record[pos].offset = START_OF_INVERTEDLIST-true_invertedlen-termlen-(char*)bkt->head; bkt->head->ptr = bkt->head->ptr-true_invertedlen-termlen; memcpy(START_OF_INVERTEDLIST,term,termlen); /* modify inverted list */ memcpy(START_OF_INVERTEDLIST+termlen,invertedlist,true_invertedlen); bkt->head->num++; } else /* insert after pos */ { if(pos+1 < bkt->head->num) /* modify record */ memmove(&bkt->record[pos+2],&bkt->record[pos+1],(bkt->head->num-pos-1)*sizeof(struct RECORD)); bkt->record[pos+1].termlen = termlen; bkt->record[pos+1].invertedlen = invertedlen; bkt->record[pos+1].offset = START_OF_INVERTEDLIST-true_invertedlen-termlen-(char*)bkt->head; bkt->head->ptr = bkt->head->ptr-true_invertedlen-termlen; memcpy(START_OF_INVERTEDLIST,term,termlen); /* modify inverted list */ memcpy(START_OF_INVERTEDLIST+termlen,invertedlist,true_invertedlen); bkt->head->num++; } bkt->page->dirty = true; assert(START_OF_INVERTEDLIST >= (char*)&bkt->record[bkt->head->num]); return 0; }