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 */
Exemple #2
0
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 */
Exemple #4
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);
}