int heap_scan(register HP_INFO *info, uchar *record) { HP_SHARE *share=info->s; ulong pos; DBUG_ENTER("heap_scan"); pos= ++info->current_record; if (pos >= share->recordspace.chunk_count) { info->update= 0; DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE); } hp_find_record(info, pos); if (get_chunk_status(&share->recordspace, info->current_ptr) != CHUNK_STATUS_ACTIVE) { DBUG_PRINT("warning",("Found deleted record or secondary chunk")); info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); } info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV; if (hp_extract_record(info, record, info->current_ptr)) { DBUG_RETURN(my_errno); } info->current_hash_ptr=0; /* Can't use read_next */ DBUG_RETURN(0); } /* heap_scan */
int heap_check_heap(HP_INFO *info, my_bool print_status) { int error; uint key; ulong records=0, deleted=0, pos, next_block; HP_SHARE *share=info->s; HP_INFO save_info= *info; /* Needed because scan_init */ DBUG_ENTER("heap_check_heap"); for (error=key= 0 ; key < share->keys ; key++) { if (share->keydef[key].algorithm == HA_KEY_ALG_BTREE) error|= check_one_rb_key(info, key, share->records, print_status); else error|= check_one_key(share->keydef + key, key, share->records, share->blength, print_status); } /* This is basicly the same code as in hp_scan, but we repeat it here to get shorter DBUG log file. */ for (pos=next_block= 0 ; ; pos++) { if (pos < next_block) { info->current_ptr+= share->block.recbuffer; } else { next_block+= share->block.records_in_block; if (next_block >= share->records+share->deleted) { next_block= share->records+share->deleted; if (pos >= next_block) break; /* End of file */ } } hp_find_record(info,pos); if (!info->current_ptr[share->reclength]) deleted++; else records++; } if (records != share->records || deleted != share->deleted) { DBUG_PRINT("error",("Found rows: %lu (%lu) deleted %lu (%lu)", records, (ulong) share->records, deleted, (ulong) share->deleted)); error= 1; } *info= save_info; DBUG_RETURN(error); }
int heap_rrnd_old(register HP_INFO *info, uchar *record, ulong pos) { HP_SHARE *share=info->s; DBUG_ENTER("heap_rrnd"); DBUG_PRINT("enter",("info: 0x%lx pos: %ld",info,pos)); info->lastinx= -1; if (pos == (ulong) -1) { pos= ++info->current_record; if (pos % share->block.records_in_block && /* Quick next record */ pos < share->records+share->deleted && (info->update & HA_STATE_PREV_FOUND)) { info->current_ptr+=share->block.recbuffer; goto end; } } else info->current_record=pos; if (pos >= share->records+share->deleted) { info->update= 0; DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE); } /* Find record number pos */ hp_find_record(info, pos); end: if (!info->current_ptr[share->reclength]) { info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); } info->update=HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND | HA_STATE_AKTIV; memcpy(record,info->current_ptr,(size_t) share->reclength); DBUG_PRINT("exit",("found record at 0x%lx",info->current_ptr)); info->current_hash_ptr=0; /* Can't use rnext */ DBUG_RETURN(0); } /* heap_rrnd */
int heap_check_heap(HP_INFO *info, my_bool print_status) { int error; uint key; ulong records= 0, deleted= 0, chunk_count= 0, pos, next_block; HP_SHARE *share=info->s; HP_INFO save_info= *info; /* Needed because scan_init */ DBUG_ENTER("heap_check_heap"); for (error=key= 0 ; key < share->keys ; key++) { if (share->keydef[key].algorithm == HA_KEY_ALG_BTREE) error|= check_one_rb_key(info, key, share->records, print_status); else error|= check_one_key(share->keydef + key, key, share->records, share->blength, print_status); } /* This is basicly the same code as in hp_scan, but we repeat it here to get shorter DBUG log file. */ for (pos=next_block= 0 ; ; pos++) { if (pos < next_block) { info->current_ptr+= share->recordspace.block.recbuffer; } else { next_block+= share->recordspace.block.records_in_block; if (next_block >= share->recordspace.chunk_count) { next_block= share->recordspace.chunk_count; if (pos >= next_block) break; /* End of file */ } } hp_find_record(info,pos); switch (get_chunk_status(&share->recordspace, info->current_ptr)) { case CHUNK_STATUS_DELETED: deleted++; chunk_count++; break; case CHUNK_STATUS_ACTIVE: records++; chunk_count++; break; case CHUNK_STATUS_LINKED: chunk_count++; break; default: DBUG_PRINT("error", ("Unknown record status: Record: 0x%lx Status %lu", (long) info->current_ptr, (ulong) get_chunk_status(&share->recordspace, info->current_ptr))); error|= 1; break; } } /* TODO: verify linked chunks (no orphans, no cycles, no bad links) */ if (records != share->records || chunk_count != share->recordspace.chunk_count || deleted != share->recordspace.del_chunk_count) { DBUG_PRINT("error", ("Found rows: %lu (%lu) total chunks %lu (%lu) deleted chunks " "%lu (%lu)", records, (ulong) share->records, chunk_count, (ulong) share->recordspace.chunk_count, deleted, (ulong) share->recordspace.del_chunk_count)); error= 1; } *info= save_info; DBUG_RETURN(error); }