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 */
Beispiel #2
0
int heap_rsame(register HP_INFO *info, uchar *record, int inx)
{
  HP_SHARE *share=info->s;
  DBUG_ENTER("heap_rsame");

  test_active(info);
  if (get_chunk_status(&share->recordspace, info->current_ptr) ==
      CHUNK_STATUS_ACTIVE)
  {
    if (inx < -1 || inx >= (int) share->keys)
    {
      DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
    }
    else if (inx != -1)
    {
      info->lastinx=inx;
      hp_make_key(share->keydef + inx, info->lastkey, record);
      if (!hp_search(info, share->keydef + inx, info->lastkey, 3))
      {
	info->update=0;
	DBUG_RETURN(my_errno);
      }
    }
    if (hp_extract_record(info, record, info->current_ptr))
    {
      DBUG_RETURN(my_errno);
    }
    DBUG_RETURN(0);
  }

  /* treat deleted and linked chunks as deleted */

  info->update=0;

  DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
}
Beispiel #3
0
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);
}