コード例 #1
0
ファイル: binsearch.c プロジェクト: BelfordZ/cAlgs
int main(void)
{
   int A[10000];
   int n, i, x, index;

   n = 0;
   while (scanf("%d", &x) == 1 && n < 10000) {
      if (!bin_search(A, n, x, &index)) {
         n++;
         insert(A, n, x, index);
      }
      printf("List:");
      for (i = 0; i < n; i++) {
         printf(" %d", A[i]);
         if (i == index) {
            printf("*");
         }
      }
      printf("\n");
   }
   return 0;
}
コード例 #2
0
ファイル: listing.c プロジェクト: Sighter/xwaxed-testing
struct record* listing_insert(struct listing *ls, struct record *item,
                              int sort)
{
    bool found;
    size_t z;

    z = bin_search(ls->record, ls->entries, item, sort, &found);
    if (found)
        return ls->record[z];

    /* Insert the new item */

    if (enlarge(ls, ls->entries + 1) == -1)
        return NULL;

    memmove(ls->record + z + 1, ls->record + z,
            sizeof(struct record*) * (ls->entries - z));
    ls->record[z] = item;
    ls->entries++;

    return item;
}
コード例 #3
0
ファイル: piojo_btree.c プロジェクト: eliangidoni/piojo
/* Binary search for key. */
static iter_t
search_node(const void *key, const piojo_btree_t *tree)
{
        bool found_p;
        size_t idx;
        iter_t iter;
        bnode_t *bnode = tree->root;

        iter.bnode = NULL;
        while (bnode->ecnt > 0){
                idx = bin_search(key, tree, bnode, &found_p);
                if (found_p){
                        iter.bnode = bnode;
                        iter.eidx = idx;
                        break;
                }else if (bnode->leaf_p){
                        break;
                }
                bnode = bnode->children[idx];
        }
        return iter;
}
コード例 #4
0
ファイル: wnutil.c プロジェクト: ARIA-VALUSPA/FlipperMMDS
unsigned int GetKeyForOffset(char *loc)
{
    unsigned int key;
    char rloc[11] = "";
    char *line;
    char searchdir[256], tmpbuf[256];

    /* Try to open file in case wn_init wasn't called */

    if (!revkeyindexfp) {
	strcpy(searchdir, SetSearchdir());
	sprintf(tmpbuf, REVKEYIDXFILE, searchdir);
	revkeyindexfp = fopen(tmpbuf, "r");
    }
    if (revkeyindexfp) {
	if ((line = bin_search(loc, revkeyindexfp)) != NULL) {
	    sscanf(line, "%s %d", rloc, &key );
	    return(key);
	}
    }
    return(0);
}
コード例 #5
0
ファイル: win9x.cpp プロジェクト: Artorios/IDAplugins-1
//--------------------------------------------------------------------------
// find all dwords equal to 'ea' and remember their translations
// search in the current module
static bool calc_thunk_target(uint32 ea32, uint32 imp32)
{
  bool matched = false;

  for ( ea_t pos = curmod.startEA;
        pos <= curmod.endEA
     && (pos = bin_search(pos, curmod.endEA, (uchar *)&ea32, NULL,
                          4, BIN_SEARCH_FORWARD,
                          BIN_SEARCH_NOBREAK|BIN_SEARCH_CASE)) != BADADDR;
        pos += sizeof(DWORD) )
  {
    if ( pos & 3 )
      continue;

    flags_t F = getFlags(pos);
    if( isTail(F) )
      continue;

    matched = true;
    thunks[pos] = imp32;
  }
  return matched;
}
コード例 #6
0
ファイル: wnutil.c プロジェクト: AdityaChaudhary/NatI
char *GetOffsetForKey(unsigned int key)
{
    unsigned int rkey;
    char ckey[7];
    static char loc[11] = "";
    char *line;
    char searchdir[256], tmpbuf[256];

    /* Try to open file in case wn_init wasn't called */

    if (!keyindexfp) {
	strcpy(searchdir, SetSearchdir());
	sprintf(tmpbuf, KEYIDXFILE, searchdir);
	keyindexfp = fopen(tmpbuf, "r");
    }
    if (keyindexfp) {
	sprintf(ckey, "%6.6d", key);
	if ((line = bin_search(ckey, keyindexfp)) != NULL) {
	    sscanf(line, "%d %s", &rkey, loc);
	    return(loc);
	}
    } 
    return(NULL);
}
コード例 #7
0
ファイル: reiserfs_stree.c プロジェクト: edgar-pek/PerspicuOS
int
search_by_key(struct reiserfs_sb_info *p_s_sbi,
    const struct cpu_key * p_s_key, /* Key to search. */
    struct path * p_s_search_path,  /* This structure was allocated and
				       initialized by the calling function.
				       It is filled up by this function. */
    int n_stop_level)               /* How far down the tree to search. To
				       stop at leaf level - set to
				       DISK_LEAF_NODE_LEVEL */
{
	int error;
	int n_node_level, n_retval;
	int n_block_number, expected_level, fs_gen;
	struct path_element *p_s_last_element;
	struct buf *p_s_bp, *tmp_bp;

	/*
	 * As we add each node to a path we increase its count. This means that
	 * we must be careful to release all nodes in a path before we either
	 * discard the path struct or re-use the path struct, as we do here.
	 */
	decrement_counters_in_path(p_s_search_path);

	/*
	 * With each iteration of this loop we search through the items in the
	 * current node, and calculate the next current node(next path element)
	 * for the next iteration of this loop...
	 */
	n_block_number = SB_ROOT_BLOCK(p_s_sbi);
	expected_level = -1;

	reiserfs_log(LOG_DEBUG, "root block: #%d\n", n_block_number);

	while (1) {
		/* Prep path to have another element added to it. */
		reiserfs_log(LOG_DEBUG, "path element #%d\n",
		    p_s_search_path->path_length);
		p_s_last_element = PATH_OFFSET_PELEMENT(p_s_search_path,
		    ++p_s_search_path->path_length);
		fs_gen = get_generation(p_s_sbi);

		/*
		 * Read the next tree node, and set the last element in the
		 * path to have a pointer to it.
		 */
		reiserfs_log(LOG_DEBUG, "reading block #%d\n",
		    n_block_number);
		if ((error = bread(p_s_sbi->s_devvp,
		    n_block_number * btodb(p_s_sbi->s_blocksize),
		    p_s_sbi->s_blocksize, NOCRED, &tmp_bp)) != 0) {
			reiserfs_log(LOG_DEBUG, "error reading block\n");
			p_s_search_path->path_length--;
			pathrelse(p_s_search_path);
			return (IO_ERROR);
		}
		reiserfs_log(LOG_DEBUG, "blkno = %ju, lblkno = %ju\n",
		    (intmax_t)tmp_bp->b_blkno, (intmax_t)tmp_bp->b_lblkno);

		/*
		 * As i didn't found a way to handle the lock correctly,
		 * i copy the data into a fake buffer
		 */
		reiserfs_log(LOG_DEBUG, "allocating p_s_bp\n");
		p_s_bp = malloc(sizeof *p_s_bp, M_REISERFSPATH, M_WAITOK);
		if (!p_s_bp) {
			reiserfs_log(LOG_DEBUG, "error allocating memory\n");
			p_s_search_path->path_length--;
			pathrelse(p_s_search_path);
			brelse(tmp_bp);
			return (IO_ERROR);
		}
		reiserfs_log(LOG_DEBUG, "copying struct buf\n");
		bcopy(tmp_bp, p_s_bp, sizeof(struct buf));

		reiserfs_log(LOG_DEBUG, "allocating p_s_bp->b_data\n");
		p_s_bp->b_data = malloc(p_s_sbi->s_blocksize,
		    M_REISERFSPATH, M_WAITOK);
		if (!p_s_bp->b_data) {
			reiserfs_log(LOG_DEBUG, "error allocating memory\n");
			p_s_search_path->path_length--;
			pathrelse(p_s_search_path);
			free(p_s_bp, M_REISERFSPATH);
			brelse(tmp_bp);
			return (IO_ERROR);
		}
		reiserfs_log(LOG_DEBUG, "copying buffer data\n");
		bcopy(tmp_bp->b_data, p_s_bp->b_data, p_s_sbi->s_blocksize);
		brelse(tmp_bp);
		tmp_bp = NULL;

		reiserfs_log(LOG_DEBUG, "...done\n");
		p_s_last_element->pe_buffer = p_s_bp;

		if (expected_level == -1)
			expected_level = SB_TREE_HEIGHT(p_s_sbi);
		expected_level--;
		reiserfs_log(LOG_DEBUG, "expected level: %d (%d)\n",
		    expected_level, SB_TREE_HEIGHT(p_s_sbi));

		/* XXX */ 
		/*
		 * It is possible that schedule occurred. We must check
		 * whether the key to search is still in the tree rooted
		 * from the current buffer. If not then repeat search
		 * from the root.
		 */
		if (fs_changed(fs_gen, p_s_sbi) &&
		    (!B_IS_IN_TREE(p_s_bp) ||
		     B_LEVEL(p_s_bp) != expected_level ||
		     !key_in_buffer(p_s_search_path, p_s_key, p_s_sbi))) {
			reiserfs_log(LOG_DEBUG,
			    "the key isn't in the tree anymore\n");
			decrement_counters_in_path(p_s_search_path);

			/*
			 * Get the root block number so that we can repeat
			 * the search starting from the root.
			 */
			n_block_number = SB_ROOT_BLOCK(p_s_sbi);
			expected_level = -1;

			/* Repeat search from the root */
			continue;
		}

		/*
		 * Make sure, that the node contents look like a node of
		 * certain level
		 */
		if (!is_tree_node(p_s_bp, expected_level)) {
			reiserfs_log(LOG_WARNING,
			    "invalid format found in block %ju. Fsck?",
			    (intmax_t)p_s_bp->b_blkno);
			pathrelse (p_s_search_path);
			return (IO_ERROR);
		}

		/* Ok, we have acquired next formatted node in the tree */
		n_node_level = B_LEVEL(p_s_bp);
		reiserfs_log(LOG_DEBUG, "block info:\n");
		reiserfs_log(LOG_DEBUG, "  node level:  %d\n",
		    n_node_level);
		reiserfs_log(LOG_DEBUG, "  nb of items: %d\n",
		    B_NR_ITEMS(p_s_bp));
		reiserfs_log(LOG_DEBUG, "  free space:  %d bytes\n",
		    B_FREE_SPACE(p_s_bp));
		reiserfs_log(LOG_DEBUG, "bin_search with :\n"
		    "  p_s_key = (objectid=%d, dirid=%d)\n"
		    "  B_NR_ITEMS(p_s_bp) = %d\n"
		    "  p_s_last_element->pe_position = %d (path_length = %d)\n",
		    p_s_key->on_disk_key.k_objectid,
		    p_s_key->on_disk_key.k_dir_id,
		    B_NR_ITEMS(p_s_bp),
		    p_s_last_element->pe_position,
		    p_s_search_path->path_length);
		n_retval = bin_search(p_s_key, B_N_PITEM_HEAD(p_s_bp, 0),
		    B_NR_ITEMS(p_s_bp),
		    (n_node_level == DISK_LEAF_NODE_LEVEL) ? IH_SIZE : KEY_SIZE,
		    &(p_s_last_element->pe_position));
		reiserfs_log(LOG_DEBUG, "bin_search result: %d\n",
		    n_retval);
		if (n_node_level == n_stop_level) {
			reiserfs_log(LOG_DEBUG, "stop level reached (%s)\n",
			    n_retval == ITEM_FOUND ? "found" : "not found");
			return (n_retval);
		}

		/* We are not in the stop level */
		if (n_retval == ITEM_FOUND)
			/*
			 * Item has been found, so we choose the pointer
			 * which is to the right of the found one
			 */
			p_s_last_element->pe_position++;

		/*
		 * If item was not found we choose the position which is
		 * to the left of the found item. This requires no code,
		 * bin_search did it already.
		 */

		/*
		 * So we have chosen a position in the current node which
		 * is an internal node. Now we calculate child block number
		 * by position in the node.
		 */
		n_block_number = B_N_CHILD_NUM(p_s_bp,
		    p_s_last_element->pe_position);
	}

	reiserfs_log(LOG_DEBUG, "done\n");
	return (0);
}
コード例 #8
0
ファイル: lines.cpp プロジェクト: FredericSH/snek
//helper function to find the index
int llget_index(llist ll, int pivot){
  return bin_search(ll, pivot, 0, ll->length);
}
コード例 #9
0
ファイル: xp2.c プロジェクト: TimLand/datacl
int
main(
     int argc,
     char **argv
     )
{
  int status = 0;
  char *t1file = NULL, *t2file = NULL, *opfile = NULL;
  char *X1 = NULL; size_t nX1 = 0;
  char *X2 = NULL; size_t nX2 = 0;
  F1TYPE *T1 = NULL;
  F2TYPE *T2 = NULL;
  int mid, pid, tid, xpid;
  FILE *ofp = NULL;
  int nR1, nR2, lb, ub, tlb, tub;
  F4TYPE *tids = NULL; int sz_tids = 8192; int n_tids = 0;

  tids = (F4TYPE *)malloc(sz_tids * sizeof(F4TYPE));
  return_if_malloc_failed(tids);
  if ( argc != 4 ) {
    fprintf(stderr, "Usage is %s <tbl1> <tbl2> <optbl> \n", argv[0]); 
    go_BYE(-1); 
  }
  t1file = argv[1];
  t2file = argv[2];
  opfile = argv[3];
  if ( strcmp(t1file, t2file) == 0 ) { go_BYE(-1); }
  if ( strcmp(t2file, opfile) == 0 ) { go_BYE(-1); }

  ofp = fopen(opfile, "wb");
  return_if_fopen_failed(ofp,  opfile, "wb");
  // mmap first file 
  status = rs_mmap(t1file, &X1, &nX1, 0);
  cBYE(status);
  nR1 = nX1 / sizeof(F1TYPE);
  if ( nR1 * sizeof(F1TYPE) != nX1 ) { go_BYE(-1); }
  if ( nR1 < 1 ) { go_BYE(-1); }
  T1 = (F1TYPE *)X1;

  // mmap first file 
  status = rs_mmap(t2file, &X2, &nX2, 0);
  cBYE(status);
  nR2 = nX2 / sizeof(F2TYPE);
  if ( nR2 * sizeof(F2TYPE) != nX2 ) { go_BYE(-1); }
  if ( nR2 < 1 ) { go_BYE(-1); }
  T2 = (F2TYPE *)X2;

  for ( int i = 0; i < nR1; ) {
    int j;
    pid  = T1[i].pid;
    for ( j = i + 1; j < nR1; j++ ) { 
      xpid   = T1[j].pid;
      if ( xpid != pid ) { break; }
    }
    /* This means that rows with lb = i and ub = j all belong to the
     * same project */
        for ( int k = i; k < j; k++ ) { 
          mid  = T1[k].mid;
          status = bin_search((F3TYPE *)T2, nR2, mid, &lb, &ub);
	  cBYE(status);
          /* All the titles in rows lb to ub belong to member mid */
          for ( int l = lb; l < ub; l++ ) { 
            tid = T2[l].tid;
            status = bin_search((F3TYPE *)tids, n_tids, tid, &tlb, &tub);
	    cBYE(status);
	    if ( tlb < 0 ) { /* not found */
	      for ( int dbg = 0; dbg < n_tids; dbg++ ) { 
		if ( tids[dbg].tid == tid ) { 
		  go_BYE(-1); // ERROR 
		}
	      }
	      if ( n_tids >= sz_tids ) { 
		go_BYE(-1); // TO BE IMPLEMENTED
	      }
	      tids[n_tids].tid = tid;
	      tids[n_tids].cnt = 1;
	      n_tids++;
	      qsort(tids, n_tids, sizeof(F4TYPE), sort2_asc_int);
	    }
	    else {
	      if ( (tub - tlb) > 1 ) { 
		 go_BYE(-1); // title is not unique
	      }
	      tids[tlb].cnt = tids[tlb].cnt + 1;
	    }
          }
        }
	if ( ( pid % 1000 ) == 0 ) {
	  fprintf(stderr, "Completed project %d \n", pid);
	}
	for ( int ii = 0; ii < n_tids; ii++ ) { 
	  int tid_ii, cnt_ii;
	  long long cnt;
	  tid_ii = tids[ii].tid;
	  cnt_ii = tids[ii].cnt;
	  for ( int jj = ii+1; jj < n_tids; jj++ ) { 
	    int tid_jj, cnt_jj;
	    long long ll_cnt;
	    tid_jj = tids[jj].tid;
	    cnt_jj = tids[jj].cnt;
	    // We write a strange format. Essentially, we write 2 long
	    // longs. First is created by concatenating tid_ii and
	    // tid_jj. Second is the count promoted to a long long
	    fwrite(&tid_ii, sizeof(int), 1, ofp);
	    fwrite(&tid_jj, sizeof(int), 1, ofp);
	    cnt = cnt_ii * cnt_jj;
	    ll_cnt = (long long)cnt;
	    fwrite(&ll_cnt, sizeof(long long), 1, ofp);
	  }
	}
	i = j;
	for ( int ii = 0; ii < n_tids; ii++ ) {
	  tids[0].tid = -1;
	  tids[0].cnt = 0;
	}
	n_tids = 0;

  }
BYE:
  free_if_non_null(tids);
  fclose_if_non_null(ofp);
  rs_munmap(X1, nX1);
  rs_munmap(X2, nX2);
  return(status);
}
コード例 #10
0
ファイル: simple_temp.cpp プロジェクト: chookee/libmsci
ind_type simple<primitive>::search(primitive value) {
  last_search=(ind_type) bin_search(data, n_data, value, last_search);
  return last_search;
}
コード例 #11
0
ファイル: code.c プロジェクト: bbyk/cwo
int main(int argc, char* argv[]) {

	FILE* input;

	if (argc > 1) {
		input = fopen(argv[1], "r");
		if (NULL == input)
			return EXIT_FAILURE;
	} else {
		input = stdin;
	}

    size_t N;
    fscanf(input, "%zu", &N);

    unsigned *A = malloc(sizeof(unsigned) * N);
    for (size_t i=0; i<N; i++) {
        fscanf(input, "%u", A + i);
    }

    size_t P,Q;
    fscanf(input, "%zu %zu", &P, &Q);
    if (P == Q) {
        printf("%zu", P);
        return -P;
    }

    // insert sort cause we only have 100 elements
    for (int i=1; i<N; i++) {
        for (int j=i; j>0; j--) {
            if (A[j] >= A[j - 1]) {
                break;
            }
            unsigned tmp = A[j];
            A[j] = A[j - 1];
            A[j - 1] = tmp;
        }
    }

    int Pi = bin_search(A, N, P);
    int Qi = bin_search(A, N, Q);

    unsigned max;
    size_t R, RC;

    if (Qi >= 0) {
        max = 0;
        R = Q;
    } else {
        Qi = ~Qi;
        if (Qi >= N) {
        	max = Q - A[--Qi];
        	R = Q;
        } else {
        	max = MIN(Q - A[Qi - 1], A[Qi] - Q);
        	R = Q;
        }
    }

    int aPi = Pi < 0 ? ~Pi : Pi;
    aPi = MAX(0, aPi - 1);

    unsigned delta;
    for (int i = Qi; i > aPi; i--) {
        delta = (A[i] - A[i - 1]) >> 1;
        RC = A[i - 1] + delta;

        if (RC > Q || RC < P)
        	continue;
        if (delta >= max) {
            max = delta;
            R = RC;
        }
    }

    if (Pi >= 0) {
    	delta = 0;
    	RC = P;
    } else {
    	Pi = ~Pi;
    	if (0 == Pi) {
    		delta = A[Pi] - P;
    		RC = P;
    	} else {
    		delta = MIN(P - A[Pi - 1], A[Pi] - P);
    		RC = P;
    	}
    }

    if (delta >= max) {
    	max = delta;
    	R = RC;
    }

    printf("%zu", R);

    free(A);

    return 0;
}
コード例 #12
0
ファイル: 13_03_16_15_C_3712.CPP プロジェクト: hrnn/olymp
void run_kmp ()
{
  nkmp = 0;
  int cur_c = 0, cur_i = 0;
  __int64 pos_c = 1, pos_i = 0;
  while (pos_c >= str[cur_c].b)
    cur_c++;
  char c_c = str[cur_c].c;
  char c_i = str[cur_i].c;
  int i_vel;
  if (c_c == c_i)
  {
    start_block (pos_c, pos_i + 1, 1);
    i_vel = 1;
  }
  else
  {
    start_block (pos_c, 0, 0);
    i_vel = 0;
  }
  __int64 time = 0;
  add_event (EVENT_CURSOR, str[cur_c].b - pos_c + time);
  add_event (EVENT_IMAGE, str[cur_i].b - pos_i + time);
  while (pos_c < len)
  {
    event e = next_event ();
    __int64 delta = e.time - time;
    time = e.time;
    pos_c += delta;
    pos_i += delta * i_vel;
    while (pos_i >= str[cur_i].b)
      cur_i++;
    while (pos_c >= str[cur_c].b)
      cur_c++;
    char c_c = str[cur_c].c;
    char c_i = str[cur_i].c;
    if (pos_c >= len)
      break;
    end_block (pos_c);
#ifdef _DBG_
    printf ("$%I64d (%d) %I64d (%d)\n", pos_i, cur_i, pos_c, cur_c);
#endif
    while (c_c != c_i && pos_i > 0)
    {
#ifdef _DBG_
      printf ("!jump from %I64d", pos_i - 1);
#endif
      pos_i = get_answer (pos_i - 1);
      cur_i = bin_search (pos_i);
      c_i = str[cur_i].c;
#ifdef _DBG_
      printf (" to %I64d (%d)\n", pos_i, cur_i);
#endif
    }
    if (c_c == c_i)
    {
      start_block (pos_c, pos_i + 1, 1);
      i_vel = 1;
    }
    else
    {
      start_block (pos_c, 0, 0);
      i_vel = 0;
    }
    add_event (EVENT_CURSOR, str[cur_c].b - pos_c + time);
    add_event (EVENT_IMAGE, str[cur_i].b - pos_i + time);
  }
  end_block (len);
}
コード例 #13
0
ファイル: database.c プロジェクト: agrimaseth/Data-Structures
int main()
{
	struct student s;
	struct student s1[10];
	int n,d,ch2,ch1;
	printf("enter the number of records  to be entered");
	scanf("%d",&n);
	printf("choose the way to operate:\n 1.with pointer\n 2. without pointer");
	scanf("%d",&ch1);
	switch(ch1)
	{
	case 1:
		{
			input_p(&s,n);

			do
				{
				printf("choose the operation to perform:\n 1.display all\n 2.display particular\n 3.delete\n 4.insert\n 5.bubble sort\n 6.selection sort\n 7.binary seach");
				scanf("%d",&ch2);
				switch(ch2)
				{
					case 1:
						display_all_p(&s,n);
					break;
					case 2:
						printf("enter the record to be displayed");
						scanf("%d",&d);
						display_part_p(&s,d);
					break;
					case 3:
						printf("\n enter the record to be deleted");
						scanf("%d",&d);
						del_p(&s,d,n);
					break;
					case 4:
						printf("\n enter the position at which record is to be inserted");
						scanf("%d",&d);
						ins_p(&s,d,n);
					break;
					case 5:
						printf("you chose to sort the records by their roll no using bubble sort");
						bubblesort(&s,n);

						break;
					case 6:
						printf("you chose to sort the records by their roll no using selection sort");
						selection_sort(&s,n);

						break;
					case 7:
						printf("you chose to search a record using binary search by their roll no");

						bin_search(&s,n);
						break;
					default:
						break;
				}
			}while(ch2!=8);

		}
		break;
	case 2:
		{
			input(s1,n);
			do
			{
				printf("choose the operation to perform:\n 1.display all\n 2.display particular\n 3.delete\n 4.insert\n 5. exit");
				scanf("%d",&ch2);
				switch(ch2)
				{
					case 1:
						display_all(s1,n);
					break;
					case 2:
						printf("enter the record to be displayed");
						scanf("%d",&d);
						display_part(s1,d);

					break;
					case 3:
						printf("\n enter the record to be deleted");
						scanf("%d",&d);
						del(s1,d,n);
					break;
					case 4:
						printf("\n enter the position at which record is to be inserted");
						scanf("%d",&d);
						ins(s1,d,n);
					break;
					default:
						printf("please enter a valid input");
						break;
				}
			}while(ch2!=5);
		}
		break;
	default:
		break;

	}
	getchar();
	return 0;
}
コード例 #14
0
int main(int argc, char *argv[]) {
	int list[] = {1, 3, 8, 10, 12, 14, 15, 19, 25, 30};
	int key = 25;
	int idx = bin_search(list, 10, key);
	printf("list[%d] = %d\n", idx, key);
}
コード例 #15
0
ファイル: stree.c プロジェクト: BackupTheBerlios/wl530g-svn
/* This function fills up the path from the root to the leaf as it
   descends the tree looking for the key.  It uses reiserfs_bread to
   try to find buffers in the cache given their block number.  If it
   does not find them in the cache it reads them from disk.  For each
   node search_by_key finds using reiserfs_bread it then uses
   bin_search to look through that node.  bin_search will find the
   position of the block_number of the next node if it is looking
   through an internal node.  If it is looking through a leaf node
   bin_search will find the position of the item which has key either
   equal to given key, or which is the maximal key less than the given
   key.  search_by_key returns a path that must be checked for the
   correctness of the top of the path but need not be checked for the
   correctness of the bottom of the path */
