int binode_cache_add (uint64_t key, unsigned char *hash_key) { clock_t start, end; int ret = 0, i = 0; uint64_t val = 0; uint32_t temp_hash; LINKED *temp; bt_key_val kv,*kv1; if(count_block_inode>MAX_BINODE_COUNT) { temp=binode_list->prev; btree_delete_key(block_inode_tree,block_inode_tree->root,binode_list->prev->kv.key); binode_list->prev=temp->prev; temp->prev->next=binode_list; free(temp); // fprintf(stderr, "flushing memory cache\n"); count_block_inode--; } kv.key = key; kv.val = 0; kv.val = (uint64_t)libhashkit_murmur(hash_key,16); if(binode_list==NULL) { binode_list=malloc(sizeof(LINKED)); binode_list->prev=binode_list; binode_list->next=binode_list; temp=binode_list; } else { temp=malloc(sizeof(LINKED)); temp->prev=binode_list->prev; temp->next=binode_list; binode_list->prev=temp; binode_list=temp; } count_block_inode++; kv.pt=temp; temp->kv=kv; temp_hash = libhashkit_murmur(hash_key,16); #ifdef DEBUG_FUXEXMP fprintf(stderr, "binode_cache_add: k %llx v %llx hash %lx\n",kv.key,kv.val,temp_hash); #endif btree_insert_key(block_inode_tree, kv); return ret; }
static test_return_t murmur_run (hashkit_st *hashk) { (void)hashk; #ifdef WORDS_BIGENDIAN (void)murmur_values; return TEST_SKIPPED; #else uint32_t x; const char **ptr; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { uint32_t hash_val; #ifdef HAVE_MURMUR_HASH hash_val= libhashkit_murmur(*ptr, strlen(*ptr)); #else hash_val= 1; #endif assert(murmur_values[x] == hash_val); } return TEST_SUCCESS; #endif }
uint32_t libhashkit_digest(const char *key, size_t key_length, hashkit_hash_algorithm_t hash_algorithm) { switch (hash_algorithm) { case HASHKIT_HASH_DEFAULT: return libhashkit_one_at_a_time(key, key_length); case HASHKIT_HASH_MD5: return libhashkit_md5(key, key_length); case HASHKIT_HASH_CRC: return libhashkit_crc32(key, key_length); case HASHKIT_HASH_FNV1_64: return libhashkit_fnv1_64(key, key_length); case HASHKIT_HASH_FNV1A_64: return libhashkit_fnv1a_64(key, key_length); case HASHKIT_HASH_FNV1_32: return libhashkit_fnv1_32(key, key_length); case HASHKIT_HASH_FNV1A_32: return libhashkit_fnv1a_32(key, key_length); case HASHKIT_HASH_HSIEH: #ifdef HAVE_HSIEH_HASH return libhashkit_hsieh(key, key_length); #else return 1; #endif case HASHKIT_HASH_MURMUR: #ifdef HAVE_MURMUR_HASH return libhashkit_murmur(key, key_length); #else return 1; #endif case HASHKIT_HASH_JENKINS: return libhashkit_jenkins(key, key_length); case HASHKIT_HASH_CUSTOM: case HASHKIT_HASH_MAX: default: #ifdef HAVE_DEBUG fprintf(stderr, "hashkit_hash_t was extended but libhashkit_generate_value was not updated\n"); fflush(stderr); cb_assert(0); #endif break; } return 1; }
static int xmp_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int fd, status,i; int res, found_index; uint32_t block_num; unsigned char hash_key[16], *data_block,temp_md5_hash[16]; uint64_t key,hash_temp,key1; struct stat stbuf; clock_t start, end; STATS case_1, case_2, case_3, case_4; bt_key_val temp_binode1; bt_key_val temp_memory1; start = clock (); #ifdef DEBUG_FUXEXMP fprintf (stderr, "Reading...\n"); fprintf (stderr, "binode size = %d cache size = %d\n", HASH_COUNT (block_inode), HASH_COUNT (memory)); #endif (void) fi; fd = open (path, O_RDONLY); if (fd == -1) return -errno; lstat64 (path, &stbuf); block_num = offset / 4096; key = stbuf.st_ino; key = key<<32; key = key + block_num; key1 = libhashkit_murmur((unsigned char *)&key, 8); key = key1; //Check if block:inode is present in (block:inode,index) table] status = binode_cache_find (key, &temp_binode1); #ifdef DEBUG_FUXEXMP fprintf (stderr, "status = %d\n", status); #endif if (status == SUCCESS) //If found, just copy the data from (md5,index) table to buffer { status = memory_cache_find (temp_binode1.val, &temp_memory1); if (status == SUCCESS) { memcpy (buf, (void *)temp_memory1.val, size); res = size; #ifdef DEBUG_FUXEXMP fprintf (stderr, "Found in cache_mem !\n"); #endif case1++; } else { #ifdef DEBUG_FUXEXMP fprintf (stderr, "Not Found in cache_mem !\n"); fprintf (stderr, "Doing read fd = %d size = %lu offset = %lu\n", fd, size, offset); #endif res = pread (fd, buf, size, offset); if (res < 4096) goto end; //Adding a new entry into (hash,data blocks) table status = memory_cache_add (hash_key, buf, res); if (status) goto end; case2++; } } else { /*if not found 1. Read data block from disk 2. Compute md5 of the block 3. Use md5 as key to check if block is already in cache 4. if block is not present, create a new entries the following tables (block:inode,index) (index, data blocks) (md5, index) else create a new entry in (block:inode,index) table and update its index field appropriately. */ #ifdef DEBUG_FUXEXMP fprintf (stderr, "Doing read fd = %d size = %lu offset = %lu\n", fd, size, offset); #endif res = pread (fd, buf, size, offset); if (res < 4096) goto end; //Use md5 as key to check if the read block is already in cache libhashkit_md5_signature_wrap (buf, res, hash_key); hash_temp = libhashkit_murmur(hash_key,16); status = memory_cache_find (hash_temp, &temp_memory1); #ifdef DEBUG_FUXEXMP fprintf (stderr, "memory_cache_find status = %d\n", status); #endif if (status == FAILURE) //if block is not present { //Adding a new entry into (inode:blocknumber,hash) table status = binode_cache_add (key, hash_key); if (status) goto end; count_block_inode++; //Adding a new entry into (hash,data blocks) table status = memory_cache_add (hash_key, buf, res); if (status) goto end; case3++; } else //if block is present, create a new entry in (block:inode,hash) table { //Adding a new entry into (inode:blocknumber,hash) table status = binode_cache_add (key, hash_key); if (status) goto end; case4++; } } end: if (res == -1) res = -errno; end = clock (); close (fd); return res; }
int memory_cache_add (unsigned char *hash_key, unsigned char *data, int size) { unsigned char *data_block = NULL; clock_t start, end; int ret = 0, i; uint64_t val = 0; unsigned char temp_md5_hash[16]; LINKED *temp; bt_key_val kv; if(count_memory_cache>MAX_MEMORY_COUNT) { temp=memory_list->prev; //while(temp->next) // temp=temp->next; btree_delete_key(memory_tree,memory_tree->root,memory_list->prev->kv.key); free(memory_list->prev->kv.val); memory_list->prev=temp->prev; temp->prev->next=memory_list; free(temp); // fprintf(stderr, "flushing memory cache\n"); count_memory_cache--; } kv.key = libhashkit_murmur(hash_key,16); kv.val = 0; start = clock (); data_block = malloc (4096); kv.val = (uint64_t)data_block; memcpy (data_block, data, size); if(memory_list==NULL) { memory_list=malloc(sizeof(LINKED)); memory_list->prev=memory_list; memory_list->next=memory_list; temp=memory_list; } else { temp=malloc(sizeof(LINKED)); temp->prev=memory_list->prev; temp->next=memory_list; memory_list->prev=temp; memory_list=temp; } count_memory_cache++; kv.pt=temp; temp->kv=kv; btree_insert_key(memory_tree,kv); exit: return ret; }