struct item * street_search_get_item(struct map_rect_priv *mr) { int dir=1,leaf; unsigned char *last; dbg(1,"enter\n"); if (! mr->search_blk_count) { dbg(1,"partial 0x%x '%s' ***\n", mr->town.street_assoc, mr->search_str); if (mr->search_linear) return NULL; dbg(1,"tree_search_next\n"); mr->search_block=-1; while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { dir=street_search_compare(&mr->search_p, mr); } dbg(1,"dir=%d mr->search_block=0x%x\n", dir, mr->search_block); if (mr->search_block == -1) return NULL; mr->search_blk_count=1; block_get_byindex(mr->m->file[file_strname_stn], mr->search_block, &mr->b); mr->b.p=mr->b.block_start+12; } dbg(1,"name id 0x%x\n", mr->b.p-mr->m->file[file_strname_stn]->begin); if (! mr->search_blk_count) return NULL; for (;;) { if (mr->b.p >= mr->b.end) { if (!block_next_lin(mr)) { dbg(1,"end of blocks in %p, %p\n", mr->m->file[file_strname_stn]->begin, mr->m->file[file_strname_stn]->end); return NULL; } mr->b.p=mr->b.block_start+12; } while (mr->b.p < mr->b.end) { last=mr->b.p; street_name_get(&mr->street.name, &mr->b.p); dir=street_search_compare_do(mr, mr->street.name.country, mr->street.name.townassoc, mr->street.name.name2); dbg(1,"country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d\n", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir); if (dir < 0) { dbg(1,"end of data\n"); mr->search_blk_count=0; return NULL; } if (!dir) { dbg(1,"result country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d aux_data=%p len=0x%x\n", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir, mr->street.name.aux_data, mr->street.name.aux_len); mr->item.type = type_street_name; mr->item.id_hi=mr->street.name.country | (mr->current_file << 16) | 0x10000000; mr->item.id_lo=last-mr->m->file[mr->current_file]->begin; mr->item.meth=&street_name_meth; mr->item.map=NULL; mr->item.priv_data=mr; return &mr->item; } } } }
static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, my_bool print_status) { HP_KEYDEF *keydef= info->s->keydef + keynr; int error= 0; ulong found= 0; uchar *key, *recpos; uint key_length; uint not_used[2]; if ((key= tree_search_edge(&keydef->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)))) { do { memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(uchar*)); key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0); if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key, key_length, SEARCH_FIND | SEARCH_SAME, not_used)) { error= 1; DBUG_PRINT("error",("Record in wrong link: key: %u Record: 0x%lx\n", keynr, (long) recpos)); } else found++; key= tree_search_next(&keydef->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, left), offsetof(TREE_ELEMENT, right)); } while (key); } if (found != records) { DBUG_PRINT("error",("Found %lu of %lu records", found, records)); error= 1; } if (print_status) printf("Key: %d records: %ld\n", keynr, records); return error; }
int heap_rprev(HP_INFO *info, uchar *record) { uchar *pos; HP_SHARE *share=info->s; HP_KEYDEF *keyinfo; DBUG_ENTER("heap_rprev"); if (info->lastinx < 0) DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); keyinfo = share->keydef + info->lastinx; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { heap_rb_param custom_arg; if (info->last_pos) pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, right), offsetof(TREE_ELEMENT, left)); else { custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = keyinfo->length; custom_arg.search_flag = SEARCH_SAME; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); } if (pos) { memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(uchar*)); info->current_ptr = pos; } else { my_errno = HA_ERR_KEY_NOT_FOUND; } } else { if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND)) { if ((info->update & HA_STATE_DELETED)) pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 3); else pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 2); } else { pos=0; /* Read next after last */ my_errno=HA_ERR_KEY_NOT_FOUND; } } if (!pos) { info->update=HA_STATE_PREV_FOUND; /* For heap_rprev */ if (my_errno == HA_ERR_KEY_NOT_FOUND) my_errno=HA_ERR_END_OF_FILE; DBUG_RETURN(my_errno); } if (hp_extract_record(info, record, pos)) { DBUG_RETURN(my_errno); } info->update=HA_STATE_AKTIV | HA_STATE_PREV_FOUND; DBUG_RETURN(0); }
int heap_rprev(HP_INFO *info, uchar *record) { uchar *pos; HP_SHARE *share=info->s; HP_KEYDEF *keyinfo; DBUG_ENTER("heap_rprev"); if (info->lastinx < 0) DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); keyinfo = share->keydef + info->lastinx; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { heap_rb_param custom_arg; /* If no active record and last was not deleted */ if (!(info->update & (HA_STATE_AKTIV | HA_STATE_NO_KEY | HA_STATE_DELETED))) { if (info->update & HA_STATE_PREV_FOUND) pos= 0; /* Can't search before first row */ else { /* Last was 'next' after last record; search after last record */ pos= tree_search_edge(&keyinfo->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, right)); } } else if (info->last_pos) pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, right), offsetof(TREE_ELEMENT, left)); else { custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = keyinfo->length; custom_arg.search_flag = SEARCH_SAME; info->last_find_flag= HA_READ_KEY_OR_PREV; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); } if (pos) { memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(uchar*)); info->current_ptr = pos; } else { my_errno = HA_ERR_KEY_NOT_FOUND; } } else { if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND)) { if ((info->update & HA_STATE_DELETED)) pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 3); else pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 2); } else { pos=0; /* Read next after last */ my_errno=HA_ERR_KEY_NOT_FOUND; } } if (!pos) { info->update=HA_STATE_PREV_FOUND; /* For heap_rprev */ if (my_errno == HA_ERR_KEY_NOT_FOUND) my_errno=HA_ERR_END_OF_FILE; DBUG_RETURN(my_errno); } memcpy(record,pos,(size_t) share->reclength); info->update=HA_STATE_AKTIV | HA_STATE_PREV_FOUND; DBUG_RETURN(0); }
int heap_rnext(HP_INFO *info, uchar *record) { uchar *pos; HP_SHARE *share=info->s; HP_KEYDEF *keyinfo; DBUG_ENTER("heap_rnext"); if (info->lastinx < 0) DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); keyinfo = share->keydef + info->lastinx; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { heap_rb_param custom_arg; /* If no active record and last was not deleted */ if (!(info->update & (HA_STATE_AKTIV | HA_STATE_NO_KEY | HA_STATE_DELETED))) { if (info->update & HA_STATE_NEXT_FOUND) pos= 0; /* Can't search after last row */ else { /* Last was 'prev' before first record; search after first record */ pos= tree_search_edge(&keyinfo->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)); } } else if (info->last_pos) { /* We enter this branch for non-DELETE queries after heap_rkey() or heap_rfirst(). As last key position (info->last_pos) is available, we only need to climb the tree using tree_search_next(). */ pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, left), offsetof(TREE_ELEMENT, right)); } else if (!info->lastkey_len) { /* We enter this branch only for DELETE queries after heap_rfirst(). E.g. DELETE FROM t1 WHERE a<10. As last key position is not available (last key is removed by heap_delete()), we must restart search as it is done in heap_rfirst(). It should be safe to handle this situation without this branch. That is branch below should find smallest element in a tree as lastkey_len is zero. tree_search_edge() is a kind of optimisation here as it should be faster than tree_search_key(). */ pos= tree_search_edge(&keyinfo->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)); } else { /* We enter this branch only for DELETE queries after heap_rkey(). E.g. DELETE FROM t1 WHERE a=10. As last key position is not available (last key is removed by heap_delete()), we must restart search as it is done in heap_rkey(). */ custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = info->lastkey_len; custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND; info->last_find_flag= HA_READ_KEY_OR_NEXT; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); } if (pos) { memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(uchar*)); info->current_ptr = pos; } else { my_errno = HA_ERR_KEY_NOT_FOUND; } } else { if (info->current_hash_ptr) pos= hp_search_next(info, keyinfo, info->lastkey, info->current_hash_ptr); else { if (!info->current_ptr && (info->update & HA_STATE_NEXT_FOUND)) { pos=0; /* Read next after last */ my_errno=HA_ERR_KEY_NOT_FOUND; } else if (!info->current_ptr) /* Deleted or first call */ pos= hp_search(info, keyinfo, info->lastkey, 0); else pos= hp_search(info, keyinfo, info->lastkey, 1); } } if (!pos) { info->update=HA_STATE_NEXT_FOUND; /* For heap_rprev */ if (my_errno == HA_ERR_KEY_NOT_FOUND) my_errno=HA_ERR_END_OF_FILE; DBUG_RETURN(my_errno); } memcpy(record,pos,(size_t) share->reclength); info->update=HA_STATE_AKTIV | HA_STATE_NEXT_FOUND; DBUG_RETURN(0); }
int aby_rprev(HPA_INFO *info, uchar *record) { uchar *pos; HPA_SHARE *share=info->s; HPA_KEYDEF *keyinfo; DBUG_ENTER("aby_rprev"); if (info->lastinx < 0) DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); keyinfo = share->keydef + info->lastinx; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { aby_rb_param custom_arg; if (info->last_pos) pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, right), offsetof(TREE_ELEMENT, left)); else { custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = keyinfo->length; custom_arg.search_flag = SEARCH_SAME; pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, info->last_find_flag, &custom_arg); } if (pos) { memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(uchar*)); if (ABY_LOCK == ABY_HEAP) info->current_ptr = pos; else if (ABY_LOCK == ABY_ROW) info->current_ptr_array[((pid_t)syscall(SYS_gettid))%ROWTHRDS] = pos; } else { my_errno = HA_ERR_KEY_NOT_FOUND; } } else { if (ABY_LOCK == ABY_HEAP) { if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND)) { if ((info->update & HA_STATE_DELETED)) pos= hpa_search(info, share->keydef + info->lastinx, info->lastkey, 3); else pos= hpa_search(info, share->keydef + info->lastinx, info->lastkey, 2); } else { pos=0; /* Read next after last */ my_errno=HA_ERR_KEY_NOT_FOUND; } } else if (ABY_LOCK == ABY_ROW) { if (info->current_ptr_array[((pid_t)syscall(SYS_gettid))%ROWTHRDS] || (info->update & HA_STATE_NEXT_FOUND)) { if ((info->update & HA_STATE_DELETED)) pos= hpa_search(info, share->keydef + info->lastinx, info->lastkey, 3); else pos= hpa_search(info, share->keydef + info->lastinx, info->lastkey, 2); } else { pos=0; /* Read next after last */ my_errno=HA_ERR_KEY_NOT_FOUND; } } } if (!pos) { info->update=HA_STATE_PREV_FOUND; /* For aby_rprev */ if (my_errno == HA_ERR_KEY_NOT_FOUND) my_errno=HA_ERR_END_OF_FILE; DBUG_RETURN(my_errno); } memcpy(record,pos,(size_t) share->reclength); info->update=HA_STATE_AKTIV | HA_STATE_PREV_FOUND; DBUG_RETURN(0); }