예제 #1
0
static void
test_remove_dup_keys(int *keys, int n)
{
	int i, j, restart, *keys_sorted;

	keys_sorted = malloc(n * sizeof(int));
	do {
		restart = 0;
		memcpy(keys_sorted, keys, n * sizeof(int));
		qsort(keys_sorted, n, sizeof(int), key_cmp);
		for (i = 0; i < n - 1; i++) {
			if (key_cmp(&keys_sorted[i], &keys_sorted[i + 1]) != 0)
				continue;
			while (i < n - 1 &&
			    key_cmp(&keys_sorted[i + 1], &keys_sorted[i]) == 0)
				i++;
			restart = 1;
			for (j = 0; j < n;  j++) {
				if (key_cmp(&keys[j], &keys_sorted[i]) != 0)
					continue;
				keys[j] = test_gen_random_key();
			}
		}
	} while (restart != 0);
	free(keys_sorted);
}
예제 #2
0
파일: pos-list.c 프로젝트: kunulee/f-stm
/* flags == 0 normal flags == 1 lock flags == 2 stm flags == 3 selectvie */
int t_pos_list_remove( char *name , void *_key, int thread_num){ 
        struct list_head * head;
        struct list_node *node, *prev_node;
        unsigned long *key;
        unsigned long *k ;
        int i;
        struct list_node * next ;

        key = (unsigned long *)_key;
        head = (struct list_head *)pos_get_prime_object(name);

        TM_START(2, RW);
        prev_node = (struct list_node *)TM_LOAD(&head->head) ;
        next = (struct list_node *)TM_LOAD(&prev_node->next) ;
        // modified in here to set prev_node 
        while( prev_node ){
                if( (next == NULL ) && ( prev_node != NULL ) ){
                        //last node ;
                        #if (KEONWOO_DEBUG == 1)
                        PR_DEBUG("Last Node\n") ;
                        #endif
                        if( key_cmp(prev_node->key , key)==1){
                                node = (struct list_node *)
                                        TM_LOAD(&prev_node->next);
                                if(node==NULL) node = 0 ;
                                //head->head = node ; 
                                //TM_STORE(prev_node , node ) ;         
                                TM_STORE(&head->head , node) ;
                                PR_DEBUG("prev_node : %p\n" , prev_node) ;
                                break;
                        }
                }
               if(key_cmp(next->key , key) == 1){ // if match
                        node = ( struct list_node *)TM_LOAD(&next->next) ;
                        TM_STORE(&prev_node->next , node ) ;
                        pos_clflush_cache_range( &prev_node->next, sizeof(struct list_node)) ;
                        goto ret;
                }
                prev_node = next ;
                next = (struct list_node *)TM_LOAD(&next->next) ;
        }

        ret:
        TM_COMMIT ;
        // after commit
/*      if( next != NULL ){ 
        r_lock() ;
        pos_free(name , next->value) ;
        pos_free(name , next) ;
        r_unlock() ;    
        }*/
        return 0;
} 
예제 #3
0
ParticleGroup *Particles::group(class Texture *texture) {
  GroupList::iterator iter = std::lower_bound(
    groups.begin(), groups.end(), texture, key_cmp());

  if (iter != groups.end())
    return (*iter).second;

  // Create the particle group
  ParticleGroup *newGroup = new ParticleGroup(texture);
  groups.push_back(std::make_pair(texture, newGroup));
  std::sort(groups.begin(), groups.end(), key_cmp());
  
  return newGroup;
}
예제 #4
0
파일: map.c 프로젝트: Ankirama/Epitech
int pair_comparator(void *first, void *second)
{
  t_key_comparator	key_cmp;

  key_cmp = key_cmp_container(FALSE, NULL);
  return (key_cmp(((t_pair *)first)->key, ((t_pair *)second)->key));
}
예제 #5
0
파일: bplus.c 프로젝트: edisenwang/libmm
int find_exact(ENTRY *pe, IX_DESC *pix)
{
    int  ret;
    ENTRY e;
    copy_entry(&e, pe);
    ret = find_key(&e, pix);
    if ( ret && pci->duplicate)
    {
        do
        {
            ret = (e.recptr == pe->recptr);
            if(!ret)  
            {
                ret = next_key(&e, pci);
            }
            /*if (ret) ret = (strcmp(e.key, pe->key) == 0);*/
            if (ret) 
            {
                ret = (key_cmp(e.key, pe->key) == 0);
            }
            else
            {
                return 0;
            }

        } while(!ret);
    }

    copy_entry(pe, &e);

    return ret;
} 
예제 #6
0
/**
 * Handler for SET_DEFAULT message from client, updates
 * default identity for some service.
 *
 * @param cls unused
 * @param client who sent the message
 * @param message the message received
 */
