/** * * nfs41_Session_Set * * This routine sets a session into the sessions's hashtable. * * @param psession [IN] pointer to the sessionid to be checked. * * @return 1 if ok, 0 otherwise. * */ int nfs41_Session_Set(char sessionid[NFS4_SESSIONID_SIZE], nfs41_session_t * psession_data) { hash_buffer_t buffkey; hash_buffer_t buffval; if(isFullDebug(COMPONENT_SESSIONS)) { char str[NFS4_SESSIONID_SIZE *2 + 1]; sprint_mem(str, (char *)sessionid, NFS4_SESSIONID_SIZE); LogFullDebug(COMPONENT_SESSIONS, " ----- SetSSession : %s\n", str); } if((buffkey.pdata = (caddr_t) Mem_Alloc(NFS4_SESSIONID_SIZE)) == NULL) return 0; memcpy(buffkey.pdata, sessionid, NFS4_SESSIONID_SIZE); buffkey.len = NFS4_SESSIONID_SIZE; buffval.pdata = (caddr_t) psession_data; buffval.len = sizeof(nfs41_session_t); if(HashTable_Test_And_Set (ht_session_id, &buffkey, &buffval, HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS) return 0; return 1; } /* nfs41_Session_Set */
/** * nlm_client_Set * * * This routine sets a NLM client into the related hashtable * * @return 1 if ok, 0 otherwise. * */ int nlm_client_Set(state_nlm_client_t * pkey, state_nlm_client_t * pclient) { hash_buffer_t buffkey; hash_buffer_t buffval; if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE)) { char str[HASHTABLE_DISPLAY_STRLEN]; buffkey.pdata = (caddr_t) pkey; buffkey.len = sizeof(*pkey); display_nlm_client_key(&buffkey, str); LogFullDebug(COMPONENT_STATE, "KEY {%s}", str); } buffkey.pdata = (caddr_t) pkey; buffkey.len = sizeof(*pkey); buffval.pdata = (caddr_t) pclient; buffval.len = sizeof(*pclient); if(HashTable_Test_And_Set (ht_nlm_client, &buffkey, &buffval, HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS) return 0; return 1; } /* nlm_client_Set */
/*---------------------------------------------------- * hash tables helpers *----------------------------------------------------*/ lookup_peer_t *h_insert_new_lookup(ino_t parent_inode, dev_t parent_dev, unsigned int parent_gen, char *name, fsnode_t * p_entry, int overwrite) { hash_buffer_t buffkey; hash_buffer_t buffval; lookup_peer_t *p_lpeer; int flag; /* alloc new peer */ p_lpeer = peer_alloc(); if(!p_lpeer) return NULL; p_lpeer->parent.inum = parent_inode; p_lpeer->parent.dev = parent_dev; p_lpeer->parent.generation = parent_gen; strncpy(p_lpeer->name, name, FSAL_MAX_NAME_LEN); buffkey.pdata = (caddr_t) p_lpeer; buffkey.len = sizeof(*p_lpeer); buffval.pdata = (caddr_t) p_entry; buffval.len = sizeof(*p_entry); if(overwrite) flag = HASHTABLE_SET_HOW_SET_OVERWRITE; else flag = HASHTABLE_SET_HOW_SET_NO_OVERWRITE; if(HashTable_Test_And_Set(lookup_hash, &buffkey, &buffval, flag) != HASHTABLE_SUCCESS) { peer_free(p_lpeer); return NULL; } /* Add lookup to node and increase n_lookup count */ p_entry->n_lookup++; p_lpeer->p_next = p_entry->parent_list; p_entry->parent_list = p_lpeer; return p_lpeer; } /* h_insert_new_lookup */
fsnode_t *h_insert_new_node(ino_t inode, dev_t device, unsigned int gen, int overwrite) { hash_buffer_t buffkey; hash_buffer_t buffval; fsnode_t *p_node; int flag; p_node = node_alloc(); if(!p_node) return NULL; p_node->inode.inum = inode; p_node->inode.dev = device; p_node->inode.generation = gen; /* no children, no hardlink for the moment */ p_node->n_lookup = 0; p_node->n_children = 0; p_node->parent_list = NULL; /* insert it to hash table */ buffkey.pdata = (caddr_t) & p_node->inode; buffkey.len = sizeof(p_node->inode); buffval.pdata = (caddr_t) p_node; buffval.len = sizeof(*p_node); if(overwrite) flag = HASHTABLE_SET_HOW_SET_OVERWRITE; else flag = HASHTABLE_SET_HOW_SET_NO_OVERWRITE; if(HashTable_Test_And_Set(nodes_hash, &buffkey, &buffval, flag) != HASHTABLE_SUCCESS) { node_free(p_node); return NULL; } return p_node; } /* h_insert_new_node */
/** * nfs4_owner_Set * * * This routine sets a open owner into the related hashtable * * @return 1 if ok, 0 otherwise. * */ int nfs4_owner_Set(state_nfs4_owner_name_t * pname, state_owner_t * powner) { hash_buffer_t buffkey; hash_buffer_t buffval; int rc; buffkey.pdata = (caddr_t) pname; buffkey.len = sizeof(state_nfs4_owner_name_t); if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nfs4_owner_key(&buffkey, str); LogFullDebug(COMPONENT_STATE, "KEY {%s}", str); } buffval.pdata = (caddr_t) powner; buffval.len = sizeof(state_owner_t); P(nfs4_owner_counter_lock); nfs4_owner_counter += 1; powner->so_owner.so_nfs4_owner.so_counter = nfs4_owner_counter; V(nfs4_owner_counter_lock); rc = HashTable_Test_And_Set (ht_nfs4_owner, &buffkey, &buffval, HASHTABLE_SET_HOW_SET_NO_OVERWRITE); if(rc != HASHTABLE_SUCCESS) { LogDebug(COMPONENT_STATE, "Failed to insert nfs4 owner into hash table rc = %d", rc); return 0; } return 1; } /* nfs4_owner_Set */
int nfs_dupreq_add_not_finished(long xid, struct svc_req *ptr_req, SVCXPRT *xprt, struct prealloc_pool *dupreq_pool, nfs_res_t *res_nfs) { hash_buffer_t buffkey; hash_buffer_t buffval; hash_buffer_t buffdata; dupreq_entry_t *pdupreq = NULL; int status = 0; dupreq_key_t *pdupkey = NULL; /* Entry to be cached */ GetFromPool(pdupreq, dupreq_pool, dupreq_entry_t); if(pdupreq == NULL) return DUPREQ_INSERT_MALLOC_ERROR; if((pdupkey = (dupreq_key_t *) Mem_Alloc(sizeof(dupreq_key_t))) == NULL) { ReleaseToPool(pdupreq, dupreq_pool); return DUPREQ_INSERT_MALLOC_ERROR; } /* Get the socket address for the key and the request */ if(copy_xprt_addr(&pdupkey->addr, xprt) == 0 || copy_xprt_addr(&pdupreq->addr, xprt) == 0) { Mem_Free(pdupkey); ReleaseToPool(pdupreq, dupreq_pool); return DUPREQ_INSERT_MALLOC_ERROR; } pdupkey->xid = xid; pdupreq->xid = xid; /* Checksum the request */ pdupkey->checksum = 0; pdupreq->checksum = 0; /* I have to keep an integer as key, I wil use the pointer buffkey->pdata for this, * this also means that buffkey->len will be 0 */ buffkey.pdata = (caddr_t) pdupkey; buffkey.len = sizeof(dupreq_key_t); /* I build the data with the request pointer that should be in state 'IN USE' */ pdupreq->rq_prog = ptr_req->rq_prog; pdupreq->rq_vers = ptr_req->rq_vers; pdupreq->rq_proc = ptr_req->rq_proc; pdupreq->timestamp = time(NULL); pdupreq->processing = 1; buffdata.pdata = (caddr_t) pdupreq; buffdata.len = sizeof(dupreq_entry_t); LogDupReq("Add Not Finished", &pdupreq->addr, pdupreq->xid, pdupreq->rq_prog); status = HashTable_Test_And_Set(ht_dupreq, &buffkey, &buffdata, HASHTABLE_SET_HOW_SET_NO_OVERWRITE); if (status == HASHTABLE_ERROR_KEY_ALREADY_EXISTS) { if(HashTable_Get(ht_dupreq, &buffkey, &buffval) == HASHTABLE_SUCCESS) { P(((dupreq_entry_t *)buffval.pdata)->dupreq_mutex); if ( ((dupreq_entry_t *)buffval.pdata)->processing == 1) { V(((dupreq_entry_t *)buffval.pdata)->dupreq_mutex); status = DUPREQ_BEING_PROCESSED; } else { *res_nfs = ((dupreq_entry_t *) buffval.pdata)->res_nfs; V(((dupreq_entry_t *)buffval.pdata)->dupreq_mutex); status = DUPREQ_ALREADY_EXISTS; } } else status = DUPREQ_NOT_FOUND; } else if (status == HASHTABLE_INSERT_MALLOC_ERROR) status = DUPREQ_INSERT_MALLOC_ERROR; else status = DUPREQ_SUCCESS; if (status != DUPREQ_SUCCESS) ReleaseToPool(pdupreq, dupreq_pool); return status; } /* nfs_dupreq_add_not_finished */
fsal_acl_t *nfs4_acl_new_entry(fsal_acl_data_t *pacldata, fsal_acl_status_t *pstatus) { fsal_acl_t *pacl = NULL; hash_buffer_t buffkey; hash_buffer_t buffvalue; int rc; /* Set the return default to NFS_V4_ACL_SUCCESS */ *pstatus = NFS_V4_ACL_SUCCESS; LogDebug(COMPONENT_NFS_V4_ACL, "nfs4_acl_new_entry: acl hash table size = %u", HashTable_GetSize(fsal_acl_hash)); /* Turn the input to a hash key */ if(nfs4_acldata_2_key(&buffkey, pacldata)) { *pstatus = NFS_V4_ACL_UNAPPROPRIATED_KEY; nfs4_release_acldata_key(&buffkey); nfs4_ace_free(pacldata->aces); return NULL; } /* Check if the entry doesn't already exists */ if(HashTable_Get(fsal_acl_hash, &buffkey, &buffvalue) == HASHTABLE_SUCCESS) { /* Entry is already in the cache, do not add it */ pacl = (fsal_acl_t *) buffvalue.pdata; *pstatus = NFS_V4_ACL_EXISTS; nfs4_release_acldata_key(&buffkey); nfs4_ace_free(pacldata->aces); return pacl; } /* Adding the entry in the cache */ pacl = nfs4_acl_alloc(); if(rw_lock_init(&(pacl->lock)) != 0) { nfs4_acl_free(pacl); LogCrit(COMPONENT_NFS_V4_ACL, "nfs4_acl_new_entry: rw_lock_init returned %d (%s)", errno, strerror(errno)); *pstatus = NFS_V4_ACL_INIT_ENTRY_FAILED; nfs4_release_acldata_key(&buffkey); nfs4_ace_free(pacldata->aces); return NULL; } pacl->naces = pacldata->naces; pacl->aces = pacldata->aces; pacl->ref = 0; /* Build the value */ buffvalue.pdata = (caddr_t) pacl; buffvalue.len = sizeof(fsal_acl_t); if((rc = HashTable_Test_And_Set(fsal_acl_hash, &buffkey, &buffvalue, HASHTABLE_SET_HOW_SET_NO_OVERWRITE)) != HASHTABLE_SUCCESS) { /* Put the entry back in its pool */ nfs4_acl_free(pacl); LogWarn(COMPONENT_NFS_V4_ACL, "nfs4_acl_new_entry: entry could not be added to hash, rc=%d", rc); if( rc != HASHTABLE_ERROR_KEY_ALREADY_EXISTS ) { *pstatus = NFS_V4_ACL_HASH_SET_ERROR; nfs4_release_acldata_key(&buffkey); return NULL; } else { LogDebug(COMPONENT_NFS_V4_ACL, "nfs4_acl_new_entry: concurrency detected during acl insertion"); /* This situation occurs when several threads try to init the same uncached entry * at the same time. The first creates the entry and the others got HASHTABLE_ERROR_KEY_ALREADY_EXISTS * In this case, the already created entry (by the very first thread) is returned */ if((rc = HashTable_Get(fsal_acl_hash, &buffkey, &buffvalue)) != HASHTABLE_SUCCESS) { *pstatus = NFS_V4_ACL_HASH_SET_ERROR; nfs4_release_acldata_key(&buffkey); return NULL; } pacl = (fsal_acl_t *) buffvalue.pdata; *pstatus = NFS_V4_ACL_SUCCESS; nfs4_release_acldata_key(&buffkey); return pacl; } } return pacl; }
int main(int argc, char *argv[]) { SetDefaultLogging("TEST"); SetNamePgm("test_cmchash"); hash_table_t *ht = NULL; hash_parameter_t hparam; hash_buffer_t buffval; hash_buffer_t buffkey; hash_buffer_t buffval2; hash_buffer_t buffkey2; hash_stat_t statistiques; int i; int val; int rc; int res; struct Temps debut, fin; char tmpstr[10]; char tmpstr2[10]; char tmpstr3[10]; char strtab[MAXTEST][10]; int critere_recherche = 0; int random_val = 0; hparam.index_size = PRIME; hparam.alphabet_length = 10; hparam.nb_node_prealloc = NB_PREALLOC; hparam.hash_func_key = simple_hash_func; hparam.hash_func_rbt = rbt_hash_func; hparam.compare_key = compare_string_buffer; hparam.key_to_str = display_buff; hparam.val_to_str = display_buff; BuddyInit(NULL); /* Init de la table */ if((ht = HashTable_Init(hparam)) == NULL) { LogTest("Test FAILED: Bad init"); exit(1); } MesureTemps(&debut, NULL); LogTest("Created the table"); for(i = 0; i < MAXTEST; i++) { sprintf(strtab[i], "%d", i); buffkey.len = strlen(strtab[i]); buffkey.pdata = strtab[i]; buffval.len = strlen(strtab[i]); buffval.pdata = strtab[i]; rc = HashTable_Set(ht, &buffkey, &buffval); LogFullDebug(COMPONENT_HASHTABLE,"Added %s , %d , return = %d", strtab[i], i, rc); } MesureTemps(&fin, &debut); LogTest("Time to insert %d entries: %s", MAXTEST, ConvertiTempsChaine(fin, NULL)); LogFullDebug(COMPONENT_HASHTABLE, "-----------------------------------------"); HashTable_Log(COMPONENT_HASHTABLE,ht); LogTest("========================================="); /* Premier test simple: verif de la coherence des valeurs lues */ critere_recherche = CRITERE; sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; MesureTemps(&debut, NULL); rc = HashTable_Get(ht, &buffkey, &buffval); MesureTemps(&fin, &debut); LogTest("Recovery of %d th key ->%d", critere_recherche, rc); LogTest("Time to recover = %s", ConvertiTempsChaine(fin, NULL)); if(rc != HASHTABLE_SUCCESS) { LogTest("Test FAILED: The key is not found"); exit(1); } sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; MesureTemps(&debut, NULL); rc = HashTable_Get(ht, &buffkey, &buffval); MesureTemps(&fin, &debut); LogTest("Recovery of %d th key (test 2) -> %s", critere_recherche, rc); LogTest("Time to recover = %s", ConvertiTempsChaine(fin, NULL)); if(rc != HASHTABLE_SUCCESS) { LogTest("Test FAILED: The key is not found (test 2)"); exit(1); } LogTest("----> retrieved value = len %d ; val = %s", buffval.len, buffval.pdata); val = atoi(buffval.pdata); if(val != critere_recherche) { LogTest("Test FAILED: the reading is incorrect"); exit(1); } LogTest("Now, I try to retrieve %d entries (taken at random, almost)", MAXGET); MesureTemps(&debut, NULL); for(i = 0; i < MAXGET; i++) { random_val = random() % MAXTEST; sprintf(tmpstr, "%d", random_val); buffkey2.len = strlen(tmpstr); buffkey2.pdata = tmpstr; rc = HashTable_Get(ht, &buffkey2, &buffval2); LogFullDebug(COMPONENT_HASHTABLE,"\tPlaying key = %s --> %s", buffkey2.pdata, buffval2.pdata); if(rc != HASHTABLE_SUCCESS) { LogTest("Error reading %d = %d", i, rc); LogTest("Test FAILED: the reading is incorrect"); exit(1); } } MesureTemps(&fin, &debut); LogTest("Time to read %d elements = %s", MAXGET, ConvertiTempsChaine(fin, NULL)); LogTest("-----------------------------------------"); sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Del(ht, &buffkey, NULL, NULL); LogTest("Deleting the key %d --> %d", critere_recherche, rc); if(rc != HASHTABLE_SUCCESS) { LogTest("Test FAILED: delete incorrect"); exit(1); } LogTest("========================================="); sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Del(ht, &buffkey, NULL, NULL); LogTest("Deleting the key %d (2nd try) --> %d", critere_recherche, rc); if(rc != HASHTABLE_ERROR_NO_SUCH_KEY) { printf("Test FAILED: delete incorrect"); exit(1); } LogTest("========================================="); sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Get(ht, &buffkey, &buffval); LogTest ("Recovery of the %d key (erased) (must return HASH_ERROR_NO_SUCH_KEY) = %d --> %d", critere_recherche, HASHTABLE_ERROR_NO_SUCH_KEY, rc); if(rc != HASHTABLE_ERROR_NO_SUCH_KEY) { LogTest("Test FAILED: the reading is incorrect"); exit(1); } LogTest("-----------------------------------------"); LogTest ("Destruction of %d items, taken at random (well if you want ... I use srandom)", MAXDESTROY); srandom(getpid()); random_val = random() % MAXTEST; MesureTemps(&debut, NULL); for(i = 0; i < MAXDESTROY; i++) { /* it used to be that the random values were chosen with repeated calls to random(), but if the same key comes up twice, that causes a fail. This way we start with a random value and just linearly delete from it */ random_val = (random_val + 1) % MAXTEST; sprintf(tmpstr, "%d", random_val); LogTest("\t Delete %d", random_val); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Del(ht, &buffkey, NULL, NULL); if(rc != HASHTABLE_SUCCESS) { LogTest("Error on delete %d = %d", i, rc); LogTest("Test FAILED: delete incorrect"); exit(1); } } MesureTemps(&fin, &debut); LogTest("Time to delete %d elements = %s", MAXDESTROY, ConvertiTempsChaine(fin, NULL)); LogTest("-----------------------------------------"); LogTest("Now, I try to retrieve %d entries (if necessary destroyed)", MAXGET); MesureTemps(&debut, NULL); for(i = 0; i < MAXGET; i++) { random_val = random() % MAXTEST; sprintf(tmpstr, "%d", random_val); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Get(ht, &buffkey, &buffval); } MesureTemps(&fin, &debut); LogTest("Tie to read %d elements = %s", MAXGET, ConvertiTempsChaine(fin, NULL)); LogTest("-----------------------------------------"); LogTest("Writing a duplicate key "); sprintf(tmpstr, "%d", CRITERE_2); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Test_And_Set(ht, &buffkey, &buffval, HASHTABLE_SET_HOW_SET_NO_OVERWRITE); LogTest("The value should be HASHTABLE_ERROR_KEY_ALREADY_EXISTS = %d --> %d", HASHTABLE_ERROR_KEY_ALREADY_EXISTS, rc); if(rc != HASHTABLE_ERROR_KEY_ALREADY_EXISTS) { LogTest("Test FAILED: duplicate key"); exit(1); } LogTest("-----------------------------------------"); HashTable_Log(COMPONENT_HASHTABLE,ht); LogFullDebug(COMPONENT_HASHTABLE,"-----------------------------------------"); LogTest("Displaying table statistics "); HashTable_GetStats(ht, &statistiques); LogTest(" Number of entries = %d", statistiques.dynamic.nb_entries); LogTest(" Successful operations : Set = %d, Get = %d, Del = %d, Test = %d", statistiques.dynamic.ok.nb_set, statistiques.dynamic.ok.nb_get, statistiques.dynamic.ok.nb_del, statistiques.dynamic.ok.nb_test); LogTest(" Failed operations : Set = %d, Get = %d, Del = %d, Test = %d", statistiques.dynamic.err.nb_set, statistiques.dynamic.err.nb_get, statistiques.dynamic.err.nb_del, statistiques.dynamic.err.nb_test); LogTest(" Operations 'NotFound': Set = %d, Get = %d, Del = %d, Test = %d", statistiques.dynamic.notfound.nb_set, statistiques.dynamic.notfound.nb_get, statistiques.dynamic.notfound.nb_del, statistiques.dynamic.notfound.nb_test); LogTest (" Calculated statistics: min_rbt_node = %d, max_rbt_node = %d, average_rbt_node = %d", statistiques.computed.min_rbt_num_node, statistiques.computed.max_rbt_num_node, statistiques.computed.average_rbt_num_node); /* Test sur la pertinence des valeurs de statistiques */ if(statistiques.dynamic.ok.nb_set != MAXTEST) { LogTest("Test FAILED: Incorrect statistics: ok.nb_set "); exit(1); } if(statistiques.dynamic.ok.nb_get + statistiques.dynamic.notfound.nb_get != 2 * MAXGET + 3) { LogTest("Test FAILED: Incorrect statistics: *.nb_get "); exit(1); } if(statistiques.dynamic.ok.nb_del != MAXDESTROY + 1 || statistiques.dynamic.notfound.nb_del != 1) { LogTest("Test ECHOUE : statistiques incorrectes: *.nb_del "); exit(1); } if(statistiques.dynamic.err.nb_test != 1) { LogTest("Test ECHOUE : statistiques incorrectes: err.nb_test "); exit(1); } /* Tous les tests sont ok */ BuddyDumpMem(stdout); LogTest("\n-----------------------------------------"); LogTest("Test succeeded: all tests pass successfully"); exit(0); }
int main(int argc, char *argv[]) { SetDefaultLogging("TEST"); SetNamePgm("test_libcmc_bugdelete"); LogTest("Initialized test program"); hash_table_t *ht = NULL; hash_parameter_t hparam; hash_buffer_t buffval; hash_buffer_t buffkey; hash_buffer_t buffval2; hash_buffer_t buffkey2; hash_stat_t statistiques; int i; int rc; struct Temps debut, fin; char tmpstr[10]; char strtab[MAXTEST][10]; int critere_recherche = 0; int random_val = 0; hparam.index_size = PRIME; hparam.alphabet_length = 10; hparam.nb_node_prealloc = NB_PREALLOC; hparam.hash_func_key = simple_hash_func; hparam.hash_func_rbt = rbt_hash_func; hparam.hash_func_both = NULL ; /* BUGAZOMEU */ hparam.compare_key = compare_string_buffer; hparam.key_to_str = display_buff; hparam.val_to_str = display_buff; BuddyInit(NULL); /* Init de la table */ if((ht = HashTable_Init(hparam)) == NULL) { LogTest("Test FAILED: Bad init"); exit(1); } MesureTemps(&debut, NULL); LogTest("Created hash table"); for(i = 0; i < MAXTEST; i++) { sprintf(strtab[i], "%d", i); buffkey.len = strlen(strtab[i]); buffkey.pdata = strtab[i]; buffval.len = strlen(strtab[i]); buffval.pdata = strtab[i]; rc = HashTable_Set(ht, &buffkey, &buffval); LogFullDebug(COMPONENT_HASHTABLE, "Added %s , %d , return code = %d", strtab[i], i, rc); } MesureTemps(&fin, &debut); LogTest("Time to insert %d entries: %s", MAXTEST, ConvertiTempsChaine(fin, NULL)); LogFullDebug(COMPONENT_HASHTABLE, "-----------------------------------------"); HashTable_Log(COMPONENT_HASHTABLE, ht); LogFullDebug(COMPONENT_HASHTABLE, "========================================="); /* Premier test simple: verif de la coherence des valeurs lues */ critere_recherche = CRITERE; sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; MesureTemps(&debut, NULL); rc = HashTable_Get(ht, &buffkey, &buffval); MesureTemps(&fin, &debut); LogTest("Now, I try to retrieve %d entries (taken at random, almost)", MAXGET); MesureTemps(&debut, NULL); for(i = 0; i < MAXGET; i++) { random_val = random() % MAXTEST; sprintf(tmpstr, "%d", random_val); buffkey2.len = strlen(tmpstr); buffkey2.pdata = tmpstr; rc = HashTable_Get(ht, &buffkey2, &buffval2); LogTest("\tPlaying key = %s --> %s", buffkey2.pdata, buffval2.pdata); if(rc != HASHTABLE_SUCCESS) { LogTest("Error reading %d = %d", i, rc); LogTest("Test FAILED: the reading is incorrect"); exit(1); } } MesureTemps(&fin, &debut); LogTest("Time to read elements %d = %s", MAXGET, ConvertiTempsChaine(fin, NULL)); LogTest("-----------------------------------------"); sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; sprintf(tmpstr, "%d", critere_recherche); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; srandom(getpid()); MesureTemps(&debut, NULL); for(i = 0; i < MAXDESTROY; i++) { random_val = bugdelete_key_array[i]; sprintf(tmpstr, "%d", random_val); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; LogFullDebug(COMPONENT_HASHTABLE, "\t Erase %u -> %lu | %lu", random_val, simple_hash_func(&hparam, &buffkey), rbt_hash_func(&hparam, &buffkey)); rc = HashTable_Del(ht, &buffkey, NULL, NULL); if(rc != HASHTABLE_SUCCESS) { LogTest("Erreur lors de la destruction de %d = %d", random_val, rc); LogTest("Test FAILED: delete incorrect"); exit(1); } } MesureTemps(&fin, &debut); LogTest("Time to delete %d elements = %s", MAXDESTROY, ConvertiTempsChaine(fin, NULL)); LogTest("-----------------------------------------"); LogTest("Now, I try to retrieve %d entries (possibly destroyed)", MAXGET); MesureTemps(&debut, NULL); for(i = 0; i < MAXGET; i++) { random_val = random() % MAXTEST; sprintf(tmpstr, "%d", random_val); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Get(ht, &buffkey, &buffval); } MesureTemps(&fin, &debut); LogTest("Time to read %d elements = %s", MAXGET, ConvertiTempsChaine(fin, NULL)); LogTest("-----------------------------------------"); LogTest("Writing a duplicated key"); sprintf(tmpstr, "%d", CRITERE_2); buffkey.len = strlen(tmpstr); buffkey.pdata = tmpstr; rc = HashTable_Test_And_Set(ht, &buffkey, &buffval, HASHTABLE_SET_HOW_SET_NO_OVERWRITE); LogTest("The value must be HASHTABLE_ERROR_KEY_ALREADY_EXISTS = %d --> %d", HASHTABLE_ERROR_KEY_ALREADY_EXISTS, rc); if(rc != HASHTABLE_ERROR_KEY_ALREADY_EXISTS) { LogTest("Test ECHOUE : Clef redondante"); exit(1); } LogTest("-----------------------------------------"); HashTable_Log(COMPONENT_HASHTABLE,ht); LogFullDebug(COMPONENT_HASHTABLE,"-----------------------------------------"); LogTest("Displaying table statistics"); HashTable_GetStats(ht, &statistiques); LogTest(" Number of Entrees = %d", statistiques.dynamic.nb_entries); LogTest(" Successful operations : Set = %d, Get = %d, Del = %d, Test = %d", statistiques.dynamic.ok.nb_set, statistiques.dynamic.ok.nb_get, statistiques.dynamic.ok.nb_del, statistiques.dynamic.ok.nb_test); LogTest(" Failed operations : Set = %d, Get = %d, Del = %d, Test = %d", statistiques.dynamic.err.nb_set, statistiques.dynamic.err.nb_get, statistiques.dynamic.err.nb_del, statistiques.dynamic.err.nb_test); LogTest(" Operations 'NotFound': Set = %d, Get = %d, Del = %d, Test = %d", statistiques.dynamic.notfound.nb_set, statistiques.dynamic.notfound.nb_get, statistiques.dynamic.notfound.nb_del, statistiques.dynamic.notfound.nb_test); LogTest(" Statistics computed: min_rbt_node = %d, max_rbt_node = %d, average_rbt_node = %d", statistiques.computed.min_rbt_num_node, statistiques.computed.max_rbt_num_node, statistiques.computed.average_rbt_num_node); /* Test sur la pertinence des valeurs de statistiques */ if(statistiques.dynamic.ok.nb_set != MAXTEST) { LogTest("Test FAILED: Incorrect statistics: ok.nb_set "); exit(1); } if(statistiques.dynamic.ok.nb_get + statistiques.dynamic.notfound.nb_get != 2 * MAXGET + 1) { LogTest("Test FAILED: Incorrect statistics: *.nb_get. Expected %d, got %d", 2 * MAXGET + 1, statistiques.dynamic.ok.nb_get + statistiques.dynamic.notfound.nb_get); exit(1); } if(statistiques.dynamic.ok.nb_del != MAXDESTROY) { LogTest("Test FAILED: Incorrect statistics: *.nb_del. Expected %d, got %d", MAXDESTROY, statistiques.dynamic.ok.nb_del); exit(1); } if(statistiques.dynamic.notfound.nb_del != 0) { LogTest("Test FAILED: Incorrect statistics: *.nb_del. Expected %d, got %d", 0, statistiques.dynamic.notfound.nb_del); exit(1); } if(statistiques.dynamic.err.nb_test != 1) { LogTest("Test FAILED: Incorrect statistics: err.nb_test "); exit(1); } /* Tous les tests sont ok */ BuddyDumpMem(stdout); LogTest("\n-----------------------------------------"); LogTest("Test succeeded: all tests pass successfully"); exit(0); }