int st_delete_safe(register st_table *table, register st_data_t *key, st_data_t *value, st_data_t never) { unsigned int hash_val; register st_table_entry *ptr; if (table->entries_packed) { st_index_t i; for (i = 0; i < table->num_entries; i++) { if ((st_data_t)table->bins[i*2] == *key) { if (value != 0) *value = (st_data_t)table->bins[i*2+1]; table->bins[i*2] = (void *)never; return 1; } } if (value != 0) *value = 0; return 0; } hash_val = do_hash_bin(*key, table); ptr = table->bins[hash_val]; for (; ptr != 0; ptr = ptr->next) { if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) { REMOVE_ENTRY(table, ptr); *key = ptr->key; if (value != 0) *value = ptr->record; ptr->key = ptr->record = never; return 1; } } if (value != 0) *value = 0; return 0; }
int cocoa_st_foreach(cocoa_st_table *table, enum cocoa_st_retval (*func)(ANYARGS), cocoa_st_data_t arg) { cocoa_st_table_entry *ptr, **last, *tmp; enum cocoa_st_retval retval; cocoa_st_index_t i; if ((ptr = table->head) != 0) { do { i = ptr->hash % table->num_bins; retval = (*func)(ptr->key, ptr->record, (void*)arg); switch (retval) { case COCOA_ST_CHECK: /* check if hash is modified during iteration */ for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) { if (!tmp) { /* call func with error notice */ retval = (*func)(0, 0, arg, 1); return 1; } } /* fall through */ default: case COCOA_ST_CONTINUE: ptr = ptr->fore; break; case COCOA_ST_STOP: return 0; case COCOA_ST_DELETE: last = &table->bins[ptr->hash % table->num_bins]; for (; (tmp = *last) != 0; last = &tmp->next) { if (ptr == tmp) { tmp = ptr->fore; *last = ptr->next; REMOVE_ENTRY(table, ptr); free(ptr); if (ptr == tmp) return 0; ptr = tmp; break; } } } } while (ptr && table->head); } return 0; }
int cocoa_st_delete(register cocoa_st_table *table, register cocoa_st_data_t *key, cocoa_st_data_t *value) { cocoa_st_index_t hash_val; cocoa_st_table_entry **prev; register cocoa_st_table_entry *ptr; hash_val = do_hash_bin(*key, table); for (prev = &table->bins[hash_val]; (ptr = *prev) != 0; prev = &ptr->next) { if (EQUAL(table, *key, ptr->key)) { *prev = ptr->next; REMOVE_ENTRY(table, ptr); if (value != 0) *value = ptr->record; *key = ptr->key; free(ptr); return 1; } } if (value != 0) *value = 0; return 0; }
int st_delete_safe(register st_table *table, register st_data_t *key, st_data_t *value, st_data_t never) { unsigned int hash_val; register st_table_entry *ptr; hash_val = do_hash_bin(*key, table); ptr = table->bins[hash_val]; for (; ptr != 0; ptr = ptr->next) { if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) { REMOVE_ENTRY(table, ptr); *key = ptr->key; if (value != 0) *value = ptr->record; ptr->key = ptr->record = never; return 1; } } if (value != 0) *value = 0; return 0; }
int st_delete(register st_table *table, register st_data_t *key, st_data_t *value) { unsigned int hash_val; st_table_entry **prev; register st_table_entry *ptr; if (table->entries_packed) { int i; for (i = 0; i < table->num_entries; i++) { if ((st_data_t)table->bins[i*2] == *key) { if (value != 0) *value = (st_data_t)table->bins[i*2+1]; table->num_entries--; memmove(&table->bins[i*2], &table->bins[(i+1)*2], sizeof(struct st_table_entry*) * 2*(table->num_entries-i)); return 1; } } if (value != 0) *value = 0; return 0; } hash_val = do_hash_bin(*key, table); for (prev = &table->bins[hash_val]; (ptr = *prev) != 0; prev = &ptr->next) { if (EQUAL(table, *key, ptr->key)) { *prev = ptr->next; REMOVE_ENTRY(table, ptr); if (value != 0) *value = ptr->record; *key = ptr->key; free(ptr); return 1; } } if (value != 0) *value = 0; return 0; }
/* fall through */ case ST_CONTINUE: ptr = ptr->fore; break; case ST_STOP: return 0; case ST_DELETE: last = &table->bins[ptr->hash % table->num_bins]; for (; (tmp = *last) != 0; last = &tmp->next) { if (ptr == tmp) { tmp = ptr->fore; *last = ptr->next; REMOVE_ENTRY(table, ptr); free(ptr); if (ptr == tmp) return 0; ptr = tmp; break; } } } } while (ptr && table->head); } return 0; } #if 0 /* unused right now */ int st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) { st_table_entry *ptr, **last, *tmp; enum st_retval retval; int i; if (table->entries_packed) { for (i = table->num_entries-1; 0 <= i; i--) { int j; st_data_t key, val; key = (st_data_t)table->bins[i*2]; val = (st_data_t)table->bins[i*2+1]; retval = (*func)(key, val, arg); switch (retval) { case ST_CHECK: /* check if hash is modified during iteration */ for (j = 0; j < table->num_entries; j++) { if ((st_data_t)table->bins[j*2] == key) break; } if (j == table->num_entries) { /* call func with error notice */ retval = (*func)(0, 0, arg, 1); return 1; } /* fall through */ case ST_CONTINUE: break; case ST_STOP: return 0; case ST_DELETE: table->num_entries--; memmove(&table->bins[i*2], &table->bins[(i+1)*2], sizeof(struct st_table_entry*) * 2*(table->num_entries-i)); break; } } return 0; } if ((ptr = table->head) != 0) { ptr = ptr->back; do { retval = (*func)(ptr->key, ptr->record, arg, 0); switch (retval) { case ST_CHECK: /* check if hash is modified during iteration */ i = ptr->hash % table->num_bins; for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) { if (!tmp) { /* call func with error notice */ retval = (*func)(0, 0, arg, 1); return 1; } } /* fall through */ case ST_CONTINUE: ptr = ptr->back; break; case ST_STOP: return 0; case ST_DELETE: last = &table->bins[ptr->hash % table->num_bins]; for (; (tmp = *last) != 0; last = &tmp->next) { if (ptr == tmp) { tmp = ptr->back; *last = ptr->next; REMOVE_ENTRY(table, ptr); free(ptr); ptr = tmp; break; } } ptr = ptr->next; free(tmp); table->num_entries--; } } while (ptr && table->head); } return 0; }