static void
handle_set_default_message (void *cls,
                            const struct SetDefaultMessage *sdm)
{
  struct Ego *ego;
  struct GNUNET_SERVICE_Client *client = cls;
  const char *str;

  str = (const char *) &sdm[1];
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received SET_DEFAULT for service `%s' from client\n",
              str);
  for (ego = ego_head; NULL != ego; ego = ego->next)
  {
    if (0 == key_cmp (ego->pk,
                      &sdm->private_key))
    {
      GNUNET_CONFIGURATION_set_value_string (subsystem_cfg,
                                             str,
                                             "DEFAULT_IDENTIFIER",
                                             ego->identifier);
      if (GNUNET_OK !=
          GNUNET_CONFIGURATION_write (subsystem_cfg,
                                      subsystem_cfg_file))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                    _("Failed to write subsystem default identifier map to `%s'.\n"),
                    subsystem_cfg_file);
      send_result_code (client, 0, NULL);
      GNUNET_SERVICE_client_continue (client);
      return;
    }
  }
  send_result_code (client, 1, _("Unknown ego specified for service (internal error)"));
  GNUNET_SERVICE_client_continue (client);
}
예제 #7
0
파일: pos-list.c 프로젝트: kunulee/f-stm
void *pos_list_lookup(char *name, void *_key)
{
	struct list_head * head;
	struct list_node *node;
	unsigned long *key;
	int i;

	key = (unsigned long *)_key;
	printf("[%s] key = %p\n",__func__ ,key) ; 	
	head = (struct list_head *)pos_get_prime_object(name);
	printf("[%s] head = %p\n", __func__, head) ;	
	node = head->head;
	printf("[%s] node = %p\n" , __func__, node) ; 


	while (node) {

#if MODE == 2
		node += OFFSET_BASE;
#endif
		//printf("DD\n") ; 	
		printf(" node->key : %d\n" , node->key) ;
		if (key_cmp(node->key, key) == 1)
			return node->value;

		node = node->next;
	}

	return NULL;
}
예제 #8
0
파일: bplus.c 프로젝트: edisenwang/libmm
/*  general BPLUS block level functions  */
static int find_block(ENTRY *pe, int *poff)
{
    register int pos, nextpos;
    int ret;
    pos = -1;
    nextpos = 0;
    ret = 1;

    /*printf("block_ptr->bend = %d.\n", block_ptr->bend);*/
    while ( nextpos < block_ptr->bend)
    {
        /*ret = strcmp((char *)(pe->key),*/
        /*(char *)(ENT_ADR(block_ptr, nextpos)->key));*/
        ret = key_cmp((char *)(pe->key),(char *)(ENT_ADR(block_ptr, nextpos)->key));
        /*printf("debug: in find_block()2 key1=%s, key2=%s, nextpos = %d ret=%d\n", pe->key, ENT_ADR(block_ptr, nextpos)->key, nextpos, ret);*/
        if (ret <= 0)
        {
            if (ret == 0) 
            {
                pos = nextpos;
            }

            break;
        }

        pos = nextpos;
        nextpos = next_entry(pos);
    }
    /*printf("debug: in find_block()4 nextpos = %d, block_ptr->bend=%d\t", nextpos, block_ptr->bend);*/
    //getchar();
    CO(pci->level) = pos;
    *poff = pos;
    /*printf("debug: out of find_block().\n\n");*/
    return ret;
} 
예제 #9
0
/**
 * Handler for SET_DEFAULT message from client, updates
 * default identity for some service.
 *
 * @param cls unused
 * @param client who sent the message
 * @param message the message received
 */
