void resman_check_watch(struct resman *rman) { struct watch_dir *wdir; unsigned int idx; unsigned int num_handles = dynarr_size(rman->watch_handles); if(!num_handles) { return; } idx = WaitForMultipleObjectsEx(num_handles, rman->watch_handles, FALSE, 0, TRUE); if(idx == WAIT_FAILED) { unsigned int err = GetLastError(); fprintf(stderr, "failed to check for file modification: %u\n", err); return; } if(idx >= WAIT_OBJECT_0 && idx < WAIT_OBJECT_0 + num_handles) { if(!(wdir = rb_find(rman->wdirbyev, rman->watch_handles[idx]))) { fprintf(stderr, "got change handle, but failed to find corresponding watch_dir!\n"); return; } handle_event(rman, rman->watch_handles[idx], wdir); /* restart the watch call */ ReadDirectoryChangesW(wdir->handle, wdir->buf, RES_BUF_SIZE, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, 0, &wdir->over, 0); } }
void BankRBTree::mergeAccount(const string& id1, const string& passwd1, const string& id2, const string& passwd2){ //find account1's position, if not exist return |NULL| string now_id1 = id1; DataNode la1 = DataNode(&now_id1, NULL); DataNode* res1 = (DataNode*)rb_find(rb_tree, &la1); if(res1 == NULL){ cout << "ID " << id1 << " not found\n"; return; } //find account2's position, if not exist return |NULL| string now_id2 = id2; DataNode la2 = DataNode(&now_id2, NULL); DataNode* res2 = (DataNode*)rb_find(rb_tree, &la2); if(res2 == NULL){ cout << "ID " << id2 << " not found\n"; return; } //verify passwd1 if(res1->second->verifyPassword(passwd1) == false){ cout << "wrong password1\n"; return; } //verify passwd2 if(res2->second->verifyPassword(passwd2) == false){ cout << "wrong password2\n"; return; } res1->second->mergeAccount(*(res2->second)); rb_delete(rb_tree, res2); }
void test_integers(void) { int i; intptr_t val; struct rb_node *node; struct rb_tree *tree = rb_create(integer_cmp, integer_free, integer_free, integer_print, integer_print); assert( rb_isempty(tree) == 1 ); srand(4545); for (i = 0; i < 10000; i++) { val = rand() % 1000000; rb_insert(tree, (void*)val, (void*)val); } srand(4545); for (i = 0; i < 10000; i++) { val = rand() % 1000000; node = rb_find(tree, (void*)val); assert(node); } { node = rb_find(tree, (void*)234324); assert(node == NULL); } assert( rb_isempty(tree) == 0 ); assert( rb_size(tree) == 10000 ); srand(4545); for (i = 0; i < 10000; i++) { val = rand() % 1000000; node = rb_find(tree, (void*)val); assert(node); rb_delete(tree, node); } assert( rb_isempty(tree) == 1 ); assert( rb_size(tree) == 0 ); rb_destroy(tree); }
void test_strings(void) { int i; char str[512]; struct rb_node *node; struct rb_tree *tree = rb_create(string_cmp, string_free, string_free, string_print, string_print); assert( rb_isempty(tree) == 1 ); srand(4545); for (i = 0; i < 10000; i++) { snprintf(str, sizeof(str), "test%d", rand() % 1000000); rb_insert(tree, strdup(str), strdup("value")); } srand(4545); for (i = 0; i < 10000; i++) { snprintf(str, sizeof(str), "test%d", rand() % 1000000); node = rb_find(tree, str); assert(node); } { node = rb_find(tree, "test46554A"); assert(node == NULL); } assert( rb_isempty(tree) == 0 ); assert( rb_size(tree) == 10000 ); srand(4545); for (i = 0; i < 10000; i++) { snprintf(str, sizeof(str), "test%d", rand() % 1000000); node = rb_find(tree, str); assert(node); rb_delete(tree, node); } assert( rb_isempty(tree) == 1 ); assert( rb_size(tree) == 0 ); rb_destroy(tree); }
static void after_queue_work(uv_work_t* req, int status) { automem_t mem; webqueuework_t * qwork = container_of(req, webqueuework_t, work); rbnode_t * n = rb_first(&qwork->request->headers); automem_init(&mem, 256); if (qwork->conn->proto == WEB_PROTO_HTTP) { if (qwork->status == 101 && qwork->request->upgrade) { webheader_t k; rbnode_t * n; const char * ver = NULL, *key = NULL; k.key = "Sec-WebSocket-Version"; if (n = rb_find(&qwork->request->headers, &k.n)) ver = container_of(n, webheader_t, n)->val; k.key = "Sec-WebSocket-Key"; if (n = rb_find(&qwork->request->headers, &k.n)) key = container_of(n, webheader_t, n)->val; if (NULL != key && NULL != ver) { ws_do_handeshake(&mem, key, strlen(key)); qwork->conn->proto = WEB_PROTO_WEBSOCKET; if (uv_is_active((uv_handle_t *)&qwork->conn->conn)) { wsparser_init(&qwork->conn->ws_parser, 13, 20480); qwork->conn->request = webrequest_get(qwork->request);//引用起来,不丢掉. } goto contents_prepare_final; } } rbnode_t * n = rb_first(&qwork->headers); automem_init_headers(&mem, qwork->status, qwork->flags); while (n) { webheader_t * h = container_of(n, webheader_t, n); automem_append_voidp(&mem, h->key, strlen(h->key)); automem_append_voidp(&mem, ": ", 2); automem_append_voidp(&mem, h->val, strlen(h->val)); automem_append_voidp(&mem, "\r\n", 2); n = rb_next(n); } automem_append_contents(&mem, qwork->mem.pdata, qwork->mem.size); } else if(qwork->conn->proto==WEB_PROTO_WEBSOCKET) { wsframe_make(&mem, WS_TEXT_FRAME, 0, qwork->mem.pdata, qwork->mem.size); } contents_prepare_final: if (0 != webconn_sendmem(qwork->conn, &mem)) { automem_uninit(&mem); } webqueuework_free(qwork); }
void ShutDownMap(dbref player, dbref mapnumber) { XCODE *xcode_obj; MAP *map; MECH *mech; int j; xcode_obj = rb_find(xcode_tree, (void *)mapnumber); if (xcode_obj) { map = (MAP *)xcode_obj; for(j = 0; j < map->first_free; j++) if(map->mechsOnMap[j] != -1) { mech = getMech(map->mechsOnMap[j]); if(mech) { notify_printf(player, "Shutting down Mech #%d and resetting map index to -1....", map->mechsOnMap[j]); mech_shutdown(GOD, (void *) mech, ""); MechLastX(mech) = 0; MechLastY(mech) = 0; MechX(mech) = 0; MechY(mech) = 0; remove_mech_from_map(map, mech); } } map->first_free = 0; notify(player, "Map Cleared"); return; } }
void * rbthash_get (rbthash_table_t *tbl, void *key, int keylen) { struct rbthash_bucket *bucket = NULL; rbthash_entry_t *entry = NULL; rbthash_entry_t searchentry = {0, }; if ((!tbl) || (!key)) return NULL; bucket = rbthash_key_bucket (tbl, key, keylen); if (!bucket) { gf_log (GF_RBTHASH, GF_LOG_ERROR, "Failed to get bucket"); return NULL; } searchentry.key = key; searchentry.keylen = keylen; LOCK (&bucket->bucketlock); { entry = rb_find (bucket->bucket, &searchentry); } UNLOCK (&bucket->bucketlock); if (!entry) return NULL; return entry->data; }
void resman_stop_watch(struct resman *rman, struct resource *res) { int i, sz; struct watch_dir *wdir; if(!res->watch_path) { return; } if(!(wdir = rb_find(rman->watchdirs, res->watch_path))) { return; } /* if there is no other reference to this watch dir, destroy it */ if(--wdir->nref <= 0) { /* find the handle in the watch_handles array and remove it */ sz = dynarr_size(rman->watch_handles); for(i=0; i<sz; i++) { if(rman->watch_handles[i] == wdir->handle) { /* swap the end for it and pop */ rman->watch_handles[i] = rman->watch_handles[sz - 1]; rman->watch_handles[sz - 1] = 0; dynarr_pop(rman->watch_handles); break; } } rb_delete(rman->wdirbyev, wdir->over.hEvent); rb_delete(rman->watchdirs, wdir->watch_path); CancelIo(wdir->handle); CloseHandle(wdir->handle); CloseHandle(wdir->over.hEvent); free(wdir->watch_path); free(wdir); res->watch_path = 0; } else { /* just remove this watch item */ if(wdir->items && wdir->items->res == res) { struct watch_item *tmp = wdir->items; wdir->items = wdir->items->next; free(tmp); } else { struct watch_item *wprev = wdir->items; struct watch_item *witem = wprev->next; while(witem) { if(witem->res == res) { struct watch_item *tmp = witem; wprev->next = witem->next; break; } witem = witem->next; } } } }
static Item *_rb_tree_find_match(QSP_ARG_DECL Container *cnt_p, const char *name) { qrb_node *tnp; tnp = rb_find(cnt_p->cnt_tree_p,name); if( tnp == NULL ) return NULL; return (Item *) tnp->data; }
int HandledCommand_sub(dbref player, dbref location, char *command) { XCODE *xcode_obj = NULL; struct SpecialObjectStruct *typeOfObject; int type; CommandsStruct *cmd; HASHTAB *damnedhash; char *tmpc, *tmpchar; int ishelp; type = WhichSpecial(location); if (type < 0 || (SpecialObjects[type].datasize > 0 && !(xcode_obj = rb_find(xcode_tree, (void *)location)))) { if(type >= 0 || !Hardcode(location) || Zombie(location)) return 0; if((type = WhichSpecialS(location)) >= 0) { if(SpecialObjects[type].datasize > 0) return 0; } else return 0; } #ifdef FAST_WHICHSPECIAL if(type > NUM_SPECIAL_OBJECTS) return 0; #endif typeOfObject = &SpecialObjects[type]; damnedhash = &SpecialCommandHash[type]; tmpc = strstr(command, " "); if(tmpc) *tmpc = 0; ishelp = !strcmp(command, "HELP"); for(tmpchar = command; *tmpchar; tmpchar++) *tmpchar = ToLower(*tmpchar); cmd = (CommandsStruct *) hashfind(command, &SpecialCommandHash[type]); if(tmpc) *tmpc = ' '; if(cmd && (type != GTYPE_MECH || (type == GTYPE_MECH && Can_Use_Command(((MECH *) xcode_obj), cmd->flag)))) { #define SKIPSTUFF(a) while (*a && *a != ' ') a++;while (*a == ' ') a++ if(cmd->helpmsg[0] != '@' || Have_MechPower(Owner(player), typeOfObject->power_needed)) { SKIPSTUFF(command); cmd->func(player, xcode_obj, command); } else notify(player, "Sorry, that command is restricted!"); return 1; } else if(ishelp) { SKIPSTUFF(command); DoSpecialObjectHelp(player, typeOfObject->type, type, location, typeOfObject->power_needed, location, command); return 1; } return 0; }
int Read(unsigned long *random_seed, param_t *params) { int read_elem; void *value; read_elem = get_random(random_seed) % params->size; value = rb_find(My_Tree, Values[read_elem]); if ((unsigned long)value == Values[read_elem]) return 0; else return 1; }
int RRead(unsigned long *random_seed, param_t *params) { long int_value; void *value; int_value = get_random(random_seed) % params->scale + 1; value = rb_find(My_Tree, int_value); if ((unsigned long)value == int_value) return 0; else return 1; }
/* * mm_malloc - Allocate a block * * If there exists a free block where the request fits, get the smallest one, segment it and allocate. * If there is no such block, increase brk. */ void* mm_malloc(size_t size) { size_t block_size, next_block_size; void *free_block, *next_block; block_size = ALIGN(HEADER_SIZE + size); block_size = block_size < MIN_BLOCK_SIZE ? MIN_BLOCK_SIZE : block_size; free_block = rb_find(block_size); if(free_block == rb_null){ // proper free block not found /* set free_block to the end of last block in heap */ free_block = mem_heap_hi() - 3; if(PREV_FREE(free_block)){ // if the last block is free /* set free_block to the last block */ free_block -= PREV_SIZE_MASKED(free_block); if(IS_IN_RB(free_block)){ rb_delete(free_block); } /* this block is smaller than request, so increase brk */ mem_sbrk(block_size - CUR_SIZE_MASKED(free_block)); }else{ // if the last block is not free mem_sbrk(block_size); } }else{ /* will be allocated, so delete from tree first */ rb_delete(free_block); /* if the block is bigger than request, segment it */ if((next_block_size = CUR_SIZE_MASKED(free_block) - block_size) > 0){ next_block = NEXT_BLOCK(free_block, block_size); CUR_SIZE(next_block) = PREV_SIZE(NEXT_BLOCK(next_block, next_block_size)) = next_block_size | 1; if(IS_IN_RB(next_block)){ rb_insert(next_block); } } } CUR_SIZE(free_block) = PREV_SIZE(NEXT_BLOCK(free_block, block_size)) = block_size; #ifdef DEBUG printf("mm_malloc(%u) called\n", size); printf("free_block = %p\n", free_block); rb_print_preorder(); printf("\n"); #endif /* DEBUG */ #ifdef CHECK if(!mm_check()){ rb_print_preorder(); exit(0); } #endif /* CHECK */ return USER_BLOCK(free_block); }
int rb_delete_key(qrb_tree *tree_p, const char *key) { qrb_node *n_p; n_p = rb_find(tree_p,key); if( n_p == NULL ){ fprintf(stderr,"rb_delete_key: failed to find key \"%s\"!?\n",key); return -1; } rb_delete(tree_p,n_p); // rb_delete frees the memory... return 0; }
void BankRBTree::transfer(const string& id, const int& money){ //find account2's position, if not exist return |NULL| string now_id = id; DataNode la2 = DataNode(&now_id, NULL); DataNode* res2 = (DataNode*)rb_find(rb_tree, &la2); if(res2 == NULL){ cout << "ID " << id << " not found, "; RecommendId rid; existRecommend(id, rid); if(rid.size() > 0) cout << rid[0]; for (int i = 1; i < rid.size(); ++i) cout << "," << rid[i]; cout << "\n"; } else{ DataNode la = DataNode(¤t_login_user, NULL); DataNode* res = (DataNode*)rb_find(rb_tree, &la); res->second->transferOut((*(res2->second)), money, lg); } }
// 获取HTTP头部信息 static int lua_webctx_server(lua_State * L) { int i, argc = lua_gettop(L); webqueuework_t * qwork = (lua_rawgeti(L, LUA_REGISTRYINDEX, WEBCTX_REF), lua_touserdata(L, -1)); if (argc > 0) { for (i = 1; i <= argc; i++) { webheader_t n; rbnode_t *r; n.key = (char *)lua_tostring(L, i); if (r = rb_find(&qwork->request->headers, &n.n)) lua_pushstring(L, container_of(r, webheader_t, n)->val); else lua_pushnil(L); } } return argc; }
void BankRBTree::deleteAccount(const string& id, const string& passwd){ //find account's position, if not exist return |NULL| string now_id = id; DataNode la = DataNode(&now_id, NULL); DataNode* res = (DataNode*)rb_find(rb_tree, &la); if(res == NULL) cout << "ID " << id << " not found\n"; else if(res->second->verifyPassword(passwd) == true){ rb_delete(rb_tree, res); cout << "success\n"; } else cout << "wrong password\n"; }
void BankRBTree::runRecommend(string id, string oid, int len, RecommendId& rid, int degree_c, int degree_a) { if (degree_c == 0 && degree_a == 0) { string now_id = id; DataNode la = DataNode(&now_id, NULL); DataNode* res = (DataNode*)rb_find(rb_tree, &la); if (res == NULL) { // it means that the id isn't exist in the bank rid.push_back(id); return; } } string tmpid; int delta = abs_num((int)oid.length() - (int)id.length()); if (degree_a > delta) { if (id.length() >= oid.length() && id.length() < MAX_STRING_SIZE) { for (char c = '0'; ; c = next_char(c)) { runRecommend(id + c, oid, id.length() + 1, rid, degree_c, degree_a - delta - 1); if (c == 'z') break; } } if (id.length() <= oid.length() && id.length() > len && id.length() > 1) { tmpid = id; tmpid.pop_back(); runRecommend(tmpid, oid, len, rid, degree_c, degree_a - delta - 1); } } if (degree_c > 0) { for (int i = max_num(min_num(id.length(), oid.length()) - degree_c, len); i < min_num(oid.length(), id.length()); i++) { if (degree_c >= min_num(oid.length(), id.length()) - i) { for (char c = '0'; c <= 'z'; c = next_char(c)) { if (c != oid[i]) { tmpid = id; tmpid[i] = c; runRecommend(tmpid, oid, i + 1, rid, degree_c - (min_num(oid.length(), id.length()) - i), degree_a); } if (c == 'z') break; } } } } }
/* -------------------------------------- * brief : delete pdata from rb tree * para t: rb tree pointer * para pdata: data pointer * return : success 0, failed -1 * -------------------------------------- */ int rb_delete(RBTree *t, void *pdata) { if (t->rb_count == 0){ return -1; } RBNode *z = rb_find(t, pdata); if (!z) return -1; RBNode *y = z, *x = NULL; RB_NODE_COLOR color = y->color; if (z->child[0] == t->nil) { x = z->child[1]; rb_trans(t, z, x); } else if (z->child[1] == t->nil) { x = z->child[0]; rb_trans(t, z, x); } else { y = rb_min(t, z->child[1]); color = y->color; x = y->child[1]; if (y->p == z) { x->p = y; } else { rb_trans(t, y, x); y->child[1] = z->child[1]; y->child[1]->p = y; } rb_trans(t, z, y); y->child[0] = z->child[0]; y->child[0]->p = y; y->color = z->color; } //free(z); //z = NULL; ((RBLANode*)z)->next = t->p; t->p = (RBLANode*)z; if (color == RB_BLACK) { rb_delete_fix(t, x); } t->rb_count -= 1; return 0; }
int main() { int i; rb_tree_t tree; rb_node_t *node; rb_tree_create(&tree, NULL); for (i = 0; i < MAX; i++) rb_insert(&tree, i, NULL); rb_clear(&tree); for (i = 0; i < MAX; i+=2) rb_insert(&tree, i, NULL); for (i = 0; i < MAX; i+=4) { node = rb_find(&tree, i); rb_delete(&tree, node, FALSE); } rb_tree_destroy(&tree); return 0; }
void BankRBTree::createAccount(const string& id, const string& passwd){ //find account's position, if not exist return |NULL| string now_id = id; DataNode la = DataNode(&now_id, NULL); if(rb_find(rb_tree, &la) == NULL){ string* new_id = new string(id); Account* new_ac = new Account(id, passwd); DataNode* data = new DataNode(new_id, new_ac); rb_probe(rb_tree, data); cout << "success\n"; } else{ cout << "ID " << id << " exists, "; // recommend 10 best account RecommendId best10; getRecommend(id, best10); cout << best10[0]; for (int i = 1; i < 10; ++i) cout << "," << best10[i]; cout << "\n"; } }
void BankRBTree::searchHistory(const string& id){ DataNode la = DataNode(¤t_login_user, NULL); DataNode* res = (DataNode*)rb_find(rb_tree, &la); //Account* res1 = (Account*)rb_find(&rb_tree, ¤t_login_user); res->second->searchHistory(id); }
int main (int argc, char **argv) { int ret = 0; zhd_rb_data_t *data = NULL; zhd_rb_data_t *getdata = NULL; zhd_rb_data_t tmp = {0,}; struct rb_table *rbt = NULL; char buf[MAX_BUF_LEN] = {0}; int i = 0; int index = 0; int randomfd = -1; char randomdata[50]; size_t randomdata_len = 0; char *tmpfilename = NULL; rbt = rb_create (rb_node_compare, &zhd_param, NULL); for (;i < MAX_NODE_NUM;i++) { data = (zhd_rb_data_t *)malloc(sizeof (zhd_rb_data_t)); if (!data) { printf ("malloc error\n"); goto out; } data->index = i; sprintf(buf,"%d-XXXXXX",i); tmpfilename = mktemp(buf); data->buf = strdup(buf); memset (buf, 0, MAX_BUF_LEN); //printf("insert data:index is %d,%s\n",data->index,data->buf); rb_insert (rbt, data); if (!getdata) { printf("rb_insert success\n"); } } randomfd = open("/dev/random", O_RDONLY); if (randomfd == -1) { printf ("open /dev/random is error\n"); goto out; } printf("get ten data randomly!\n"); for (i = 0;i < 10;i++) { tmp.index = random()%MAX_NODE_NUM; #if 0 while (randomdata_len < sizeof randomdata) { ssize_t result; result = read(randomfd, randomdata+randomdata_len,(sizeof randomdata - randomdata_len)); if (result < 0) { /* error */ printf ("unable to read /dev/random\n"); } randomdata_len += result; } printf("randomdata is %s\n",randomdata); #endif getdata = rb_delete (rbt, &tmp); if (getdata) { printf("get data:index is %d,%s\n",getdata->index,getdata->buf); printf("get data:index is %d,%s\n",tmp.index,tmp.buf); } else { printf("get data error\n"); } getdata = rb_find (rbt, &tmp); if (getdata) { printf("get data:index is %d,%s\n",getdata->index,getdata->buf); printf("get data:index is %d,%s\n",tmp.index,tmp.buf); } else { printf("get data error\n"); } } if (randomfd > 0) { close(randomfd); } out: return ret; }
void test_integers_multi(int factor) { int i; intptr_t val; unsigned int count; struct rb_node *node; struct rb_tree *tree = rb_create(integer_cmp, integer_free, integer_free, integer_print, integer_print); assert( rb_isempty(tree) == 1 ); for (i = 0; i < 100 * factor; i++) { val = i % factor; rb_insert(tree, (void*)val, (void*)val); } assert( rb_isempty(tree) == 0 ); assert( rb_size(tree) == (unsigned int)100 * factor); for (i = 0; i < factor; i++) { val = i; node = rb_find(tree, (void*)val); assert(node); count = 0; while (node != rb_end(tree) && (intptr_t)node->key == i) { ++count; node = rb_successor(tree, node); } assert(count == 100); } { count = 0; for(node = rb_begin(tree); node != rb_end(tree); node = rb_successor(tree, node)) { assert((intptr_t)node->key == (count++ / 100)); } } for (i = 0; i < 100 * factor; i++) { val = i % factor; node = rb_find(tree, (void*)val); assert(node); rb_delete(tree, node); } assert( rb_isempty(tree) == 1 ); rb_destroy(tree); }
void BankRBTree::accountWithdraw(const int& money){ DataNode la = DataNode(¤t_login_user, NULL); DataNode* res = (DataNode*)rb_find(rb_tree, &la); res->second->withdrawMoney(money); }
int resman_start_watch(struct resman *rman, struct resource *res) { char *path = 0, *last_slash; struct watch_dir *wdir = 0; struct watch_item *witem = 0; /* construct an absolute path for the directory containing this file (must free it afterwards) */ if(!(path = abs_path(res->name))) { return -1; } clean_path(path); /* we need the directory path, so let's find the last slash and cut it there */ if(!(last_slash = strrchr(path, '\\'))) { goto err; } *last_slash = 0; /* check to see if we already have a watch handle for this directory */ if((wdir = rb_find(rman->watchdirs, path))) { wdir->nref++; /* ... if so, increase the refcount */ } else { /* otherwise start a new watch */ if(!(wdir = malloc(sizeof *wdir))) { perror("failed to allocate watchdir"); goto err; } memset(wdir, 0, sizeof *wdir); wdir->nref = 1; /* open the directory we need to watch */ wdir->handle = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); if(wdir->handle == INVALID_HANDLE_VALUE) { fprintf(stderr, "failed to watch %s: failed to open directory: %s\n", res->name, path); goto err; } if(!(wdir->buf_unaligned = malloc(RES_BUF_SIZE + 3))) { fprintf(stderr, "failed to allocate watch result buffer (%d bytes)\n", RES_BUF_SIZE); goto err; } wdir->buf = (char*)(((intptr_t)wdir->buf_unaligned + 3) & ~(intptr_t)0x3); memset(&wdir->over, 0, sizeof wdir->over); wdir->over.hEvent = CreateEvent(0, TRUE, FALSE, 0); if(!ReadDirectoryChangesW(wdir->handle, wdir->buf, RES_BUF_SIZE, 0, FILE_NOTIFY_CHANGE_LAST_WRITE, 0, &wdir->over, 0)) { fprintf(stderr, "failed to start async dirchange monitoring\n"); goto err; } wdir->watch_path = path; rb_insert(rman->watchdirs, path, wdir); rb_insert(rman->wdirbyev, wdir->over.hEvent, wdir); rman->watch_handles = dynarr_push(rman->watch_handles, &wdir->over.hEvent); } /* add a new watch item to this watch dir */ if(!(witem = malloc(sizeof *witem))) { perror("failed to allocate watch item"); goto err; } witem->next = wdir->items; wdir->items = witem; witem->res = res; res->watch_path = path; return 0; err: free(path); if(wdir) { if(wdir->handle && wdir->handle != INVALID_HANDLE_VALUE) { CloseHandle(wdir->handle); } free(wdir->buf_unaligned); if(wdir->over.hEvent && wdir->over.hEvent != INVALID_HANDLE_VALUE) { CloseHandle(wdir->over.hEvent); } } return -1; }
/* -------------------------------------------- * brief : fetch space index of data in tree t * return : -1 if not found * -------------------------------------------- */ int rb_index (RBTree * t, void *data){ RBNode *z = rb_find(t, data); if (!z) return -1; return ((RBLANode*)z) - t->rb_node_space; }
int main(int argc, char *argv[]) { rb_tree_t rb_tree; rb_node_t *node; unsigned int key_pool[KEY_POOL_CAPS]; unsigned int key; for (int i = 0; i < KEY_POOL_CAPS; ++i) { add_key: key = arc4random() % 3000; for (int j = i - 1; j >= 0; j--) { if (key == key_pool[j]) { goto add_key; } } key_pool[i] = key; printf("Add %u into key pool.\n", key_pool[i]); } rb_tree_init(&rb_tree, data_compare, data_destroy); redo: for (int i = 0; i < KEY_POOL_CAPS; ++i) { data_node_t *data = (data_node_t *)malloc(sizeof(*data)); data->key = key_pool[i]; if (rb_insert(&(data->rb_node), &rb_tree)) { printf("Key %u already exist.\n", data->key); } else { printf("Add %u into tree.\n", data->key); } } printf("INIT: ************\n"); printf("Min:%u\n", rb_entry(rb_first(&rb_tree), data_node_t, rb_node)->key); printf("Max:%u\n", rb_entry(rb_last(&rb_tree), data_node_t, rb_node)->key); printf("Trav with rb_next:\n"); node = rb_first(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_next(node); } printf("\n"); printf("Trav with rb_prev:\n"); node = rb_last(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_prev(node); } printf("\n"); printf("ERASE: ************\n"); data_node_t search_node; for (int i = 0; i < 5; i++) { unsigned int j = arc4random() % KEY_POOL_CAPS; search_node.key = key_pool[j]; rb_node_t *to_remove = rb_find(&(search_node.rb_node), &rb_tree); if (to_remove) { printf("Remove %u from tree.\n", search_node.key); rb_remove(to_remove, &rb_tree); free(rb_entry(to_remove, data_node_t, rb_node)); } else { printf("Key %u not in tree.\n", search_node.key); } } printf("PRINT: ************\n"); printf("Min:%u\n", rb_entry(rb_first(&rb_tree), data_node_t, rb_node)->key); printf("Max:%u\n", rb_entry(rb_last(&rb_tree), data_node_t, rb_node)->key); printf("Trav with rb_next:\n"); node = rb_first(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_next(node); } printf("\n"); printf("Trav with rb_prev:\n"); node = rb_last(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_prev(node); } printf("\n"); rb_clear(&rb_tree); printf("PRINT2: ************\n"); node = rb_first(&rb_tree); if (node) { printf("Min:%u\n", rb_entry(node, data_node_t, rb_node)->key); } node = rb_last(&rb_tree); if (node) { printf("Max:%u\n", rb_entry(node, data_node_t, rb_node)->key); } printf("Trav with rb_next:\n"); node = rb_first(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_next(node); } printf("\n"); printf("Trav with rb_prev:\n"); node = rb_last(&rb_tree); while (node) { printf("%u, ",rb_entry(node, data_node_t, rb_node)->key); node = rb_prev(node); } printf("\n"); goto redo; return 0; }
/* Checks that |tree| is well-formed and verifies that the values in |array[]| are actually in |tree|. There must be |n| elements in |array[]| and |tree|. Returns nonzero only if no errors detected. */ static int verify_tree (struct rb_table *tree, int array[], size_t n) { int okay = 1; /* Check |tree|'s bst_count against that supplied. */ if (rb_count (tree) != n) { printf (" Tree count is %lu, but should be %lu.\n", (unsigned long) rb_count (tree), (unsigned long) n); okay = 0; } if (okay) { if (tree->rb_root != NULL && tree->rb_root->rb_color != RB_BLACK) { printf (" Tree's root is not black.\n"); okay = 0; } } if (okay) { /* Recursively verify tree structure. */ size_t count; int bh; recurse_verify_tree (tree->rb_root, &okay, &count, 0, INT_MAX, &bh); if (count != n) { printf (" Tree has %lu nodes, but should have %lu.\n", (unsigned long) count, (unsigned long) n); okay = 0; } } if (okay) { /* Check that all the values in |array[]| are in |tree|. */ size_t i; for (i = 0; i < n; i++) if (rb_find (tree, &array[i]) == NULL) { printf (" Tree does not contain expected value %d.\n", array[i]); okay = 0; } } if (okay) { /* Check that |rb_t_first()| and |rb_t_next()| work properly. */ struct rb_traverser trav; size_t i; int prev = -1; int *item; for (i = 0, item = rb_t_first (&trav, tree); i < 2 * n && item != NULL; i++, item = rb_t_next (&trav)) { if (*item <= prev) { printf (" Tree out of order: %d follows %d in traversal\n", *item, prev); okay = 0; } prev = *item; } if (i != n) { printf (" Tree should have %lu items, but has %lu in traversal\n", (unsigned long) n, (unsigned long) i); okay = 0; } } if (okay) { /* Check that |rb_t_last()| and |rb_t_prev()| work properly. */ struct rb_traverser trav; size_t i; int next = INT_MAX; int *item; for (i = 0, item = rb_t_last (&trav, tree); i < 2 * n && item != NULL; i++, item = rb_t_prev (&trav)) { if (*item >= next) { printf (" Tree out of order: %d precedes %d in traversal\n", *item, next); okay = 0; } next = *item; } if (i != n) { printf (" Tree should have %lu items, but has %lu in reverse\n", (unsigned long) n, (unsigned long) i); okay = 0; } } if (okay) { /* Check that |rb_t_init()| works properly. */ struct rb_traverser init, first, last; int *cur, *prev, *next; rb_t_init (&init, tree); rb_t_first (&first, tree); rb_t_last (&last, tree); cur = rb_t_cur (&init); if (cur != NULL) { printf (" Inited traverser should be null, but is actually %d.\n", *cur); okay = 0; } next = rb_t_next (&init); if (next != rb_t_cur (&first)) { printf (" Next after null should be %d, but is actually %d.\n", *(int *) rb_t_cur (&first), *next); okay = 0; } rb_t_prev (&init); prev = rb_t_prev (&init); if (prev != rb_t_cur (&last)) { printf (" Previous before null should be %d, but is actually %d.\n", *(int *) rb_t_cur (&last), *prev); okay = 0; } rb_t_next (&init); } return okay; }