int set_add(set *s,char* key,int klen,double score) { int ret; double exp; vr_object *obj; obj = dict_get(&s->set_dict,key,klen,&exp); if( obj == NULL) { ret = dict_add_double(&s->set_dict,key,klen,score,VR_FLAG_NONE,-1); skip_list_insert(&s->set_list,score,key,klen); if(ret != VR_ERR_OK) printf("Fatal : Key which is not supposed to exists, does exist\n"); s->len = s->len + 1; //printf("set len = %d value = %lf\n",s->len,score); } else { if(VR_EQ(score,obj->value)) return VR_ERR_EXIST; skip_list_delete_with_key(&s->set_list,obj->value,key,klen); ret = dict_add_double(&s->set_dict,key,klen,score,VR_FLAG_NONE,-1); skip_list_insert(&s->set_list,score,key,klen); if(ret != VR_ERR_EXIST) printf("Fatal : Key which is supposed to exist, does not exist\n"); } return ret; }
static gint skip_list_insert_random(skip_list_t* list) { gint result = g_random_int_range(0, 100); skip_list_insert(list, result, GINT_TO_POINTER(result)); return result; }
int main() { g_type_init(); if (!g_thread_supported ()) g_thread_init (NULL); g_print("Testing skip lists"); skip_list_t *list = skip_list_new(8, 0.65); skip_list_t *list2 = skip_list_new(6, 0.3); /* for-each test */ int i; for (i = 0; i < 50; ++i) { gint key = skip_list_insert_random(list); skip_list_insert(list2, key, GINT_TO_POINTER(key)); } skip_list_foreach (list, (GFunc)assert_present, list2); g_print("..."); for (i = 0; i < 50; ++i) { gint next = skip_list_insert_random(list); gint popped = skip_list_pop_first(list); } g_assert(skip_list_self_consistent(list)); /* pop test */ for (i = 0; i < 500; ++i) { gint next = skip_list_insert_random(list); gint popped = GPOINTER_TO_INT(skip_list_pop(list, next)); g_assert(popped == next); } g_assert(skip_list_self_consistent(list)); g_print("..."); /* lookup test */ for (i = 0; i < 500; ++i) { gint next = skip_list_insert_random(list); gint looked = GPOINTER_TO_INT(skip_list_lookup(list, next)); g_assert(looked == next); } g_assert(skip_list_self_consistent(list)); g_print("..."); g_print("OK\n"); g_print("Testing skiplist thread safety"); GError *error = NULL; g_thread_create((GThreadFunc)skip_list_jitter, list, FALSE, &error); g_assert(error == NULL); static const int n_trial = 500; gint n_success = 0; for (i = 0; i < n_trial; ++i) { g_usleep(10000); g_assert(skip_list_length(list) < (jitter_length_min + 5)); gint key = g_random_int_range(0, 100); gpointer retrieve = skip_list_lookup(list, key); g_assert((retrieve == NULL) || (GPOINTER_TO_INT(retrieve) == key)); if (retrieve != NULL) ++n_success; if ((i % (n_trial / 20)) == 0) g_print("."); } /* chances of _no_ successes are vanishingly small */ g_assert(n_success > 0); g_print("OK (%d / %d)\n", n_success, n_trial); return 0; }