/* * Sorting tree building goes here * NOTE : We do not need to make tree balancing because of random nature of keys. * Tree will not degradate strongly. */ void add_to_tree(compact_header_t * node, compact_header_t * tree) { compact_header_t * to_hang = tree; int complete = 0; do { switch (compare_keys(node->key, to_hang->key)) { case 1 : if (to_hang->right != NULL) { to_hang = to_hang->right; } else { to_hang->right = node; complete = 1; } break; case 0 : case -1 : if (to_hang->left != NULL) { to_hang = to_hang->left; } else { to_hang->left = node; complete = 1; } break; } } while(!complete); }
tree* insert_tree(tree** t, const void* key, int key_sz, const tree* parent, int (*compare_keys)(const void* key1, const void* key2)) { tree* p; if(*t == NULL) { p = malloc(sizeof(tree)); p->key = malloc(key_sz); p->key_sz = key_sz; memcpy(p->key, key, key_sz); p->item = NULL; p->left = p->right = NULL; p->parent = (tree*)parent; *t = p; return *t; } int cmp = compare_keys(key, (*t)->key); if(cmp < 0) return insert_tree(&((*t)->left), key, key_sz, *t, compare_keys); else return insert_tree(&((*t)->right), key, key_sz, *t, compare_keys); }
static int __ardb_compare_keys(WT_COLLATOR *collator, WT_SESSION *session, const WT_ITEM *v1, const WT_ITEM *v2, int *cmp) { const char *s1 = (const char *) v1->data; const char *s2 = (const char *) v2->data; (void) session; /* unused */ (void) collator; /* unused */ *cmp = compare_keys(s1, v1->size, s2, v2->size, false); return (0); }
static void list_preinsert(list_t *list, void *ptr) { ulong_t k1, k2; if (list->l_used < list->l_size) { /* just add */ list_insert(list, ptr); return; } k1 = list_getkeyval(list, list->l_ptrs[list->l_used - 1]); k2 = list_getkeyval(list, ptr); if (compare_keys(list, k1, k2) >= 0) /* skip insertion */ return; k1 = list_getkeyval(list, list->l_ptrs[0]); if (compare_keys(list, k2, k1) >= 0) { /* add at the head */ list_insert(list, ptr); return; } list_insert(list, ptr); }
static int compare_keys_len (const void *p1, const void *p2) { const char *key1 = * (char * const *) p1; const char *key2 = * (char * const *) p2; int c; c = strlen (key1) - strlen (key2); if (c != 0) return c; return compare_keys (p1, p2); }
const tree* search_tree(const tree* t, const void* key, int (*compare_keys)(const void* key1, const void* key2)) { if(t == NULL) return NULL; int cmp = compare_keys(key, t->key); if(cmp == 0) return t; if(cmp < 0) return search_tree(t->left, key, compare_keys); else return search_tree(t->right, key, compare_keys); }
/* * keyed_min_max_combine_internal */ static Datum keyed_min_max_combine_internal(FunctionCallInfo fcinfo, int sign) { KeyedAggState *kas; KeyValue *state; KeyValue *incoming = (KeyValue *) PG_GETARG_VARLENA_P(1); MemoryContext old; MemoryContext context; int cmp; bool isnull; if (!AggCheckCallContext(fcinfo, &context)) elog(ERROR, "keyed_min_combine_internal called in non-aggregate context"); if (PG_ARGISNULL(0)) { /* * We can't use the startup function that the aggregate uses because * the combiner Aggref doesn't have all of the original arguments. */ old = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); kas = palloc0(sizeof(KeyedAggState)); kas->key_type = lookup_type_cache(incoming->key_type, TYPECACHE_CMP_PROC_FINFO); kas->value_type = lookup_type_cache(incoming->value_type, 0); fcinfo->flinfo->fn_extra = kas; MemoryContextSwitchTo(old); old = MemoryContextSwitchTo(context); state = copy_kv(kas, incoming); MemoryContextSwitchTo(old); PG_RETURN_POINTER(state); } old = MemoryContextSwitchTo(context); state = (KeyValue *) PG_GETARG_VARLENA_P(0); kas = (KeyedAggState *) fcinfo->flinfo->fn_extra; incoming = point_to_self(kas, (struct varlena *) incoming); cmp = sign * compare_keys(kas, state, incoming->key, KV_KEY_IS_NULL(incoming), state->key_collation, &isnull); if (!isnull && cmp <= 0) state = copy_kv(kas, incoming); MemoryContextSwitchTo(old); PG_RETURN_POINTER(state); }
static void insert_node(skipnode* h, skipnode* s, int l, int (*compare_keys)(const void* key1, const void* key2)) { int i; for(i = l; i >= 0; i--) { int j = (h->next[i] != NULL) ? compare_keys(h->next[i]->key, s->key) : INT_MAX; while(h->next[i] != NULL && j < 0) { h = h->next[i]; j = (h->next[i] != NULL) ? compare_keys(h->next[i]->key, s->key) : INT_MAX; } /*slot in new node*/ s->next[i] = h->next[i]; s->prev[i] = h; h->next[i] = s; if(s->next[i] != NULL) s->next[i]->prev[i] = s; } }
/*In the first case the search was successful. */ const skipnode* contains_skipnode(const skipset* ss, const void* key, int (*compare_keys)(const void* key1, const void* key2)) { skipnode* s = ss->header; int i; for(i = ss->level; i >= 0; i--) { /*first key less than second key*/ int j = (s->next[i] != NULL) ? compare_keys(s->next[i]->key, key) : INT_MAX; while(s->next[i] != NULL && j < 0) { s = s->next[i]; j = (s->next[i] != NULL) ? compare_keys(s->next[i]->key, key) : INT_MAX; } /*both keys equal*/ if(s->next[i] != NULL && j == 0) return s->next[i]; } return NULL; }
// helper function for recursive search facility. static struct trie_node * _search (struct trie_node *node, const char *string, size_t strlen) { // immediate exit on no-node. if (node == NULL) return NULL; // See if this key is a substring of the string passed in size_t keylen; int cmp = compare_keys(node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // partial match, if the node keylen is longer than the // input key, we cannot have a match, and cannot have // sibling or child match, so return NULL. if (node->strlen > strlen) node = NULL; // else if there are still chars left in the input key // to consume, recurse into children. else if (strlen > keylen) node = _search(node->children, string, strlen - keylen); // else i we have a winner, but only if there is an ip address // if there isn't (0), then this must be considered an just an // intermediate note and should not be returned as the "find" else if (node->ip4_address == 0) node = NULL; } // if the node's key is "less" than look to the siblings // of the current node. else if (cmp < 0) node = _search(node->next, string, strlen); // else it is greater, and there can be no possible match else node = NULL; // final return value. return node; }
static void test_der_public (gcry_sexp_t key) { guchar *data; gsize n_data; GkmDataResult ret; gcry_sexp_t sexp; /* Encode it */ data = gkm_data_der_write_public_key (key, &n_data); g_assert ("couldn't encode public key" && data != NULL); g_assert ("encoding is empty" && n_data > 0); /* Now parse it */ ret = gkm_data_der_read_public_key (data, n_data, &sexp); g_assert ("couldn't decode public key" && ret == GKM_DATA_SUCCESS); g_assert ("parsed key is empty" && sexp != NULL); /* Now compare them */ g_assert ("key parsed differently" && compare_keys (key, sexp)); }
/* * keyed_min_trans_internal */ static Datum keyed_min_max_trans_internal(FunctionCallInfo fcinfo, int sign) { KeyValue *kv; Datum incoming_key = PG_GETARG_DATUM(1); Datum incoming_value = PG_GETARG_DATUM(2); KeyedAggState *state; MemoryContext old; MemoryContext context; bool isnull; int cmp; if (!AggCheckCallContext(fcinfo, &context)) elog(ERROR, "keyed_min_max_trans_internal called in non-aggregate context"); old = MemoryContextSwitchTo(context); if (PG_ARGISNULL(0)) { kv = keyed_trans_startup(fcinfo); MemoryContextSwitchTo(old); PG_RETURN_POINTER(kv); } state = (KeyedAggState *) fcinfo->flinfo->fn_extra; kv = point_to_self(state, PG_GETARG_BYTEA_P(0)); cmp = sign * compare_keys(state, kv, incoming_key, PG_ARGISNULL(1), PG_GET_COLLATION(), &isnull); if (!isnull && cmp <= 0) kv = set_kv(state, kv, incoming_key, PG_ARGISNULL(1), incoming_value, PG_ARGISNULL(2)); MemoryContextSwitchTo(old); PG_RETURN_POINTER(kv); }
static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) { struct dn_route *rth, **rthp; unsigned long now = jiffies; rthp = &dn_rt_hash_table[hash].chain; spin_lock_bh(&dn_rt_hash_table[hash].lock); while((rth = *rthp) != NULL) { if (compare_keys(&rth->fl, &rt->fl)) { /* Put it first */ *rthp = rth->u.rt_next; rcu_assign_pointer(rth->u.rt_next, dn_rt_hash_table[hash].chain); rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth); rth->u.dst.__use++; dst_hold(&rth->u.dst); rth->u.dst.lastuse = now; spin_unlock_bh(&dn_rt_hash_table[hash].lock); dnrt_drop(rt); *rp = rth; return 0; } rthp = &rth->u.rt_next; } rcu_assign_pointer(rt->u.rt_next, dn_rt_hash_table[hash].chain); rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt); dst_hold(&rt->u.dst); rt->u.dst.__use++; rt->u.dst.lastuse = now; spin_unlock_bh(&dn_rt_hash_table[hash].lock); *rp = rt; return 0; }
/* Recursive helper function. * Returns a pointer to the node if found. * Stores an optional pointer to the * parent, or what should be the parent if not found. * */ struct trie_node * _search (struct trie_node *node, const char *string, size_t strlen) { int keylen, cmp; // First things first, check if we are NULL if (node == NULL) return NULL; assert(node->strlen < 64); // See if this key is a substring of the string passed in cmp = compare_keys(node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, the key isn't here if (node->strlen > keylen) { return NULL; } else if (strlen > keylen) { // Recur on children list return _search(node->children, string, strlen - keylen); } else { assert (strlen == keylen); return node; } } else if (cmp < 0) { // No, look right (the node's key is "less" than the search key) return _search(node->next, string, strlen); } else { // Quit early return 0; } }
/* Check previously generated output file */ void check_output(const char * file_path) { int fd = open(file_path, O_RDONLY); fprintf(stderr, "Trying to open file %s\n", file_path); if (fd < 0) { perror("Cannot open file"); exit(EXIT_FAILURE); } header_t hdr_prev; memset(hdr_prev.key, 0, sizeof(hdr_prev.key)); header_t hdr_curr; size_t cnt = 0; while(!read_header_from_file(fd, &hdr_curr)) { if (compare_keys(hdr_curr.key, hdr_prev.key) == -1) { fprintf(stderr, "mismatch on %u!\n", cnt); return; } hdr_prev = hdr_curr; lseek64(fd, hdr_curr.size, SEEK_CUR); } fprintf(stderr, "CHECK OK\n"); }
/* gets the inode of a directory entry, or 0 if errno. * (inode 0 is the root dir, which is not an entry in any dir) */ PUBLIC uint32_t get_dir_ent_inode(struct fs_info *fsi, uint32_t dir_inode, char *name) { struct path p; struct key key; struct dir_ent_metadata *demd; int ret; set_dir_ent_key(dir_inode, name, &key); ret = search_slot(&fsi->fs_root, &key, &p, 0); if (ret == KEY_NOT_FOUND) { free_path(&p); /* only for search_slot(), not step_to_next_slot() */ } while (TRUE) { if (ret == KEY_NOT_FOUND) { errno = ENOENT; } if (ret < 0) { errno = -ret; } if (ret != KEY_FOUND) { return 0; /* failure, with errno */ } demd = (struct dir_ent_metadata *) metadata_for(&p); if (!strcmp(name, demd->name)) { /* name matches */ ret = demd->inode; free_path(&p); return ret; } ret = step_to_next_slot(&p); if (ret == KEY_FOUND && compare_keys(&key, item_key(&p))) { errno = ENOENT; free_path(&p); return 0; /* failure, with errno */ } } }
static void list_insert(list_t *list, void *ptr) { int i, j; long k1, k2; for (i = 0; i < list->l_used; i++) { /* insert in the middle */ k1 = list_getkeyval(list, ptr); k2 = list_getkeyval(list, list->l_ptrs[i]); if (compare_keys(list, k1, k2) >= 0) { for (j = list->l_used - 1; j >= i; j--) list->l_ptrs[j+1] = list->l_ptrs[j]; list->l_ptrs[i] = ptr; if (list->l_used < list->l_size) list->l_used++; return; } } if (i + 1 <= list->l_size) { /* insert at the tail */ list->l_ptrs[list->l_used] = ptr; list->l_used++; } }
int merge_files(dbfr_t *left_reader, dbfr_t *right_reader, FILE * out, struct cmdargs *args) { int retval = EXIT_OKAY; char field_right[MAX_FIELD_LEN + 1]; /* buffer for holding field values */ int i; /* general-purpose counter */ /** @todo take into account that files a & b might have the same fields in * a different order. */ int keycmp = 0; /* assume that if there is a header line, it exists in both files. */ while (!left_reader->eof) { if (left_reader->current_line == NULL || left_reader->current_line[0] == '\0') { /* get a line from the full set */ if (dbfr_getline(left_reader) <= 0) { free(left_reader->current_line); left_reader->current_line = NULL; break; } } if (right_reader->current_line == NULL || right_reader->current_line[0] == '\0') { if (right_reader->eof) { /* no more delta data to merge in: just dump the rest of the full data set. */ Fputs(left_reader->current_line, out); while (dbfr_getline(left_reader) > 0) Fputs(left_reader->current_line, out); continue; } /* get a line from the delta set */ if (dbfr_getline(right_reader) <= 0) { free(right_reader->current_line); right_reader->current_line = NULL; continue; } } keycmp = compare_keys(left_reader->current_line, right_reader->current_line); switch (keycmp) { /* keys equal - print the delta line and scan forward in both files the next time around. */ case 0: Fputs(right_reader->current_line, out); right_reader->current_line[0] = '\0'; left_reader->current_line[0] = '\0'; break; /* delta line greater than full-set line. print the full set line and keep the delta line for later. */ case -1: Fputs(left_reader->current_line, out); left_reader->current_line[0] = '\0'; break; /* delta line less than full-set line: the full set did not previously contain the key from delta. */ case 1: Fputs(right_reader->current_line, out); right_reader->current_line[0] = '\0'; break; } } if (right_reader->current_line != NULL && right_reader->current_line[0] != '\0') Fputs(right_reader->current_line, out); if (! right_reader->eof) { while (dbfr_getline(right_reader) > 0) Fputs(right_reader->current_line, out); } if (keyfields) free(keyfields); return retval; }
int sort_main(int argc, char **argv) { FILE *fp,*outfile=NULL; int linecount=0,i,flag; char *line,**lines=NULL,*optlist="ngMucszbrdfimS:T:o:k:t:"; int c; bb_default_error_retval = 2; /* Parse command line options */ while((c=getopt(argc,argv,optlist))>0) { line=index(optlist,c); if(!line) bb_show_usage(); switch(*line) { #ifdef CONFIG_FEATURE_SORT_BIG case 'o': if(outfile) bb_error_msg_and_die("Too many -o."); outfile=bb_xfopen(optarg,"w"); break; case 't': if(key_separator || optarg[1]) bb_error_msg_and_die("Too many -t."); key_separator=*optarg; break; /* parse sort key */ case 'k': { struct sort_key *key=add_key(); char *temp, *temp2; temp=optarg; for(i=0;*temp;) { /* Start of range */ key->range[2*i]=(unsigned short)strtol(temp,&temp,10); if(*temp=='.') key->range[(2*i)+1]=(unsigned short)strtol(temp+1,&temp,10); for(;*temp;temp++) { if(*temp==',' && !i++) { temp++; break; } /* no else needed: fall through to syntax error because comma isn't in optlist */ temp2=index(optlist,*temp); flag=(1<<(temp2-optlist)); if(!temp2 || (flag>FLAG_M && flag<FLAG_b)) bb_error_msg_and_die("Unknown key option."); /* b after , means strip _trailing_ space */ if(i && flag==FLAG_b) flag=FLAG_bb; key->flags|=flag; } } break; } #endif default: global_flags|=(1<<(line-optlist)); /* global b strips leading and trailing spaces */ if(global_flags&FLAG_b) global_flags|=FLAG_bb; break; } } /* Open input files and read data */ for(i=argv[optind] ? optind : optind-1;argv[i];i++) { if(i<optind || (*argv[i]=='-' && !argv[i][1])) fp=stdin; else fp=bb_xfopen(argv[i],"r"); for(;;) { line=GET_LINE(fp); if(!line) break; if(!(linecount&63)) lines=xrealloc(lines, sizeof(char *)*(linecount+64)); lines[linecount++]=line; } fclose(fp); } #ifdef CONFIG_FEATURE_SORT_BIG /* if no key, perform alphabetic sort */ if(!key_list) add_key()->range[0]=1; /* handle -c */ if(global_flags&FLAG_c) { int j=(global_flags&FLAG_u) ? -1 : 0; for(i=1;i<linecount;i++) if(compare_keys(&lines[i-1],&lines[i])>j) { fprintf(stderr,"Check line %d\n",i); return 1; } return 0; } #endif /* Perform the actual sort */ qsort(lines,linecount,sizeof(char *),compare_keys); /* handle -u */ if(global_flags&FLAG_u) { for(flag=0,i=1;i<linecount;i++) { if(!compare_keys(&lines[flag],&lines[i])) free(lines[i]); else lines[++flag]=lines[i]; } if(linecount) linecount=flag+1; } /* Print it */ if(!outfile) outfile=stdout; for(i=0;i<linecount;i++) fprintf(outfile,"%s\n",lines[i]); bb_fflush_stdout_and_exit(EXIT_SUCCESS); }
/* Recursive helper function. * Returns a pointer to the node if found. * Returns ip address of the node... -1 if not found * Stores an optional pointer to the * parent, or what should be the parent if not found. * * assumes node is locked * node lock will be released before returning * * node should never be null */ int32_t _search_and_squat(struct trie_node *node, const char *string, size_t strlen, int32_t ip4_address) { int keylen, cmp; int rc; // First things first, check if we are NULL // this should never happen assert(node != NULL); if (node == NULL) return -1; assert(node->strlen < 64); assert(strlen >0); // See if this key is a substring of the string passed in cmp = compare_keys(node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, the key isn't here if (node->strlen > keylen) { rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } else if (strlen > keylen) { if(node->children != NULL) { // first lock children, then unlock parent to prevent possible // situation where the thread has no locks and children is deleted rc = pthread_mutex_lock(&(node->children->lock)); assert(rc == 0); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); // Recur on children list return _search(node->children, string, strlen - keylen); } else { rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } } else { //here is where squatting block happens, loop through until rv = 1 due to having a max # of squats int rv = 0; node->waiting++; while(!rv) { if(node->ip4_address == 0) { node->ip4_address = ip4_address; node->waiting--; rv = 1; } else { int waitSuccess = pthread_cond_wait(&(node->c), &(node->lock)); assert(waitSuccess == 0); } } assert (strlen == keylen); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 1; } } else if (cmp < 0) { if(node->next != NULL) { // No, look right (the node's key is "less" than the search key) // first lock next, then unlock parent to prevent possible // situation where the thread has no locks and next is deleted //assign next node, get its lock, return lock of current node //recur through the next struct trie_node *next = node->next; rc = pthread_mutex_lock(&(next->lock)); assert(rc == 0); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return _search(next, string, strlen); } else { rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } } else { // Quit early rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } }
int check_in_use(int _currentState,int index,const KeyCombo *kc,NppParameters *nppParam,TCHAR *str,int str_size) { int i,count=0; if(kc->_key==0) return count; _sntprintf_s(str,str_size,_TRUNCATE,L"%s",L"Duplicate shortcuts found:"); { vector<CommandShortcut> &shortcuts=nppParam->getUserShortcuts(); for(i=0;i<(int)shortcuts.size();i++){ CommandShortcut sc=shortcuts[i]; count+=compare_keys(_currentState==STATE_MENU?i:-1,index,sc.getName(),&sc.getKeyCombo(),kc,str,str_size); } } { vector<MacroShortcut> & shortcuts = nppParam->getMacroList(); for(i=0;i<(int)shortcuts.size();i++){ MacroShortcut sc=shortcuts[i]; count+=compare_keys(_currentState==STATE_MACRO?i:-1,index,sc.getName(),&sc.getKeyCombo(),kc,str,str_size); } } { vector<UserCommand> & shortcuts = nppParam->getUserCommandList(); for(i=0;i<(int)shortcuts.size();i++){ UserCommand sc=shortcuts[i]; count+=compare_keys(_currentState==STATE_USER?i:-1,index,sc.getName(),&sc.getKeyCombo(),kc,str,str_size); } } { vector<PluginCmdShortcut> & shortcuts = nppParam->getPluginCommandList(); for(i=0;i<(int)shortcuts.size();i++){ PluginCmdShortcut sc=shortcuts[i]; count+=compare_keys(_currentState==STATE_PLUGIN?i:-1,index,sc.getName(),&sc.getKeyCombo(),kc,str,str_size); } } { vector<ScintillaKeyMap> & shortcuts = nppParam->getScintillaKeyList(); for(i=0;i<(int)shortcuts.size();i++){ ScintillaKeyMap sc=shortcuts[i]; int j,max; max=sc.getSize(); for(j=0;j<max;j++){ KeyCombo sckc=sc.getKeyComboByIndex(j); count+=compare_keys(_currentState==STATE_SCINTILLA?i:-1,index,sc.getName(),&sckc,kc,str,str_size); } if(_currentState==STATE_SCINTILLA && (size_t)index<shortcuts.size()){ ScintillaKeyMap current_sc=shortcuts[index]; if(current_sc.getSize()>1){ int k,current_max=current_sc.getSize(); for(k=1;k<current_max;k++){ for(j=0;j<max;j++){ KeyCombo sckc=sc.getKeyComboByIndex(j); KeyCombo current_kc=current_sc.getKeyComboByIndex(k); count+=compare_keys(i,index,sc.getName(),&sckc,¤t_kc,str,str_size); } } } } } } return count; }
/* Recursive helper function */ int _insert (const char *string, size_t strlen, int32_t ip4_address, struct trie_node *node, struct trie_node *parent, struct trie_node *left) { int rc; // assert that this thread has a lock on both parent or left // whichever is not null // First things first, check if we are NULL assert (node != NULL); // get a lock on node rc = pthread_mutex_lock(&(node->lock)); assert(rc == 0); int cmp, keylen; assert (node->strlen < 64); assert (node->strlen > 0); assert (strlen > 0); // Take the minimum of the two lengths cmp = compare_keys (node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, we need to insert // "above" this node if (node->strlen > keylen) { struct trie_node *new_node; assert(keylen == strlen); assert((!parent) || parent->children == node); new_node = new_leaf (string, strlen, ip4_address); rc = pthread_mutex_lock(&(new_node->lock)); assert(rc == 0); node->strlen -= keylen; new_node->children = node; assert ((!parent) || (!left)); // should already have a lock on the parent or left node if (parent) { parent->children = new_node; } else if (left) { left->next = new_node; } else if ((!parent) || (!left)) { root = new_node; } rc = pthread_mutex_unlock(&(new_node->lock)); assert(rc == 0); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 1; } else if (strlen > keylen) { if (node->children == NULL) { struct trie_node *new_node = new_leaf (string, strlen - keylen, ip4_address); rc = pthread_mutex_lock(&(new_node->lock)); assert(rc == 0); node->children = new_node; rc = pthread_mutex_unlock(&(new_node->lock)); assert(rc == 0); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 1; } else { // Recur on children list, store "parent" (loosely defined) int rv = _insert(string, strlen - keylen, ip4_address, node->children, node, NULL); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return rv; } } else { assert (strlen == keylen); if (node->ip4_address == 0) { node->ip4_address = ip4_address; // unlock node rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 1; } else { // unlock node rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 0; } } } else { /* Is there any common substring? */ int i, cmp2, keylen2, overlap = 0; for (i = 1; i < keylen; i++) { cmp2 = compare_keys (&node->key[i], node->strlen - i, &string[i], strlen - i, &keylen2); assert (keylen2 > 0); if (cmp2 == 0) { overlap = 1; break; } } if (overlap) { // Insert a common parent, recur struct trie_node *new_node = new_leaf (&string[i], strlen - i, 0); // lock new node rc = pthread_mutex_lock(&(new_node->lock)); assert(rc == 0); int diff = node->strlen - i; assert ((node->strlen - diff) > 0); node->strlen -= diff; new_node->children = node; assert ((!parent) || (!left)); // TODO get root lock if (node == root) { new_node->next = node->next; node->next = NULL; root = new_node; } else if (parent) { assert(parent->children == node); new_node->next = NULL; parent->children = new_node; } else if (left) { new_node->next = node->next; node->next = NULL; left->next = new_node; } else if ((!parent) && (!left)) { // TODO get root lock root = new_node; } rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); int rv = _insert(string, i, ip4_address, node, new_node, NULL); rc = pthread_mutex_unlock(&(new_node->lock)); assert(rc == 0); return rv; } else if (cmp < 0) { if (node->next == NULL) { // Insert here struct trie_node *new_node = new_leaf (string, strlen, ip4_address); rc = pthread_mutex_lock(&(new_node->lock)); assert(rc == 0); node->next = new_node; rc = pthread_mutex_unlock(&(new_node->lock)); assert(rc == 0); // unlock node rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 1; } else { // No, recur right (the node's key is "greater" than the search key) // by convention node should be locked and node->next will be locked inside the method int rv = _insert(string, strlen, ip4_address, node->next, NULL, node); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return rv; } } else { // Insert here struct trie_node *new_node = new_leaf (string, strlen, ip4_address); rc = pthread_mutex_lock(&(new_node->lock)); assert(rc == 0); new_node->next = node; // TODO get root lock if (node == root) { root = new_node; } else if (parent && parent->children == node) { parent->children = new_node; } rc = pthread_mutex_unlock(&(new_node->lock)); assert(rc == 0); } rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return 1; } }
/* Recursive helper function. * Returns a pointer to the node if found. * Stores an optional pointer to the * parent, or what should be the parent if not found. * * If it returns a node, there will be a lock on that node */ struct trie_node * _delete (struct trie_node *node, const char *string, size_t strlen) { int keylen, cmp; int rc; // First things first, check if we are NULL if (node == NULL) return NULL; // lock the node here, rc = pthread_mutex_lock(&(node->lock)); assert(rc == 0); assert(node->strlen < 64); // See if this key is a substring of the string passed in cmp = compare_keys (node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, the key isn't here if (node->strlen > keylen) { // unlock node rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return NULL; } else if (strlen > keylen) { // found wont be unlocked by this method struct trie_node *found = _delete(node->children, string, strlen - keylen); if (found) { if(found->waiting > 0 && allow_squatting) { pthread_cond_broadcast(&(found->c)); rc = pthread_mutex_unlock(&(found->lock)); assert(rc == 0); } else { /* If the node doesn't have children, delete it. * Otherwise, keep it around to find the kids */ if (found->children == NULL && found->ip4_address == 0) { // shouldnt need to lock found->next because as long as parent is locked, // nothing bad should be able to happen to it (check what insert does) assert(node->children == found); node->children = found->next; // unlock found rc = pthread_mutex_unlock(&(found->lock)); assert(rc == 0); free(found); } else { rc = pthread_mutex_unlock(&(found->lock)); assert(rc == 0); } } // unlock found // TODO get root lock /* Delete the root node if we empty the tree */ if (node == root && node->children == NULL && node->ip4_address == 0) { if(node->waiting > 0 && allow_squatting) { pthread_cond_broadcast(&(node->c)); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); } else { root = node->next; rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); free(node); } } // dont unlock node, we are still doing operations on it return node; /* Recursively delete needless interior nodes */ } else { rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return NULL; } } else { assert (strlen == keylen); /* We found it! Clear the ip4 address and return. */ if (node->ip4_address) { node->ip4_address = 0; //TODO lock root /* Delete the root node if we empty the tree */ if (node == root && node->children == NULL && node->ip4_address == 0) { root = node->next; rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); // dont free if waiting > 0 free(node); return (struct trie_node *) 0x100100; /* XXX: Don't use this pointer for anything except * comparison with NULL, since the memory is freed. * Return a "poison" pointer that will probably * segfault if used. */ } // dont return node, still doing stuff return node; } else { /* Just an interior node with no value */ rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return NULL; } } } else if (cmp < 0) { // No, look right (the node's key is "less" than the search key) // found should be locked struct trie_node *found = _delete(node->next, string, strlen); if (found) { if(found->waiting > 0 && allow_squatting) { pthread_cond_broadcast(&(found->c)); rc = pthread_mutex_unlock(&(found->lock)); assert(rc == 0); } else { /* If the node doesn't have children, delete it. * Otherwise, keep it around to find the kids */ if (found->children == NULL && found->ip4_address == 0) { assert(node->next == found); node->next = found->next; rc = pthread_mutex_unlock(&(found->lock)); assert(rc == 0); free(found); } else { rc = pthread_mutex_unlock(&(found->lock)); assert(rc == 0); } } return node; /* Recursively delete needless interior nodes */ } rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return NULL; } else { // Quit early rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return NULL; } }
/* Recursive helper function. * Returns a pointer to the node if found. * Returns ip address of the node... -1 if not found * Stores an optional pointer to the * parent, or what should be the parent if not found. * * assumes node is locked * node lock will be released before returning * * node should never be null */ int32_t _search (struct trie_node *node, const char *string, size_t strlen) { //This function is always entered by one of the _search functions, this is the HEAVY LIFTER of the searchers. int keylen, cmp; int rc; // First things first, check if we are NULL // NULL node means something screwed up somewhere. assert(node != NULL); if (node == NULL) return -1; //Strlen must be below 64 characters, this is just a standard of the application assert(node->strlen < 64); //Similar to the strlen being below 64 it must be greater than 0 assert(strlen >0); //Check for substring, we start by comparing the sizes. cmp = compare_keys(node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, the key isn't here if (node->strlen > keylen) { //Unlock the lock we previously acquired in a controller search function int rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); //return fail code return -1; } else if (strlen > keylen) { if(node->children != NULL) { // first lock children, then unlock parent to prevent possible // hand over hand //acquire childs lock, assert gaurantees we got it or terminates rc = pthread_mutex_lock(&(node->children->lock)); assert(rc == 0); //unlock the current nodes lock, this is us moving forward on the search rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); //Recur into the child return _search(node->children, string, strlen - keylen); } else { //if there are no children release the lock, return fail code rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } } else { //strlen should be the same length as keylen, assert it, return the IP address of the node assert (strlen == keylen); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return node->ip4_address; } } else if (cmp < 0) { //cmp returns 0 then we are looking next to us for the node if(node->next != NULL) { // No, look right (the node's key is "less" than the search key) // hand over hand //assign the next node struct trie_node *next = node->next; //get its lock, release the lock of current node rc = pthread_mutex_lock(&(next->lock)); assert(rc == 0); rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); //recur the search through the next node return _search(next, string, strlen); } else { //not found release lock, return fail. rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } } else { // Quit early rc = pthread_mutex_unlock(&(node->lock)); assert(rc == 0); return -1; } }
/* searches a tree for a key, or the slot where it should be inserted. * (This function's signature is modeled after the one in Btrfs.) * r - the root of the tree to search * key - the key to search for * p - path result found/prepared for modification (shadowed at least) * ins_len - number of bytes needed for the item and its metadata in leaf * (if inserting), or negative if deleting. When inserting, * index nodes on the path and the leaf node are proactively split * if at the upper bounds, or to provide the required space in the leaf. * When deleting, index nodes (below root) at the lower bounds * on the path are proactively fixed. When 0, the nodes on the path * are not modified or shadowed. * returns 0 if the key is found, 1 if not, or a negative errno with no path. */ PUBLIC int search_slot(struct root *r, struct key *key, struct path *p, int ins_len) { int ret, level = -1; blocknr_t blocknr = r->blocknr; /* start at root blocknr */ memset(p, 0, sizeof(*p)); /* make NULL after the root level */ /* traverse from root to leaf */ while (TRUE) { int i, j, least_key, comparison; struct header *hdr; struct cache *node = get_block(blocknr); if (!node) { if (level != -1) { free_path_from(p, level); } return -errno; } hdr = &node->u.node.header; assert(hdr->header_magic == HEADER_MAGIC); if (level >= 0) { assert(level == hdr->level + 1); /* level counts down to 0 */ } level = hdr->level; p->nodes[level] = node; /* check for special case: empty root node during mkfs */ if (!hdr->nritems) { struct cache *leaf; blocknr_t leafnr; uint16_t type = LEAF_TYPE_FOR(hdr->type); assert(level == 1); assert(!p->nodes[2]); assert(ins_len > 0); p->slots[level] = 0; /* init first leaf and add to path, but leave empty */ leafnr = alloc_block(r->fs_info, node, type); if (!leafnr) { free_path_from(p, level); return -ENOSPC; } leaf = init_node(leafnr, type, 0); if (!leaf) { free_path_from(p, level); return -errno; } /* a new node gets a new ptr to it */ insert_key_ptr(r, p, level, key, leafnr); p->nodes[0] = leaf; p->slots[0] = 0; /* the caller will insert the first item in the new leaf */ return KEY_NOT_FOUND; } /* go one slot past the search key */ for (i = 0; i < hdr->nritems; i++) { comparison = compare_keys(key_for(node, i), key); if (comparison > 0) break; /* one slot past the key */ } if (i) { /* the slot to the left is equal or less */ p->slots[level] = i - 1; least_key = FALSE; } else { /* the key is less than everything else in the tree */ least_key = TRUE; p->slots[level] = 0; /* it would be inserted here */ j = level; while (TRUE) { assert(p->slots[j] == 0); if (is_root_level(j++, p)) break; } } /* if going to modify, shadow now (on tree descent) */ if (ins_len) { ret = ensure_will_write(r, p, level); if (ret) { free_path_from(p, level); return ret; } } /* leaf node */ if (level == 0) { if (ins_len > 0) { ret = ensure_leaf_space(r, p, ins_len); if (ret) { free_path(p); return ret; } } assert(hdr->nritems); /* an empty leaf would not be preserved */ /* so there is an item to compare with */ comparison = compare_keys(key_for(node, p->slots[0]), key); if (comparison < 0) { p->slots[0]++; /* would insert at next slot in leaf */ } ret = insert_extents_for_reserves(&r->fs_info->extent_root); return ret ? ret : (comparison ? KEY_NOT_FOUND : KEY_FOUND); /* index node */ } else { if (ins_len > 0) { /* inserting */ if (least_key) { /* will make leftmost key less */ update_index_key(r, p, level, key); } if (hdr->nritems >= UPPER_BOUNDS(r->fs_info->lower_bounds)) { ret = split_index_node(r, p, level); if (ret) { free_path_from(p, level); return ret; } } } if (ins_len < 0) { /* deleting */ if (!is_root_level(level, p) && hdr->nritems <= r->fs_info->lower_bounds) { ret = fix_index_node(r, p, level); if (ret) { free_path_from(p, level); return ret; } } } blocknr = ptr_for(node, p->slots[level]); } } }
/* Recursive helper function. * Returns a pointer to the node if found. * Stores an optional pointer to the * parent, or what should be the parent if not found. * */ struct trie_node * _delete (struct trie_node *node, const char *string, size_t strlen) { int keylen, cmp; // First things first, check if we are NULL if (node == NULL) return NULL; assert(node->strlen < 64); // See if this key is a substring of the string passed in cmp = compare_keys (node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, the key isn't here if (node->strlen > keylen) { return NULL; } else if (strlen > keylen) { struct trie_node *found = _delete(node->children, string, strlen - keylen); if (found) { /* If the node doesn't have children, delete it. * Otherwise, keep it around to find the kids */ if (found->children == NULL && found->ip4_address == 0) { assert(node->children == found); node->children = found->next; free(found); } /* Delete the root node if we empty the tree */ if (node == root && node->children == NULL && node->ip4_address == 0) { root = node->next; free(node); } return node; /* Recursively delete needless interior nodes */ } else return NULL; } else { assert (strlen == keylen); /* We found it! Clear the ip4 address and return. */ if (node->ip4_address) { node->ip4_address = 0; /* Delete the root node if we empty the tree */ if (node == root && node->children == NULL && node->ip4_address == 0) { root = node->next; free(node); return (struct trie_node *) 0x100100; /* XXX: Don't use this pointer for anything except * comparison with NULL, since the memory is freed. * Return a "poison" pointer that will probably * segfault if used. */ } return node; } else { /* Just an interior node with no value */ return NULL; } } } else if (cmp < 0) { // No, look right (the node's key is "less" than the search key) struct trie_node *found = _delete(node->next, string, strlen); if (found) { /* If the node doesn't have children, delete it. * Otherwise, keep it around to find the kids */ if (found->children == NULL && found->ip4_address == 0) { assert(node->next == found); node->next = found->next; free(found); } return node; /* Recursively delete needless interior nodes */ } return NULL; } else { // Quit early return NULL; } }
/* Recursive helper function */ int _insert (const char *string, size_t strlen, int32_t ip4_address, struct trie_node *node, struct trie_node *parent, struct trie_node *left) { int cmp, keylen; // First things first, check if we are NULL assert (node != NULL); assert (node->strlen < 64); // Take the minimum of the two lengths cmp = compare_keys (node->key, node->strlen, string, strlen, &keylen); if (cmp == 0) { // Yes, either quit, or recur on the children // If this key is longer than our search string, we need to insert // "above" this node if (node->strlen > keylen) { struct trie_node *new_node; assert(keylen == strlen); assert((!parent) || parent->children == node); new_node = new_leaf (string, strlen, ip4_address); node->strlen -= keylen; new_node->children = node; assert ((!parent) || (!left)); if (parent) { parent->children = new_node; } else if (left) { left->next = new_node; } else if ((!parent) || (!left)) { root = new_node; } return 1; } else if (strlen > keylen) { if (node->children == NULL) { // Insert leaf here struct trie_node *new_node = new_leaf (string, strlen - keylen, ip4_address); node->children = new_node; return 1; } else { // Recur on children list, store "parent" (loosely defined) return _insert(string, strlen - keylen, ip4_address, node->children, node, NULL); } } else { assert (strlen == keylen); if (node->ip4_address == 0) { node->ip4_address = ip4_address; return 1; } else { //IF IT FAILS ON READDING IT printf("I AM HERE WITH SOURABH"); fflush(stdout); return 0; } } } else { /* Is there any common substring? */ int i, cmp2, keylen2, overlap = 0; for (i = 1; i < keylen; i++) { cmp2 = compare_keys (&node->key[i], node->strlen - i, &string[i], strlen - i, &keylen2); assert (keylen2 > 0); if (cmp2 == 0) { overlap = 1; break; } } if (overlap) { // Insert a common parent, recur struct trie_node *new_node = new_leaf (&string[i], strlen - i, 0); int diff = node->strlen - i; assert ((node->strlen - diff) > 0); node->strlen -= diff; new_node->children = node; assert ((!parent) || (!left)); if (node == root) { new_node->next = node->next; node->next = NULL; root = new_node; } else if (parent) { assert(parent->children == node); new_node->next = NULL; parent->children = new_node; } else if (left) { new_node->next = node->next; node->next = NULL; left->next = new_node; } else if ((!parent) && (!left)) { root = new_node; } return _insert(string, i, ip4_address, node, new_node, NULL); } else if (cmp < 0) { if (node->next == NULL) { // Insert here struct trie_node *new_node = new_leaf (string, strlen, ip4_address); node->next = new_node; return 1; } else { // No, recur right (the node's key is "greater" than the search key) return _insert(string, strlen, ip4_address, node->next, NULL, node); } } else { // Insert here struct trie_node *new_node = new_leaf (string, strlen, ip4_address); new_node->next = node; if (node == root) root = new_node; else if (parent && parent->children == node) parent->children = new_node; } return 1; } }
int sort_main(int argc, char **argv) { FILE *fp, *outfile = stdout; char *line, **lines = NULL; char *str_ignored, *str_o, *str_t; llist_t *lst_k = NULL; int i, flag; int linecount = 0; xfunc_error_retval = 2; /* Parse command line options */ /* -o and -t can be given at most once */ opt_complementary = "o--o:t--t:" /* -t, -o: maximum one of each */ "k::"; /* -k takes list */ getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); #if ENABLE_FEATURE_SORT_BIG if (option_mask32 & FLAG_o) outfile = xfopen(str_o, "w"); if (option_mask32 & FLAG_t) { if (!str_t[0] || str_t[1]) bb_error_msg_and_die("bad -t parameter"); key_separator = str_t[0]; } /* parse sort key */ while (lst_k) { enum { FLAG_allowed_for_k = FLAG_n | /* Numeric sort */ FLAG_g | /* Sort using strtod() */ FLAG_M | /* Sort date */ FLAG_b | /* Ignore leading blanks */ FLAG_r | /* Reverse */ FLAG_d | /* Ignore !(isalnum()|isspace()) */ FLAG_f | /* Force uppercase */ FLAG_i | /* Ignore !isprint() */ 0 }; struct sort_key *key = add_key(); char *str_k = lst_k->data; const char *temp2; i = 0; /* i==0 before comma, 1 after (-k3,6) */ while (*str_k) { /* Start of range */ /* Cannot use bb_strtou - suffix can be a letter */ key->range[2*i] = str2u(&str_k); if (*str_k == '.') { str_k++; key->range[2*i+1] = str2u(&str_k); } while (*str_k) { if (*str_k == ',' && !i++) { str_k++; break; } /* no else needed: fall through to syntax error because comma isn't in OPT_STR */ temp2 = strchr(OPT_STR, *str_k); if (!temp2) bb_error_msg_and_die("unknown key option"); flag = 1 << (temp2 - OPT_STR); if (flag & ~FLAG_allowed_for_k) bb_error_msg_and_die("unknown sort type"); /* b after ',' means strip _trailing_ space */ if (i && flag == FLAG_b) flag = FLAG_bb; key->flags |= flag; str_k++; } } /* leaking lst_k... */ lst_k = lst_k->link; } #endif /* global b strips leading and trailing spaces */ if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb; /* Open input files and read data */ for (i = argv[optind] ? optind : optind-1; argv[i]; i++) { fp = stdin; if (i >= optind && NOT_LONE_DASH(argv[i])) fp = xfopen(argv[i], "r"); for (;;) { line = GET_LINE(fp); if (!line) break; if (!(linecount & 63)) lines = xrealloc(lines, sizeof(char *) * (linecount + 64)); lines[linecount++] = line; } fclose(fp); } #if ENABLE_FEATURE_SORT_BIG /* if no key, perform alphabetic sort */ if (!key_list) add_key()->range[0] = 1; /* handle -c */ if (option_mask32 & FLAG_c) { int j = (option_mask32 & FLAG_u) ? -1 : 0; for (i = 1; i < linecount; i++) if (compare_keys(&lines[i-1], &lines[i]) > j) { fprintf(stderr, "Check line %d\n", i); return 1; } return 0; } #endif /* Perform the actual sort */ qsort(lines, linecount, sizeof(char *), compare_keys); /* handle -u */ if (option_mask32 & FLAG_u) { flag = 0; /* coreutils 6.3 drop lines for which only key is the same */ /* -- disabling last-resort compare... */ option_mask32 |= FLAG_s; for (i = 1; i < linecount; i++) { if (!compare_keys(&lines[flag], &lines[i])) free(lines[i]); else lines[++flag] = lines[i]; } if (linecount) linecount = flag+1; } /* Print it */ for (i = 0; i < linecount; i++) fprintf(outfile, "%s\n", lines[i]); fflush_stdout_and_exit(EXIT_SUCCESS); }
VM_OBJ_HEADER *VM_VALUE_HASH_IMP_do_hash(VSCRIPTVM *vm, VM_VALUE_HASH_OP op, VM_VALUE_HASH_IMP *imp, VM_OBJ_HEADER *key, VM_OBJ_HEADER *value) { unsigned int hash_val; int idx, i, found; VM_VALUE_HASH_BUCKET *buck; int empty_idx = -1; VM_VALUE_HASH_BUCKET *empty_entry; char tmp_buf_rhs[100]; const char *ret_rhs; int len_rhs; ret_rhs = VM_SCALAR_to_string(vm, key, tmp_buf_rhs, &len_rhs); hash_val = VHASHFUNCTION_Bob_Jenkins_one_at_a_time((void *) ret_rhs, VHASH_STRING); idx = hash_val & (imp->buckets_count - 1); buck = imp->buckets[idx]; found = 0; if (op == VM_VALUE_HASH_INSERT) { for(;buck; buck = buck->next) { for(i=0;i<VM_VALUE_HASH_ENTRIES_PER_BUCKET;i++) { if (buck->entry[i].hash == hash_val) { if (compare_keys(vm, buck->entry[i].key, ret_rhs, len_rhs)) { found = 1; goto next; } } } buck = buck->next; } } else { for(;buck; buck = buck->next) { for(i=0;i<VM_VALUE_HASH_ENTRIES_PER_BUCKET;i++) { if (buck->entry[i].hash == hash_val) { if (compare_keys(vm, buck->entry[i].key, ret_rhs, len_rhs)) { found = 1; goto next; } } if (empty_idx == -1 && buck->entry[i].hash == 0 ) { empty_idx = i; empty_entry = buck; } } } } next: switch(op) { case VM_VALUE_HASH_FIND: if (found) { return buck->entry[i].value; } break; case VM_VALUE_HASH_INSERT: if (found) { // replace old value with new value. VM_OBJ_HEADER_release( vm->ctx, buck->entry[i].value); buck->entry[i].value = value; return 0; } if (empty_idx == -1) { // insert new bucket entry etc. etc. empty_entry = (VM_VALUE_HASH_BUCKET *) V_MALLOC(vm->ctx, sizeof(VM_VALUE_HASH_BUCKET) + VM_VALUE_HASH_ENTRIES_PER_BUCKET * sizeof(VM_VALUE_HASH_ENTRY)); if (!empty_entry) { return (VM_OBJ_HEADER *) -1; } empty_entry->next = 0; for(i =0; i < VM_VALUE_HASH_ENTRIES_PER_BUCKET; i++) { empty_entry->entry[i].hash = 0; } empty_entry->next = imp->buckets[ idx ]; imp->buckets[ idx ] = empty_entry; empty_idx = 0; } VM_OBJ_HEADER_add_ref(key); VM_OBJ_HEADER_add_ref(value); empty_entry->entry[empty_idx].hash = hash_val; empty_entry->entry[empty_idx].key = key; empty_entry->entry[empty_idx].value = value; imp->elmcount++; break; case VM_VALUE_HASH_DELETE: if (found) { buck->entry[i].hash = 0; VM_OBJ_HEADER_release( vm->ctx, buck->entry[i].key); VM_OBJ_HEADER_release( vm->ctx, buck->entry[i].value); } break; } return 0; }
OP_NAMESPACE_BEGIN int compare_keyslices(const Slice& k1, const Slice& k2, bool has_ns) { return compare_keys(k1.data(), k1.size(), k2.data(), k2.size(), has_ns); }