static void
handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client,
			    const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_IDENTITY_SetDefaultMessage *sdm;
  uint16_t size;
  uint16_t name_len;
  struct Ego *ego;
  const char *str;

  size = ntohs (message->size);
  if (size <= sizeof (struct GNUNET_IDENTITY_SetDefaultMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) message;
  name_len = ntohs (sdm->name_len);
  GNUNET_break (0 == ntohs (sdm->reserved));
  if (name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) != size)
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  str = (const char *) &sdm[1];
  if ('\0' != str[name_len - 1])
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Received SET_DEFAULT for service `%s' from client\n",
	      str);
  for (ego = ego_head; NULL != ego; ego = ego->next)
  {
    if (0 == key_cmp (ego->pk,
		      &sdm->private_key))
    {
      GNUNET_CONFIGURATION_set_value_string (subsystem_cfg,
					     str,
					     "DEFAULT_IDENTIFIER",
					     ego->identifier);
      if (GNUNET_OK !=
	  GNUNET_CONFIGURATION_write (subsystem_cfg,
				      subsystem_cfg_file))
	GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		    _("Failed to write subsystem default identifier map to `%s'.\n"),
		    subsystem_cfg_file);
      send_result_code (client, 0, NULL);
      GNUNET_SERVER_receive_done (client, GNUNET_OK);
      return;
    }
  }
  send_result_code (client, 1, _("Unknown ego specified for service (internal error)"));
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
예제 #10
0
파일: hhash.c 프로젝트: gitter-badger/knot
/*! \brief Universal comparator. */
static int universal_cmp(uint32_t i1, uint32_t i2, hhash_t *tbl)
{
	/* Get item data from indirect positions. */
	void *k1 = tbl->item[i1].d;
	void *k2 = tbl->item[i2].d;

	/* Read key lengths. */
	return key_cmp(KEY_STR(k1), key_readlen(k1), KEY_STR(k2), key_readlen(k2));
}
예제 #11
0
파일: map.c 프로젝트: Ankirama/Epitech
void *map_get_elem(t_map map, void *key, t_key_comparator key_cmp)
{
  t_map head;

  head = map;
  while (head != NULL && key_cmp(key, ((t_pair *)(head->value))->key) != 0)
    head = head->next;
  if (head == NULL)
    return (NULL);
  return (((t_pair *)(head->value))->value);
}
예제 #12
0
int match_cmp(match_t *m, const entry_t *e)
{
    int ans = key_cmp(&m->key, &e->key);
    /* Calculate and compare value if key matches */
    if (ans == 0) {
        if (m->value != m->source)
            m->value = m->source;
        ans = m->value - e->value;
    }
    return ans;
}
예제 #13
0
파일: btree_aux.c 프로젝트: joerong666/hidb
int fkv_cmp(fkv_t *kv1, fkv_t *kv2)
{
    char k1[G_KSIZE_LIMIT], k2[G_KSIZE_LIMIT];
    mkey_t mk1, mk2;

    mk1.len = kv1->kshare.len + kv1->kdelt.len;
    mk1.data = k1;

    mk2.len = kv2->kshare.len + kv2->kdelt.len;
    mk2.data = k2;

    if (kv1->kshare.len > 0) {
        memcpy(k1, kv1->kshare.data, kv1->kshare.len);
    }
    memcpy(k1 + kv1->kshare.len, kv1->kdelt.data, kv1->kdelt.len);

    if (kv2->kshare.len > 0) {
        memcpy(k2, kv2->kshare.data, kv2->kshare.len);
    }
    memcpy(k2 + kv2->kshare.len, kv2->kdelt.data, kv2->kdelt.len);

    return key_cmp(&mk1, &mk2);
}
예제 #14
0
int save_index (int writing_binlog) {
  hash_count = get_entry_cnt (); 
//  hash_entry_t **p = zzmalloc (hash_count * sizeof (hash_entry_t *)); 
  char *newidxname = NULL;

  if (engine_snapshot_replica) {
    newidxname = get_new_snapshot_name (engine_snapshot_replica, log_cur_pos(), engine_snapshot_replica->replica_prefix);
  }

  if (!newidxname || newidxname[0] == '-') {
    fprintf (stderr, "cannot write index: cannot compute its name\n");
    exit (1);
  }

  if (log_cur_pos() == jump_log_pos) {
    fprintf (stderr, "skipping generation of new snapshot %s for position %lld: snapshot for this position already exists\n",
       newidxname, jump_log_pos);
    return 0;
  } 

  if (verbosity > 0) {
    fprintf (stderr, "creating index %s at log position %lld\n", newidxname, log_cur_pos());
  }

  newidx_fd = open (newidxname, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL, 0660);

  if (newidx_fd < 0) {
    fprintf (stderr, "cannot create new index file %s: %m\n", newidxname);
    exit (1);
  }

  index_header header;
  memset (&header, 0, sizeof (header));

  header.magic = PMEMCACHED_INDEX_MAGIC;
  header.created_at = time (NULL);
  header.log_pos1 = log_cur_pos ();
  header.log_timestamp = log_read_until;
  if (writing_binlog) {
    relax_write_log_crc32 ();
  } else {
    relax_log_crc32 (0);
  }
  header.log_pos1_crc32 = ~log_crc32_complement;
  p = zzmalloc (hash_count * sizeof (hash_entry_t *)); 
  assert (p);
  int x = (dump_pointers (p, 0, hash_count));
  if (x != hash_count) {
    vkprintf (0, "dump_pointers = %d, hash_count = %d\n", x, hash_count);
    assert (0);
  }

  int p1 = 0;
  int p2 = 0;
  int total_elem = 0;
  while (p1 < hash_count || p2 < index_size) {
    //fprintf (stderr, "<");
    int c = key_cmp(p1, p2);
    //fprintf (stderr, ">");
    if (c == 0) {
      do_pmemcached_merge (p[p1]->key, p[p1]->key_len);
    }
    if (c <= 0) {
      assert (p1 < hash_count);
      assert (p[p1]);
      if (p[p1]->data_len < 0) {
        total_elem--;
      }      
      p1++; 
    } 
    if (c >= 0) {
      p2++; 
    } 
    total_elem++;
  }

  header.nrecords = total_elem;
  writeout (&header, get_index_header_size (&header) );;

  long long shift = 0;//16*total_elem;

  p1 = 0;
  p2 = 0;
  while (p1 < hash_count || p2 < index_size) {
    int c = key_cmp(p1, p2);
    if (c <= 0) {
      if (p[p1]->data_len >= 0){
        writeout_long (shift);
        shift += 13 + p[p1]->data_len + p[p1]->key_len;
      }
      p1++; 
    } 
    if (c >= 0) {
      if (c > 0) {
        writeout_long (shift);
        shift += 13 + index_get_by_idx (p2)->data_len + index_get_by_idx (p2)->key_len;
      }
      p2++;
    } 
  }
  writeout_long (shift);

  if (verbosity >= 3) {
    fprintf (stderr, "writing offsets done\n");
  }

  if (verbosity >= 3) {
    fprintf (stderr, "writing binary data\n");
  }
  p1 = 0;
  p2 = 0;
  while (p1 < hash_count || p2 < index_size) {
    int c = key_cmp(p1, p2);
    if (c <= 0) {
      if (p[p1]->data_len >= 0){
        struct hash_entry* entry = p[p1];
        vkprintf (4, "Writing to index: key_len = %d, data_len = %d, p1 = %d, p[p1] = %p\n", (int)entry->key_len, entry->data_len, p1, p[p1]);
        writeout_short (entry->key_len);
        writeout_short (entry->flags);
        writeout_int (entry->data_len);
        writeout_int (entry->exp_time);
        writeout (entry->key, entry->key_len);
        writeout (entry->data, entry->data_len);
        writeout_char (0);
      }
      p1++; 
    } 
    if (c >= 0) {
      if (c > 0) {
        struct index_entry *entry =  index_get_by_idx (p2);
        writeout (entry, sizeof(struct index_entry) + entry->key_len + entry->data_len);
        writeout_char (0);
      }
      p2++;
    } 
  }
  if (verbosity >= 3) {
    fprintf (stderr, "writing binary data done\n");
  }

  flushout ();

  assert (fsync (newidx_fd) >= 0);
  assert (close (newidx_fd) >= 0);

  if (verbosity >= 3) {
    fprintf (stderr, "writing index done\n");
  }

  if (rename_temporary_snapshot (newidxname)) {
    fprintf (stderr, "cannot rename new index file from %s: %m\n", newidxname);
    unlink (newidxname);
    exit (1);
  }

  print_snapshot_name (newidxname);
  return 0;
}
예제 #15
0
파일: pos-list.c 프로젝트: kunulee/f-stm
int t_t_pos_list_remove( char * name , void *_key){ 
	if( flags_num & NORMAL_ROUTINE ){ 
		struct list_head * head ; 	
		struct list_node * node , ** prev_node ; 	
		// stm prev
		struct list_node * sprev_node ; 	
		struct list_node * next ;
		unsigned long * key ; 	
		
		key = (unsigned long *)_key ; 	
		head = (struct list_head *)pos_get_prime_object(name) ; 	
		
		if( flags_num & LOCK_ROUTINE ){ // if lock flags settings. 
			llock() ; //lock 
			prev_node = &head->head ; 	
			node = head->head ; 	
			while(node){ 
				if( key_cmp( node->key , key ) == 1 ){ 
					*prev_node = node->next ; 	
					PR_DEBUG("%p\n" , node->next) ;
					/* 
					pos_free(name , node->value) ; 	
					pos_free(name , node) ; 	
					*/
					pos_clflush_cache_range( prev_node , sizeof(struct list_node)) ; 	

					lunlock() ; //unlock 
					return 0 ; 	
				}
				prev_node = &node->next ; 	
				node = node->next ; 	
			}
			lunlock() ; //unlock
			return -1;	
		}else if( flags_num & STM_ROUTINE ){ //if stm flags settings. 
			/*PR_DEBUG("DA\n") ;
			TM_START(2,RW) ; 
			struct list_node * p , * n ; 	
			p = (struct list_node *)TM_LOAD(&head->head) ; 		
			PR_DEBUG("A\n") ;
			n = (struct list_node *)TM_LOAD(&p->next) ; 	
			PR_DEBUG("D\n") ; 	
			PR_DEBUG("p = %p , n = %p\n" , p, n ) ; 
			while(1){ 
				if(key_cmp(n->key , key ) == 1){
					PR_DEBUG("%d fount\n" , *(int*)p->key) ;	
					break; 	
				}
				p = n ; 	
				n = (struct list_node *)TM_LOAD(&p->next);
			}
			PR_DEBUG("DD\n") ; 
			node = (struct list_node *)TM_LOAD(&n->next);	
			PR_DEBUG("DD\n") ; 
			TM_STORE(&p->next , node) ; 	
			PR_DEBUG("DD\n") ; 
			//TM_POS_FREE// 
			TM_COMMIT ; */ 
			TM_START(2,RW) ; 	
			#if (KEONWOO_DEBUG == 1 )
			PR_DEBUG("[TM_START]\n") ; 	
			#endif 
			sprev_node = (struct list_node *)TM_LOAD(&head->head); 	
			next = (struct list_node*)TM_LOAD(&sprev_node->next); 	
//			while( next || ((next==NULL)&&(sprev_node!=NULL))){ 
			while(sprev_node){ 
				if( (next==NULL) && (sprev_node!=NULL) ){
					
					PR_DEBUG("LastNode\n");
					if( key_cmp( sprev_node->key , key ) == 1){
						PR_DEBUG("[%d] [%d]\n" , *(int*)sprev_node->key,*(int*)key);
						PR_DEBUG("IN HERE\n") ;
						node = (struct list_node*)TM_LOAD(&sprev_node->next);
						if( node == NULL ) node = 0 ;
						PR_DEBUG("node ; %p\n" , node) ;
						//sprev_node = node ; 
						//head->head = node ; 	
						TM_STORE(&head->head,node);
						PR_DEBUG("head->head: %p\n" , head->head ) ;	
						//pos_clflush_cache_range(&sprev_node->next,sizeof(struct list_node)) ; 		
						break ;
					}
				}
				if( key_cmp( next->key , key ) == 1 ){ 
					node = (struct list_node *)TM_LOAD(&next->next); 	
					TM_STORE(&sprev_node->next ,node ); 	
					pos_clflush_cache_range(&sprev_node->next ,sizeof(struct list_node)) ; 	
					break; // out to while loop.
				}
				sprev_node = next ; 	
				next = (struct list_node *)TM_LOAD(&next->next);
			}
			 
			TM_COMMIT ; 	
			#if (KEONWOO_DEBUG == 1) 
			PR_DEBUG("[TM_COMMIT]\n") ;
			#endif 
		}
	}
}
예제 #16
0
파일: btrfs.c 프로젝트: kissthink/os-grub2
static grub_err_t
lower_bound (struct grub_btrfs_data *data,
	     const struct grub_btrfs_key *key_in, 
	     struct grub_btrfs_key *key_out,
	     grub_disk_addr_t root,
	     grub_disk_addr_t *outaddr, grub_size_t *outsize,
	     struct grub_btrfs_leaf_descriptor *desc)
{
  grub_disk_addr_t addr = root;
  int depth = -1;

