void test_order_is_not_fetchable_after_delete() { fh_shr_lkp_tbl_t *table = valid_table(); fh_shr_lkp_ord_t *entry; FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, valid_entry(), &entry), (int)FH_OK); FH_TEST_ASSERT_EQUAL(table->count, 1); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_del(table, valid_key(), &entry), (int)FH_OK); FH_TEST_ASSERT_EQUAL(table->count, 0); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_get(table, valid_key(), &entry), (int)FH_ERR_NOTFOUND); }
/* * Remove deleted records and double the table size */ static void strmap_extend(strmap_t *hmap) { strmap_rec_t *r, *tmp; uint32_t i, n, n2, mask; n = hmap->size; n2 = n << 1; if (n2 >= STRMAP_MAX_SIZE) { out_of_memory(); } tmp = (strmap_rec_t *) safe_malloc(n2 * sizeof(strmap_rec_t)); for (i=0; i<n2; i++) { tmp[i].key = NULL; } mask = n2 - 1; r = hmap->data; for (i=0; i<n; i++) { if (valid_key(r->key)) { strmap_clean_copy(tmp, r, mask); } r ++; } safe_free(hmap->data); hmap->data = tmp; hmap->size = n2; hmap->ndeleted = 0; hmap->resize_threshold = (uint32_t) (n2 * STRMAP_RESIZE_RATIO); hmap->cleanup_threshold = (uint32_t) (n2 * STRMAP_CLEANUP_RATIO); }
void test_deleting_a_nonexistent_order_produces_correct_status() { fh_shr_lkp_tbl_t *table = valid_table(); fh_shr_lkp_ord_t *entry; FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_del(table, valid_key(), &entry), (int)FH_ERR_NOTFOUND); FH_TEST_ASSERT_NULL(entry); FH_TEST_ASSERT_EQUAL(table->count, 0); }
void test_deleting_an_existing_order_decrements_count() { fh_shr_lkp_tbl_t *table = valid_table(); fh_shr_lkp_ord_t *entry; FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, valid_entry(), &entry), (int)FH_OK); FH_TEST_ASSERT_EQUAL(table->count, 1); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_del(table, valid_key(), &entry), (int)FH_OK); FH_TEST_ASSERT_EQUAL(table->count, 0); }
void test_fetch_returns_same_pointer_as_add() { fh_shr_lkp_ord_t *addentry, *getentry; fh_shr_lkp_tbl_t *table = valid_table(); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, valid_entry(), &addentry), (int)FH_OK); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_get(table, valid_key(), &getentry), (int)FH_OK); FH_TEST_ASSERT_LEQUAL((unsigned long)addentry, (unsigned long)getentry); }
void test_modified_entry_persists_after_refetching() { fh_shr_lkp_ord_t *tblentry; fh_shr_lkp_tbl_t *table = valid_table(); fh_shr_lkp_ord_t *entry = valid_entry(); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, entry, &tblentry), (int)FH_OK); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_get(table, valid_key(), &tblentry), (int)FH_OK); tblentry->shares = 200; FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_get(table, valid_key(), &tblentry), (int)FH_OK); FH_TEST_ASSERT_LEQUAL(tblentry->order_no, entry->order_no); FH_TEST_ASSERT_LEQUAL(tblentry->price, entry->price); FH_TEST_ASSERT_EQUAL(tblentry->shares, 200); FH_TEST_ASSERT_EQUAL(tblentry->buy_sell_ind, entry->buy_sell_ind); FH_TEST_ASSERT_STREQUAL(tblentry->stock, entry->stock); FH_TEST_ASSERT_EQUAL(table->count, 1); }
/* * Iterator: apply f(aux, r) to all records r in the table */ void strmap_iterate(strmap_t *hmap, void *aux, strmap_iterator_t f) { uint32_t i, n; strmap_rec_t *r; n = hmap->size; r = hmap->data; for (i=0; i<n; i++) { if (valid_key(r->key)) { f(aux, r); } r ++; } }
/* * Delete: call decref on all keys */ void delete_strmap(strmap_t *hmap) { uint32_t i, n; char *key; n = hmap->size; for (i=0; i<n; i++) { key = hmap->data[i].key; if (valid_key(key)) { string_decref(key); } } safe_free(hmap->data); hmap->data = NULL; }
/* * Empty the table */ void reset_strmap(strmap_t *hmap) { uint32_t i, n; char *key; n = hmap->size; for (i=0; i<n; i++) { key = hmap->data[i].key; hmap->data[i].key = NULL; if (valid_key(key)) { string_decref(key); } } hmap->nelems = 0; hmap->ndeleted = 0; }
/* * Find or create record with the given key * - set is_new to true if that's a new record * - set is_new to false otherwise */ strmap_rec_t *strmap_get(strmap_t *hmap, const char *key, bool *is_new) { uint32_t mask, i, h; strmap_rec_t *d, *aux; char *clone; assert(is_power_of_two(hmap->size) && hmap->nelems + hmap->ndeleted < hmap->size); mask = hmap->size - 1; h = jenkins_hash_string(key); i = h & mask; for (;;) { d = hmap->data + i; if (! valid_key(d->key)) break; if (d->hash == h && strcmp(d->key, key) == 0) goto found; i ++; i &= mask; } aux = d; // this is where the new record will go if needed while(d->key != NULL) { i ++; i &= mask; if (d->key != DELETED_KEY && d->hash == h && strcmp(d->key, key) == 0) goto found; } // not found: add a new record hmap->nelems ++; clone = clone_string(key); string_incref(clone); if (hmap->nelems + hmap->ndeleted > hmap->resize_threshold) { // resize: we can't use the current aux strmap_extend(hmap); aux = strmap_get_clean(hmap, h); } aux->key = clone; aux->hash = h; aux->val = 0; *is_new = true; return aux; found: *is_new = false; return d; }
/* * Remove the deleted records */ static void strmap_cleanup(strmap_t *hmap) { strmap_rec_t *r, *tmp; uint32_t i, n, mask; n = hmap->size; tmp = (strmap_rec_t *) safe_malloc(n * sizeof(strmap_rec_t)); for (i=0; i<n; i++) { tmp[i].key = NULL; } mask = n - 1; r = hmap->data; for (i=0; i<n; i++) { if (valid_key(r->key)) { strmap_clean_copy(tmp, r, mask); } r ++; } safe_free(hmap->data); hmap->data = tmp; hmap->ndeleted = 0; }
int control_menu(t_event *e) { if (e->keys[125] || e->keys[1]) { e->menu_select++; e->menu_select = e->menu_select % 3; e->keys[125] = 0; e->keys[1] = 0; } if (e->keys[126] || e->keys[13]) { e->menu_select--; if (e->menu_select < 0) e->menu_select += 3; e->keys[126] = 0; e->keys[13] = 0; } if (e->keys[36]) { valid_key(e); e->keys[36] = 0; } return (1); }
/**************************************************************************** *** FUNCTIONS *** ****************************************************************************/ static am_node * amfs_lookup_node(am_node *mp, char *fname, int *error_return) { am_node *new_mp; int error = 0; /* Error so far */ int in_progress = 0; /* # of (un)mount in progress */ mntfs *mf; char *expanded_fname = NULL; dlog("in amfs_lookup_node"); /* * If the server is shutting down * then don't return information * about the mount point. */ if (amd_state == Finishing) { if (mp->am_al == NULL || mp->am_al->al_mnt == NULL || mp->am_al->al_mnt->mf_fsflags & FS_DIRECT) { dlog("%s mount ignored - going down", fname); } else { dlog("%s/%s mount ignored - going down", mp->am_path, fname); } ereturn(ENOENT); } /* * Handle special case of "." and ".." */ if (fname[0] == '.') { if (fname[1] == '\0') return mp; /* "." is the current node */ if (fname[1] == '.' && fname[2] == '\0') { if (mp->am_parent) { dlog(".. in %s gives %s", mp->am_path, mp->am_parent->am_path); return mp->am_parent; /* ".." is the parent node */ } ereturn(ESTALE); } } /* * Check for valid key name. * If it is invalid then pretend it doesn't exist. */ if (!valid_key(fname)) { plog(XLOG_WARNING, "Key \"%s\" contains a disallowed character", fname); ereturn(ENOENT); } /* * Expand key name. * expanded_fname is now a private copy. */ expanded_fname = expand_selectors(fname); /* * Search children of this node */ for (new_mp = mp->am_child; new_mp; new_mp = new_mp->am_osib) { if (FSTREQ(new_mp->am_name, expanded_fname)) { if (new_mp->am_error) { error = new_mp->am_error; continue; } /* * If the error code is undefined then it must be * in progress. */ mf = new_mp->am_al->al_mnt; if (mf->mf_error < 0) goto in_progrss; /* * If there was a previous error with this node * then return that error code. */ if (mf->mf_flags & MFF_ERROR) { error = mf->mf_error; continue; } if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) { in_progrss: /* * If the fs is not mounted or it is unmounting then there * is a background (un)mount in progress. In this case * we just drop the RPC request (return nil) and * wait for a retry, by which time the (un)mount may * have completed. */ dlog("ignoring mount of %s in %s -- %smounting in progress, flags %x", expanded_fname, mf->mf_mount, (mf->mf_flags & MFF_UNMOUNTING) ? "un" : "", mf->mf_flags); in_progress++; if (mf->mf_flags & MFF_UNMOUNTING) { dlog("will remount later"); new_mp->am_flags |= AMF_REMOUNT; } continue; } /* * Otherwise we have a hit: return the current mount point. */ dlog("matched %s in %s", expanded_fname, new_mp->am_path); XFREE(expanded_fname); return new_mp; } } if (in_progress) { dlog("Waiting while %d mount(s) in progress", in_progress); XFREE(expanded_fname); ereturn(-1); } /* * If an error occurred then return it. */ if (error) { dlog("Returning error: %s", strerror(error)); XFREE(expanded_fname); ereturn(error); } /* * If the server is going down then just return, * don't try to mount any more file systems */ if ((int) amd_state >= (int) Finishing) { dlog("not found - server going down anyway"); ereturn(ENOENT); } /* * Allocate a new map */ new_mp = get_ap_child(mp, expanded_fname); XFREE(expanded_fname); if (new_mp == NULL) ereturn(ENOSPC); *error_return = -1; return new_mp; }
fh_shr_cfg_tbl_t *valid_config() { static fh_shr_cfg_tbl_t config = { .name = "dummy_config", .enabled = 1, .size = 100 }; return &config; } fh_shr_lkp_tbl_t *valid_table() { static fh_shr_lkp_tbl_t table; fh_shr_lkp_ord_init(valid_config(), &table); return &table; } fh_shr_lkp_ord_t *valid_entry() { static fh_shr_lkp_ord_t entry = { .order_no = 1, .price = 1005000, .shares = 100, .buy_sell_ind = 'B', .stock = "AAPL", .sym_entry = NULL, .context = NULL }; return &entry; } fh_shr_lkp_ord_key_t *valid_key() { static fh_shr_lkp_ord_key_t key = { .order_no = 1 }; return &key; } void test_count_responds_to_entry_insertion() { fh_shr_lkp_tbl_t *table = valid_table(); fh_shr_lkp_ord_t *tblentry; FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, valid_entry(), &tblentry), (int)FH_OK); FH_TEST_ASSERT_EQUAL(table->count, 1); } void test_get_after_insertion_yields_correct_values() { fh_shr_lkp_ord_t *tblentry; fh_shr_lkp_tbl_t *table = valid_table(); fh_shr_lkp_ord_t *entry = valid_entry(); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, entry, &tblentry), (int)FH_OK); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_get(table, valid_key(), &tblentry), (int)FH_OK); FH_TEST_ASSERT_LEQUAL(tblentry->order_no, entry->order_no); FH_TEST_ASSERT_LEQUAL(tblentry->price, entry->price); FH_TEST_ASSERT_EQUAL(tblentry->shares, entry->shares); FH_TEST_ASSERT_EQUAL(tblentry->buy_sell_ind, entry->buy_sell_ind); FH_TEST_ASSERT_STREQUAL(tblentry->stock, entry->stock); FH_TEST_ASSERT_EQUAL(table->count, 1); } void test_retrieving_entry_with_freed_key_works() { fh_shr_lkp_ord_key_t *key; fh_shr_lkp_ord_t *entry; fh_shr_lkp_tbl_t *table = valid_table(); key = (fh_shr_lkp_ord_key_t *)malloc(sizeof(fh_shr_lkp_ord_key_t)); memcpy(key, valid_key(), sizeof(fh_shr_lkp_ord_key_t)); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_add(table, valid_entry(), &entry), (int)FH_OK); free(key); FH_TEST_ASSERT_EQUAL((int)fh_shr_lkp_ord_get(table, valid_key(), &entry), (int)FH_OK); FH_TEST_ASSERT_EQUAL(table->count, 1); }