int search_by_key(
    struct super_block  * p_s_sb,         /* Super block.                           */
    struct key          * p_s_key,        /* Key to search.                         */
    struct path         * p_s_search_path,/* This structure was allocated and initialized by
					     the calling function. It is filled up by this
					     function.  */
    int                 * p_n_repeat,     /* Whether schedule occured. */
    int                   n_stop_level   /* How far down the tree to search.*/
    ) {
    dev_t                      n_dev           = p_s_sb->s_dev;
    int                         n_repeat,
	n_block_number  = SB_ROOT_BLOCK (p_s_sb),
	expected_level = SB_TREE_HEIGHT (p_s_sb),
	n_block_size    = p_s_sb->s_blocksize;
    struct buffer_head  *       p_s_bh;
    struct path_element *       p_s_last_element;
    int				n_retval;
    int 			right_neighbor_of_leaf_node;

#ifdef CONFIG_REISERFS_CHECK
    int n_repeat_counter = 0;
#endif

    /* As we add each node to a path we increase its count.  This
       means that we must be careful to release all nodes in a path
       before we either discard the path struct or re-use the path
       struct, as we do here. */
    pathrelse (p_s_search_path);

    *p_n_repeat = CARRY_ON;

    /* With each iteration of this loop we search through the items in
       the current node, and calculate the next current node(next path
       element) for the next iteration of this loop.. */
    while ( 1 ) {

#ifdef CONFIG_REISERFS_CHECK
	if ( !(++n_repeat_counter % 50000) )
	    printk ("PAP-5100: search_by_key(pid %u): there were %d searches from the tree_root lokking for key %p\n",
		    current->pid, n_repeat_counter, p_s_key);
#endif

	/* prep path to have another element added to it. */
	p_s_last_element = PATH_OFFSET_PELEMENT(p_s_search_path, ++p_s_search_path->path_length);
	expected_level --;
	n_repeat = CARRY_ON;

	/* Read the next tree node, and set the last element in the
           path to have a pointer to it. */
	if ( ! (p_s_bh = p_s_last_element->pe_buffer =
		reiserfs_bread(n_dev, n_block_number, n_block_size, &n_repeat)) ) {
	    p_s_search_path->path_length --;
	    pathrelse(p_s_search_path);
	    *p_n_repeat |= n_repeat;
	    return IO_ERROR;
	}

	*p_n_repeat |= n_repeat;

	/* It is possible that schedule occured. We must check whether
	   the key to search is still in the tree rooted from the
	   current buffer. If not then repeat search from the root. */
	if ( n_repeat != CARRY_ON && 
	     (!B_IS_IN_TREE (p_s_bh) || (! key_in_buffer(p_s_search_path, p_s_key, p_s_sb))) ) {
	    pathrelse (p_s_search_path);

	    /* Get the root block number so that we can repeat the
               search starting from the root. */
	    n_block_number  = SB_ROOT_BLOCK (p_s_sb);
	    expected_level = SB_TREE_HEIGHT (p_s_sb);
	    right_neighbor_of_leaf_node = 0;

	    /* repeat search from the root */
	    continue;
	}

#ifdef CONFIG_REISERFS_CHECK

	if ( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb) )
	    reiserfs_panic(p_s_sb, "PAP-5130: search_by_key: key is not in the buffer");
	if ( cur_tb ) {
/*	print_tb (init_mode, init_item_pos, init_pos_in_item, &init_tb, "5140");*/
	    reiserfs_panic(p_s_sb, "PAP-5140: search_by_key: schedule occurred in do_balance!");
	}

#endif

	// make sure, that the node contents look like a nod of
	// certain level
	if (!is_tree_node (p_s_bh, expected_level)) {
	    print_block (stderr, 0, p_s_bh, 3, -1, -1);
	    reiserfs_panic ("vs-5150: search_by_key: expeced level %d", expected_level);
	    pathrelse (p_s_search_path);
	    return IO_ERROR;
	}

	/* ok, we have acquired next formatted node in the tree */
	n_retval = bin_search (p_s_key, B_N_PITEM_HEAD(p_s_bh, 0), B_NR_ITEMS(p_s_bh),
			       is_leaf_node (p_s_bh) ? IH_SIZE : KEY_SIZE, &(p_s_last_element->pe_position));
	if (node_level (p_s_bh) == n_stop_level)
	    return n_retval;

	/* we are not in the stop level */
	if (n_retval == ITEM_FOUND)
	    /* item has been found, so we choose the pointer which is to the right of the found one */
	    p_s_last_element->pe_position++;
	/* if item was not found we choose the position which is to the left of the found item. This
	   requires no code, bin_search did it already.*/


	/* So we have chosen a position in the current node which is an
	   internal node.  Now we calculate child block number by position in the node. */
	n_block_number = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position);
    }
}
コード例 #16
0
ファイル: binarysearch.c プロジェクト: DmytroLebediev/cs50
bool search(int number, int length, const int numbers[])
{
    return bin_search(0, length, number, numbers);
}