static void __simple_checks(struct radix_tree_root *tree, unsigned long index, int tag) { unsigned long first = 0; int ret; item_check_absent(tree, index); assert(item_tag_get(tree, index, tag) == 0); item_insert(tree, index); assert(item_tag_get(tree, index, tag) == 0); item_tag_set(tree, index, tag); ret = item_tag_get(tree, index, tag); assert(ret != 0); ret = tag_tagged_items(tree, NULL, first, ~0UL, 10, tag, !tag); assert(ret == 1); ret = item_tag_get(tree, index, !tag); assert(ret != 0); ret = item_delete(tree, index); assert(ret != 0); item_insert(tree, index); ret = item_tag_get(tree, index, tag); assert(ret == 0); ret = item_delete(tree, index); assert(ret != 0); ret = item_delete(tree, index); assert(ret == 0); }
int find_existing_processes(void) { struct windowlist *wl = NULL; struct process_record *pr = NULL; unsigned int i, count; wl = (struct windowlist *) malloc(sizeof(struct windowlist)); memset(wl, 0, sizeof(struct windowlist)); EnumWindows(CountPuTTYWindows, (LPARAM) &wl->nhandles); count = wl->nhandles; if (wl->nhandles == 0) wl->handles = NULL; else { wl->handles = (HWND *) malloc(wl->nhandles * sizeof(HWND)); memset(wl->handles, 0, wl->nhandles * sizeof(HWND)); EnumWindows(EnumPuTTYWindows, (LPARAM) wl); for (i = 0; i < wl->nhandles; i++) { DWORD pid = 0, tid = 0; HANDLE hprocess; tid = GetWindowThreadProcessId(wl->handles[i], &pid); hprocess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE | PROCESS_VM_READ | SYNCHRONIZE, FALSE, pid); if (!pid || !tid || !hprocess) continue; pr = (struct process_record *) malloc(sizeof(struct process_record)); pr->pid = pid; pr->tid = tid; pr->hprocess = hprocess; pr->window = wl->handles[i]; pr->path = NULL; item_insert((void *) &process_handles, &nprocesses, hprocess); nprocesses -= 1; item_insert((void *) &process_records, &nprocesses, pr); }; free(wl->handles); }; free(wl); return count; };
HWND launch_putty(int action, char *path) { STARTUPINFO si; PROCESS_INFORMATION pi; DWORD wait; HWND pwin; struct process_record *pr; char buf[BUFSIZE]; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); memset(&pi, 0, sizeof(PROCESS_INFORMATION)); sprintf(buf, "%s -%s \"%s\"", config->putty_path, action ? "edit" : "load", path); if (!CreateProcess(config->putty_path, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return NULL; wait = WaitForInputIdle(pi.hProcess, LAUNCH_TIMEOUT); if (wait != 0) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return NULL; }; CloseHandle(pi.hThread); pwin = NULL; EnumThreadWindows(pi.dwThreadId, FindPuttyWindowCallback, (LPARAM) &pwin); if (!pwin) { CloseHandle(pi.hProcess); return NULL; }; pr = (struct process_record *) malloc(sizeof(struct process_record)); pr->pid = pi.dwProcessId; pr->tid = pi.dwThreadId; pr->hprocess = pi.hProcess; pr->window = pwin; pr->path = dupstr(path); item_insert((void *) &process_handles, &nprocesses, pi.hProcess); nprocesses -= 1; item_insert((void *) &process_records, &nprocesses, pr); return pwin; };
void cmd_list_create(struct response *rsp, struct request *req, struct command *cmd) { struct item *it; struct bstring *key = _get_key(req); struct element *reply = (struct element *)array_push(rsp->token); INCR(process_metrics, list_create); it = _add_key(rsp, key); if (it == NULL) { log_debug("command '%.*s' '%.*s' failed: cannot store", cmd->bstr.len, cmd->bstr.data, key->len, key->data); return; } /* initialize data structure */ ziplist_reset((ziplist_p)item_data(it)); it->vlen = ZIPLIST_HEADER_SIZE; /* link into index */ item_insert(it, key); rsp->type = reply->type = ELEM_STR; reply->bstr = str2bstr(RSP_OK); log_verb("command '%.*s' '%.*s' succeeded", cmd->bstr.len, cmd->bstr.data, key->len, key->data); }
static void leak_check(void) { RADIX_TREE(tree, GFP_KERNEL); item_insert(&tree, 1000000); item_delete(&tree, 1000000); item_kill_tree(&tree); }
void add_and_check(void) { RADIX_TREE(tree, GFP_KERNEL); item_insert(&tree, 44); item_check_present(&tree, 44); item_check_absent(&tree, 43); item_kill_tree(&tree); }
static void __leak_check(void) { RADIX_TREE(tree, GFP_KERNEL); printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); item_insert(&tree, 1000000); printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); item_delete(&tree, 1000000); printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); item_kill_tree(&tree); printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); }
/* * Check that tags propagate correctly when extending a tree. */ static void extend_checks(void) { RADIX_TREE(tree, GFP_KERNEL); item_insert(&tree, 43); assert(item_tag_get(&tree, 43, 0) == 0); item_tag_set(&tree, 43, 0); assert(item_tag_get(&tree, 43, 0) == 1); item_insert(&tree, 1000000); assert(item_tag_get(&tree, 43, 0) == 1); item_insert(&tree, 0); item_tag_set(&tree, 0, 0); item_delete(&tree, 1000000); assert(item_tag_get(&tree, 43, 0) != 0); item_delete(&tree, 43); assert(item_tag_get(&tree, 43, 0) == 0); /* crash */ assert(item_tag_get(&tree, 0, 0) == 1); verify_tag_consistency(&tree, 0); item_kill_tree(&tree); }
static void __simple_checks(struct radix_tree_root *tree, unsigned long index, int tag) { int ret; item_check_absent(tree, index); assert(item_tag_get(tree, index, tag) == 0); item_insert(tree, index); assert(item_tag_get(tree, index, tag) == 0); item_tag_set(tree, index, tag); ret = item_tag_get(tree, index, tag); assert(ret != 0); ret = item_delete(tree, index); assert(ret != 0); item_insert(tree, index); ret = item_tag_get(tree, index, tag); assert(ret == 0); ret = item_delete(tree, index); assert(ret != 0); ret = item_delete(tree, index); assert(ret == 0); }
void dynamic_height_check(void) { int i; RADIX_TREE(tree, GFP_KERNEL); tree_verify_min_height(&tree, 0); item_insert(&tree, 42); tree_verify_min_height(&tree, 42); item_insert(&tree, 1000000); tree_verify_min_height(&tree, 1000000); assert(item_delete(&tree, 1000000)); tree_verify_min_height(&tree, 42); assert(item_delete(&tree, 42)); tree_verify_min_height(&tree, 0); for (i = 0; i < 1000; i++) { item_insert(&tree, i); tree_verify_min_height(&tree, i); } i--; for (;;) { assert(item_delete(&tree, i)); if (i == 0) { tree_verify_min_height(&tree, 0); break; } i--; tree_verify_min_height(&tree, i); } item_kill_tree(&tree); }
/* * Check that tags propagate correctly when contracting a tree. */ static void contract_checks(void) { struct item *item; int tmp; RADIX_TREE(tree, GFP_KERNEL); tmp = 1<<RADIX_TREE_MAP_SHIFT; item_insert(&tree, tmp); item_insert(&tree, tmp+1); item_tag_set(&tree, tmp, 0); item_tag_set(&tree, tmp, 1); item_tag_set(&tree, tmp+1, 0); item_delete(&tree, tmp+1); item_tag_clear(&tree, tmp, 1); assert(radix_tree_gang_lookup_tag(&tree, (void **)&item, 0, 1, 0) == 1); assert(radix_tree_gang_lookup_tag(&tree, (void **)&item, 0, 1, 1) == 0); assert(item_tag_get(&tree, tmp, 0) == 1); assert(item_tag_get(&tree, tmp, 1) == 0); verify_tag_consistency(&tree, 0); item_kill_tree(&tree); }
static void single_check(void) { struct item *items[BATCH]; RADIX_TREE(tree, GFP_KERNEL); int ret; item_insert(&tree, 0); item_tag_set(&tree, 0, 0); ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0); assert(ret == 1); ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 1, BATCH, 0); assert(ret == 0); verify_tag_consistency(&tree, 0); verify_tag_consistency(&tree, 1); item_kill_tree(&tree); }
void __gang_check(unsigned long middle, long down, long up, int chunk, int hop) { long idx; RADIX_TREE(tree, GFP_KERNEL); middle = 1 << 30; for (idx = -down; idx < up; idx++) item_insert(&tree, middle + idx); item_check_absent(&tree, middle - down - 1); for (idx = -down; idx < up; idx++) item_check_present(&tree, middle + idx); item_check_absent(&tree, middle + up); item_gang_check_present(&tree, middle - down, up + down, chunk, hop); item_full_scan(&tree, middle - down, down + up, chunk); item_kill_tree(&tree); }
static void single_check(void) { struct item *items[BATCH]; RADIX_TREE(tree, GFP_KERNEL); int ret; unsigned long first = 0; item_insert(&tree, 0); item_tag_set(&tree, 0, 0); ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0); assert(ret == 1); ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 1, BATCH, 0); assert(ret == 0); verify_tag_consistency(&tree, 0); verify_tag_consistency(&tree, 1); ret = tag_tagged_items(&tree, NULL, first, 10, 10, 0, 1); assert(ret == 1); ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 1); assert(ret == 1); item_tag_clear(&tree, 0, 0); ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0); assert(ret == 0); item_kill_tree(&tree); }
void fp_Tree::list_insert(const vector<int> & v) { int now = 0; for(int i = 1 ; i < v.size() ; ++i) { now = item_insert(v[i] , now); } }
// 创建道具 int item_create( int actor_index, int itemkind, int itemnum, ItemOut *pOut ) { if ( actor_index < 0 || actor_index >= g_maxactornum ) return -1; if ( itemkind <= 0 || itemkind >= g_itemkindnum ) return -1; if ( itemnum <= 0 ) return -1; Item * pitem = NULL; int find_offset = 0; int remain_item = 0; int remain_count = 0; int totle_remain = 0; int item_offset; int tmpi, tmpj; int tmpmin, tmpmax; short itemtype; Actor *pActor = &g_actors[actor_index]; while ( 1 ) { // 找一个可以存放itemkind的空位置 remain_item = _item_find_empty( pActor, itemkind, &find_offset ); if ( remain_item <= 0 ) return -1; if ( totle_remain + remain_item > itemnum ) remain_item = itemnum - totle_remain; pOut[remain_count].m_item_offset = (find_offset < MAX_ACTOR_ITEMNUM) ? find_offset : find_offset - MAX_ACTOR_ITEMNUM; pOut[remain_count].m_count = remain_item; pOut[remain_count].m_itemkind = itemkind; remain_count++; find_offset++; totle_remain += remain_item; if ( totle_remain >= itemnum ) break; } for ( tmpi = 0; tmpi < remain_count; tmpi++ ) { item_offset = pOut[tmpi].m_item_offset; remain_item = pOut[tmpi].m_count; if ( item_offset >= 0 && item_offset < MAX_ACTOR_ITEMNUM ) pitem = &pActor->item[item_offset]; else continue; if ( pitem->m_num > 0 ) pitem->m_num += remain_item; else { memset( pitem, 0, sizeof(Item) ); pitem->m_kind = g_itemkind[itemkind].m_kind; pitem->m_num = remain_item; itemtype = item_gettype( pitem->m_kind ); if ( itemtype >= ITEM_TYPE_EQUIP1 && itemtype <= ITEM_TYPE_EQUIP10 ) { // 如果是装备 equip_create( actor_index, itemkind, item_offset ); } else { // 其它道具 for ( tmpj = 0; tmpj < ITEM_ABILITY_NUM; tmpj++ ) { pitem->m_ability[tmpj] = g_itemkind[itemkind].m_ability[tmpj]; tmpmin = g_itemkind[itemkind].m_value_min[tmpj]; tmpmax = g_itemkind[itemkind].m_value_max[tmpj]; if ( tmpmin == tmpmax ) pitem->m_value[tmpj] = tmpmin; else if ( tmpmax - tmpmin < 3 ) pitem->m_value[tmpj] = tmpmin + rand() % (tmpmax - tmpmin + 1); else pitem->m_value[tmpj] = tmpmin + rand() % (tmpmax - tmpmin + 1); } } // 颜色 如果颜色信息有意义,以当前为主,否则为0 if ( g_itemkind[itemkind].m_color_level >= 0 && pitem->m_color_level <= 0 ) pitem->m_color_level = g_itemkind[itemkind].m_color_level; // 插入这个数据到数据库 item_insert( actor_index, item_offset ); } } return remain_count; }
static void do_thrash(struct radix_tree_root *tree, char *thrash_state, int tag) { int insert_chunk; int delete_chunk; int tag_chunk; int untag_chunk; int total_tagged = 0; int total_present = 0; for (insert_chunk = 1; insert_chunk < THRASH_SIZE; insert_chunk *= N) for (delete_chunk = 1; delete_chunk < THRASH_SIZE; delete_chunk *= N) for (tag_chunk = 1; tag_chunk < THRASH_SIZE; tag_chunk *= N) for (untag_chunk = 1; untag_chunk < THRASH_SIZE; untag_chunk *= N) { int i; unsigned long index; int nr_inserted = 0; int nr_deleted = 0; int nr_tagged = 0; int nr_untagged = 0; int actual_total_tagged; int actual_total_present; for (i = 0; i < insert_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] != NODE_ABSENT) continue; item_check_absent(tree, index); item_insert(tree, index); assert(thrash_state[index] != NODE_PRESENT); thrash_state[index] = NODE_PRESENT; nr_inserted++; total_present++; } for (i = 0; i < delete_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] == NODE_ABSENT) continue; item_check_present(tree, index); if (item_tag_get(tree, index, tag)) { assert(thrash_state[index] == NODE_TAGGED); total_tagged--; } else { assert(thrash_state[index] == NODE_PRESENT); } item_delete(tree, index); assert(thrash_state[index] != NODE_ABSENT); thrash_state[index] = NODE_ABSENT; nr_deleted++; total_present--; } for (i = 0; i < tag_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] != NODE_PRESENT) { if (item_lookup(tree, index)) assert(item_tag_get(tree, index, tag)); continue; } item_tag_set(tree, index, tag); item_tag_set(tree, index, tag); assert(thrash_state[index] != NODE_TAGGED); thrash_state[index] = NODE_TAGGED; nr_tagged++; total_tagged++; } for (i = 0; i < untag_chunk; i++) { index = rand() % THRASH_SIZE; if (thrash_state[index] != NODE_TAGGED) continue; item_check_present(tree, index); assert(item_tag_get(tree, index, tag)); item_tag_clear(tree, index, tag); item_tag_clear(tree, index, tag); assert(thrash_state[index] != NODE_PRESENT); thrash_state[index] = NODE_PRESENT; nr_untagged++; total_tagged--; } actual_total_tagged = 0; actual_total_present = 0; for (index = 0; index < THRASH_SIZE; index++) { switch (thrash_state[index]) { case NODE_ABSENT: item_check_absent(tree, index); break; case NODE_PRESENT: item_check_present(tree, index); assert(!item_tag_get(tree, index, tag)); actual_total_present++; break; case NODE_TAGGED: item_check_present(tree, index); assert(item_tag_get(tree, index, tag)); actual_total_present++; actual_total_tagged++; break; } } gang_check(tree, thrash_state, tag); printf("%d(%d) %d(%d) %d(%d) %d(%d) / " "%d(%d) present, %d(%d) tagged\n", insert_chunk, nr_inserted, delete_chunk, nr_deleted, tag_chunk, nr_tagged, untag_chunk, nr_untagged, total_present, actual_total_present, total_tagged, actual_total_tagged); } }
void copy_tag_check(void) { RADIX_TREE(tree, GFP_KERNEL); unsigned long idx[ITEMS]; unsigned long start, end, count = 0, tagged, cur, tmp; int i; // printf("generating radix tree indices...\n"); start = rand(); end = rand(); if (start > end && (rand() % 10)) { cur = start; start = end; end = cur; } /* Specifically create items around the start and the end of the range * with high probability to check for off by one errors */ cur = rand(); if (cur & 1) { item_insert(&tree, start); if (cur & 2) { if (start <= end) count++; item_tag_set(&tree, start, 0); } } if (cur & 4) { item_insert(&tree, start-1); if (cur & 8) item_tag_set(&tree, start-1, 0); } if (cur & 16) { item_insert(&tree, end); if (cur & 32) { if (start <= end) count++; item_tag_set(&tree, end, 0); } } if (cur & 64) { item_insert(&tree, end+1); if (cur & 128) item_tag_set(&tree, end+1, 0); } for (i = 0; i < ITEMS; i++) { do { idx[i] = rand(); } while (item_lookup(&tree, idx[i])); item_insert(&tree, idx[i]); if (rand() & 1) { item_tag_set(&tree, idx[i], 0); if (idx[i] >= start && idx[i] <= end) count++; } /* if (i % 1000 == 0) putchar('.'); */ } // printf("\ncopying tags...\n"); tagged = tag_tagged_items(&tree, start, end, ITEMS, XA_MARK_0, XA_MARK_1); // printf("checking copied tags\n"); assert(tagged == count); check_copied_tags(&tree, start, end, idx, ITEMS, 0, 1); /* Copy tags in several rounds */ // printf("\ncopying tags...\n"); tmp = rand() % (count / 10 + 2); tagged = tag_tagged_items(&tree, start, end, tmp, XA_MARK_0, XA_MARK_2); assert(tagged == count); // printf("%lu %lu %lu\n", tagged, tmp, count); // printf("checking copied tags\n"); check_copied_tags(&tree, start, end, idx, ITEMS, 0, 2); verify_tag_consistency(&tree, 0); verify_tag_consistency(&tree, 1); verify_tag_consistency(&tree, 2); // printf("\n"); item_kill_tree(&tree); }
item_rstatus_e item_annex(struct item *oit, const struct bstring *key, const struct bstring *val, bool append) { item_rstatus_e status = ITEM_OK; struct item *nit = NULL; uint8_t id; uint32_t ntotal = oit->vlen + val->len; id = item_slabid(oit->klen, ntotal, oit->olen); if (id == SLABCLASS_INVALID_ID) { log_info("client error: annex operation results in oversized item with" "key size %"PRIu8" old value size %"PRIu32" and new value " "size %"PRIu32, oit->klen, oit->vlen, ntotal); return ITEM_EOVERSIZED; } if (append) { /* if it is large enough to hold the extra data and left-aligned, * which is the default behavior, we copy the delta to the end of * the existing data. Otherwise, allocate a new item and store the * payload left-aligned. */ if (id == oit->id && !(oit->is_raligned)) { cc_memcpy(item_data(oit) + oit->vlen, val->data, val->len); oit->vlen = ntotal; INCR_N(slab_metrics, item_keyval_byte, val->len); INCR_N(slab_metrics, item_val_byte, val->len); item_set_cas(oit); } else { status = _item_alloc(&nit, oit->klen, ntotal, oit->olen); if (status != ITEM_OK) { log_debug("annex failed due to failure to allocate new item"); return status; } _copy_key_item(nit, oit); nit->expire_at = oit->expire_at; nit->create_at = time_proc_sec(); item_set_cas(nit); /* value is left-aligned */ cc_memcpy(item_data(nit), item_data(oit), oit->vlen); cc_memcpy(item_data(nit) + oit->vlen, val->data, val->len); nit->vlen = ntotal; item_insert(nit, key); } } else { /* if oit is large enough to hold the extra data and is already * right-aligned, we copy the delta to the front of the existing * data. Otherwise, allocate a new item and store the payload * right-aligned, assuming more prepends will happen in the future. */ if (id == oit->id && oit->is_raligned) { cc_memcpy(item_data(oit) - val->len, val->data, val->len); oit->vlen = ntotal; INCR_N(slab_metrics, item_keyval_byte, val->len); INCR_N(slab_metrics, item_val_byte, val->len); item_set_cas(oit); } else { status = _item_alloc(&nit, oit->klen, ntotal, oit->olen); if (status != ITEM_OK) { log_debug("annex failed due to failure to allocate new item"); return status; } _copy_key_item(nit, oit); nit->expire_at = oit->expire_at; nit->create_at = time_proc_sec(); item_set_cas(nit); /* value is right-aligned */ nit->is_raligned = 1; cc_memcpy(item_data(nit) - ntotal, val->data, val->len); cc_memcpy(item_data(nit) - oit->vlen, item_data(oit), oit->vlen); nit->vlen = ntotal; item_insert(nit, key); } } log_verb("annex to it %p of id %"PRIu8", new it at %p", oit, oit->id, nit ? oit : nit); return status; }