示例#1
0
文件: main.c 项目: seccipon/test01
/*
 * 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);
}
示例#2
0
文件: tree.c 项目: armenr/algorist
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);
}
示例#3
0
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);
}
示例#4
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);
}
示例#5
0
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);
}
示例#6
0
文件: tree.c 项目: armenr/algorist
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);
}
示例#7
0
文件: kv.c 项目: bhaprayan/pipelinedb
/*
 * 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);
}
示例#8
0
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;
  }  
}  
示例#9
0
/*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;   
}
示例#10
0
// 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;
}
示例#11
0
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));
}
示例#12
0
文件: kv.c 项目: bhaprayan/pipelinedb
/*
 * 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);
}
示例#13
0
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;
  }

}
示例#15
0
文件: main.c 项目: seccipon/test01
/*  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");
}
示例#16
0
/* 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 */
		}
	}
}
示例#17
0
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++;
	}
}
示例#18
0
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;
}
示例#19
0
文件: sort.c 项目: K0T0LI/busybox
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);
}
示例#20
0
  /* 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;
    }
  }
示例#21
0
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,&current_kc,str,str_size);
						}
					}
				}
			}
		}
	}
	return count;
}
示例#22
0
  /* 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;
        }
      }
示例#23
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.
      *
      * 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;
          }

        }
示例#24
0
  /* 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;
    }

  }
示例#25
0
/* 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;
  }
}
示例#28
0
文件: sort.c 项目: Predator-SD/Tarixy
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);
}
示例#29
0
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;
}
示例#30
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);
    }