  if (desc)
    {
      desc->allocated = 16;
      desc->depth = 0;
      desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated);
      if (!desc->data)
	return grub_errno;
    }

  grub_dprintf ("btrfs",
		"retrieving %" PRIxGRUB_UINT64_T
		" %x %" PRIxGRUB_UINT64_T "\n",
		key_in->object_id, key_in->type, key_in->offset);

  while (1)
    {
      grub_err_t err;
      struct btrfs_header head;

    reiter:
      depth++;
      /* FIXME: preread few nodes into buffer. */
      err = grub_btrfs_read_logical (data, addr, &head, sizeof (head));
      if (err)
	return err;
      addr += sizeof (head);
      if (head.level)
	{
	  unsigned i;
	  struct grub_btrfs_internal_node node, node_last;
	  int have_last = 0;
	  grub_memset (&node_last, 0, sizeof (node_last));
	  for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++)
	    {
	      err = grub_btrfs_read_logical (data, addr + i * sizeof (node),
					     &node, sizeof (node));
	      if (err)
		return err;

	      grub_dprintf ("btrfs",
			    "internal node (depth %d) %" PRIxGRUB_UINT64_T
			    " %x %" PRIxGRUB_UINT64_T "\n", depth,
			    node.key.object_id, node.key.type, node.key.offset);
	      
	      if (key_cmp (&node.key, key_in) == 0)
		{
		  err = GRUB_ERR_NONE;
		  if (desc)
		    err = save_ref (desc, addr - sizeof (head), i,
				    grub_le_to_cpu32 (head.nitems), 0);
		  if (err)
		    return err;
		  addr = grub_le_to_cpu64 (node.addr);
		  goto reiter;
		}
	      if (key_cmp (&node.key, key_in) > 0)
		break;
	      node_last = node;
	      have_last = 1;
	    }
	  if (have_last)
	    {
	      err = GRUB_ERR_NONE;
	      if (desc)
		err = save_ref (desc, addr - sizeof (head), i - 1,
				 grub_le_to_cpu32 (head.nitems), 0);
	      if (err)
		return err;
	      addr = grub_le_to_cpu64 (node_last.addr);
	      goto reiter;
	    }
	  *outsize = 0;
	  *outaddr = 0;
	  grub_memset (key_out, 0, sizeof (*key_out));
	  if (desc)
	    return save_ref (desc, addr - sizeof (head), -1,
			     grub_le_to_cpu32 (head.nitems), 0);
	  return GRUB_ERR_NONE;
	}
      {
	unsigned i;
	struct grub_btrfs_leaf_node leaf, leaf_last;
	int have_last = 0;
	for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++)
	  {
	    err = grub_btrfs_read_logical (data, addr + i * sizeof (leaf),
					   &leaf, sizeof (leaf));
	    if (err)
	      return err;
	    
	    grub_dprintf ("btrfs",
			  "leaf (depth %d) %" PRIxGRUB_UINT64_T
			  " %x %" PRIxGRUB_UINT64_T "\n", depth,
			  leaf.key.object_id, leaf.key.type, leaf.key.offset);

	    if (key_cmp (&leaf.key, key_in) == 0)
	      {
		grub_memcpy (key_out, &leaf.key, sizeof(*key_out));
		*outsize = grub_le_to_cpu32 (leaf.size);
		*outaddr = addr + grub_le_to_cpu32 (leaf.offset);
		if (desc)
		  return save_ref (desc, addr - sizeof (head), i,
				   grub_le_to_cpu32 (head.nitems), 1);
		return GRUB_ERR_NONE;	      
	      }
	    
	    if (key_cmp (&leaf.key, key_in) > 0)
	      break;
	    
	    have_last = 1;
	    leaf_last = leaf;
	  }

	if (have_last)
	  {
	    grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out));
	    *outsize = grub_le_to_cpu32 (leaf_last.size);
	    *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset);
	    if (desc)
	      return save_ref (desc, addr - sizeof (head), i - 1,
			       grub_le_to_cpu32 (head.nitems), 1);
	    return GRUB_ERR_NONE;	      
	  }
	*outsize = 0;
	*outaddr = 0;
	grub_memset (key_out, 0, sizeof (*key_out));
	if (desc)
	  return save_ref (desc, addr - sizeof (head), -1,
			   grub_le_to_cpu32 (head.nitems), 1);
	return GRUB_ERR_NONE;
      }
    }
}
예제 #17
0
파일: btree_aux.c 프로젝트: joerong666/hidb
int mkv_cmp(mkv_t *kv1, mkv_t *kv2)
{
    return key_cmp(&kv1->k, &kv2->k);
}