/** * Resize the hashset * @internal */ static inline void resize(HashSet *self, size_t new_size) { size_t num_buckets = self->num_buckets; size_t i; HashSetEntry *old_entries = self->entries; HashSetEntry *new_entries; /* allocate a new array with double size */ new_entries = Alloc(new_size); SetRangeEmpty(new_entries, new_size); /* use the new array */ self->entries = new_entries; self->num_buckets = new_size; self->num_elements = 0; self->num_deleted = 0; #ifndef NDEBUG self->entries_version++; #endif reset_thresholds(self); /* reinsert all elements */ for(i = 0; i < num_buckets; ++i) { HashSetEntry *entry = & old_entries[i]; if(EntryIsEmpty(*entry) || EntryIsDeleted(*entry)) continue; insert_new(self, EntryGetHash(self, *entry), EntryGetValue(*entry)); } /* now we can free the old array */ Free(old_entries); }
/************************************************************************** 函数 : reverse_sort() 功能 : 将排序好的链表进行倒置 传入参数: 无 传出参数: 无 返回值 : 无 **************************************************************************/ void reverse_sort() { struct student *temp_stu = boy_head; /*用来存放取出的节点*/ struct student *temp_new = boy_head; /*用来存放下一个节点*/ while (temp_new != NULL) { temp_new = temp_stu->next; /*保存下一个节点地址*/ insert_new(temp_stu); /*插入新的链表*/ temp_stu = temp_new; /*将下一个节点地址取出*/ } }
Key PeerObject::key_for_remote(PyObject *object) noexcept { Key key; auto i = states.find(object); if (i != states.end()) key = i->second.key; else key = insert_new(object, State::DIRTY_FLAG); return key_for_remote(key); }
std::pair<Key, bool> PeerObject::insert_or_clear_for_remote(PyObject *object) noexcept { bool object_changed; Key key; auto i = states.find(object); if (i != states.end()) { object_changed = i->second.test_flag(State::DIRTY_FLAG); i->second.clear_flag(State::DIRTY_FLAG); key = i->second.key; } else { object_changed = true; key = insert_new(object, 0); } Key remote_key = key_for_remote(key); return std::make_pair(remote_key, object_changed); }
interp_list *do_split(interp_list *current) { interp_list *pointer; /* Create a new node in the list of interpretations with */ /* the same value as the current node (spine) */ current = insert_new(current); pointer = current->next_interp; strcpy(pointer->name,current->name); pointer->indicator = '*'; current->indicator = '*'; /* Keep any necessary statistics for the -v option */ if (verbose) { split_spines += 1; } return current; }
interp_list *do_add(interp_list *current) { interp_list *pointer; /* Insert a new node in the current list of nodes (interpretations) */ /* and set variables so that the next record will check for the */ /* presence of an exclusive interpretation in the appropriate spine */ current = insert_new(current); pointer = current->next_interp; strcpy(pointer->name,""); pointer->indicator = 'N'; current->indicator = '*'; new_path = TRUE; /* Keep any necessary statistics for the -v option */ if (verbose) { added_spines += 1; } return current; }
/** * Adding a member to the set requires updating both of these arrays: * this should be constant time. */ inline void insert(unsigned int i){ if (!ismember(i)){ insert_new(i); } }
int main (int argc, char **argv) { unsigned int i; unsigned int k; unsigned int table_size[] = {1, 2, 3, 4, 5, 23, 53}; Hash_table *ht; Hash_tuning tuning; hash_reset_tuning (&tuning); tuning.shrink_threshold = 0.3; tuning.shrink_factor = 0.707; tuning.growth_threshold = 1.5; tuning.growth_factor = 2.0; tuning.is_n_buckets = true; if (1 < argc) { unsigned int seed; if (get_seed (argv[1], &seed) != 0) { fprintf (stderr, "invalid seed: %s\n", argv[1]); exit (EXIT_FAILURE); } srand (seed); } for (i = 0; i < ARRAY_CARDINALITY (table_size); i++) { size_t sz = table_size[i]; ht = hash_initialize (sz, NULL, hash_pjw, hash_compare_strings, NULL); ASSERT (ht); insert_new (ht, "a"); { char *str1 = strdup ("a"); char *str2; ASSERT (str1); str2 = hash_insert (ht, str1); ASSERT (str1 != str2); ASSERT (STREQ (str1, str2)); free (str1); } insert_new (ht, "b"); insert_new (ht, "c"); i = 0; ASSERT (hash_do_for_each (ht, walk, &i) == 3); ASSERT (i == 7); { void *buf[5] = { NULL }; ASSERT (hash_get_entries (ht, NULL, 0) == 0); ASSERT (hash_get_entries (ht, buf, 5) == 3); ASSERT (STREQ (buf[0], "a") || STREQ (buf[0], "b") || STREQ (buf[0], "c")); } ASSERT (hash_delete (ht, "a")); ASSERT (hash_delete (ht, "a") == NULL); ASSERT (hash_delete (ht, "b")); ASSERT (hash_delete (ht, "c")); ASSERT (hash_rehash (ht, 47)); ASSERT (hash_rehash (ht, 467)); /* Free an empty table. */ hash_clear (ht); hash_free (ht); ht = hash_initialize (sz, NULL, hash_pjw, hash_compare_strings, NULL); ASSERT (ht); insert_new (ht, "z"); insert_new (ht, "y"); insert_new (ht, "x"); insert_new (ht, "w"); insert_new (ht, "v"); insert_new (ht, "u"); hash_clear (ht); ASSERT (hash_get_n_entries (ht) == 0); hash_free (ht); /* Test pointer hashing. */ ht = hash_initialize (sz, NULL, NULL, NULL, NULL); ASSERT (ht); { char *str = strdup ("a"); ASSERT (str); insert_new (ht, "a"); insert_new (ht, str); ASSERT (hash_lookup (ht, str) == str); free (str); } hash_free (ht); } hash_reset_tuning (&tuning); tuning.shrink_threshold = 0.3; tuning.shrink_factor = 0.707; tuning.growth_threshold = 1.5; tuning.growth_factor = 2.0; tuning.is_n_buckets = true; /* Invalid tuning. */ ht = hash_initialize (4651, &tuning, hash_pjw, hash_compare_strings, hash_freer); ASSERT (!ht); /* Alternate tuning. */ tuning.growth_threshold = 0.89; /* Run with default tuning, then with custom tuning settings. */ for (k = 0; k < 2; k++) { Hash_tuning const *tune = (k == 0 ? NULL : &tuning); /* Now, each entry is malloc'd. */ ht = hash_initialize (4651, tune, hash_pjw, hash_compare_strings, hash_freer); ASSERT (ht); for (i = 0; i < 10000; i++) { unsigned int op = rand () % 10; switch (op) { case 0: case 1: case 2: case 3: case 4: case 5: { char buf[50]; char const *p = uinttostr (i, buf); char *p_dup = strdup (p); ASSERT (p_dup); insert_new (ht, p_dup); } break; case 6: { size_t n = hash_get_n_entries (ht); ASSERT (hash_rehash (ht, n + rand () % 20)); } break; case 7: { size_t n = hash_get_n_entries (ht); size_t delta = rand () % 20; if (delta < n) ASSERT (hash_rehash (ht, n - delta)); } break; case 8: case 9: { /* Delete a random entry. */ size_t n = hash_get_n_entries (ht); if (n) { size_t kk = rand () % n; void const *p; void *v; for (p = hash_get_first (ht); kk; --kk, p = hash_get_next (ht, p)) { /* empty */ } ASSERT (p); v = hash_delete (ht, p); ASSERT (v); free (v); } break; } } ASSERT (hash_table_ok (ht)); } hash_free (ht); } return 0; }