Files
hdf5/src/H5HFdtable.c
Binh-Minh Ribler ec31438afd Fixed HDFFV-10404
Description:
    Applied the typo fixes from user's report.
    The previous pull request couldn't be merged because it was too old,
    and it was too complicated for me to resolve conflicts.
Platform tested:
    Linux/64 (jelly) - very minor
2018-07-13 13:40:22 -05:00

371 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*-------------------------------------------------------------------------
*
* Created: H5HFdtable.c
* Apr 10 2006
* Quincey Koziol <koziol@ncsa.uiuc.edu>
*
* Purpose: "Doubling table" routines for fractal heaps.
*
*-------------------------------------------------------------------------
*/
/****************/
/* Module Setup */
/****************/
#include "H5HFmodule.h" /* This source code file is part of the H5HF module */
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5HFpkg.h" /* Fractal heaps */
#include "H5MMprivate.h" /* Memory management */
#include "H5VMprivate.h" /* Vectors and arrays */
/****************/
/* Local Macros */
/****************/
/******************/
/* Local Typedefs */
/******************/
/********************/
/* Package Typedefs */
/********************/
/********************/
/* Local Prototypes */
/********************/
/*********************/
/* Package Variables */
/*********************/
/*****************************/
/* Library Private Variables */
/*****************************/
/*******************/
/* Local Variables */
/*******************/
/*-------------------------------------------------------------------------
* Function: H5HF_dtable_init
*
* Purpose: Initialize values for doubling table
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Mar 6 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_dtable_init(H5HF_dtable_t *dtable)
{
hsize_t tmp_block_size; /* Temporary block size */
hsize_t acc_block_off; /* Accumulated block offset */
size_t u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(dtable);
/* Compute/cache some values */
dtable->start_bits = H5VM_log2_of2((uint32_t)dtable->cparam.start_block_size);
dtable->first_row_bits = dtable->start_bits + H5VM_log2_of2(dtable->cparam.width);
dtable->max_root_rows = (dtable->cparam.max_index - dtable->first_row_bits) + 1;
dtable->max_direct_bits = H5VM_log2_of2((uint32_t)dtable->cparam.max_direct_size);
dtable->max_direct_rows = (dtable->max_direct_bits - dtable->start_bits) + 2;
dtable->num_id_first_row = dtable->cparam.start_block_size * dtable->cparam.width;
dtable->max_dir_blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dtable->cparam.max_direct_size);
/* Build table of block sizes for each row */
if(NULL == (dtable->row_block_size = (hsize_t *)H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table block size table")
if(NULL == (dtable->row_block_off = (hsize_t *)H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table block offset table")
if(NULL == (dtable->row_tot_dblock_free = (hsize_t *)H5MM_malloc(dtable->max_root_rows * sizeof(hsize_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table total direct block free space table")
if(NULL == (dtable->row_max_dblock_free = (size_t *)H5MM_malloc(dtable->max_root_rows * sizeof(size_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create doubling table max. direct block free space table")
tmp_block_size = dtable->cparam.start_block_size;
acc_block_off = dtable->cparam.start_block_size * dtable->cparam.width;
dtable->row_block_size[0] = dtable->cparam.start_block_size;
dtable->row_block_off[0] = 0;
for(u = 1; u < dtable->max_root_rows; u++) {
dtable->row_block_size[u] = tmp_block_size;
dtable->row_block_off[u] = acc_block_off;
tmp_block_size *= 2;
acc_block_off *= 2;
} /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_dtable_init() */
/*-------------------------------------------------------------------------
* Function: H5HF_dtable_lookup
*
* Purpose: Compute the row & col of an offset in a doubling-table
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Mar 6 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off, unsigned *row, unsigned *col)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
/*
* Check arguments.
*/
HDassert(dtable);
HDassert(row);
HDassert(col);
#ifdef QAK
HDfprintf(stderr, "%s: off = %Hu\n", "H5HF_dtable_lookup", off);
#endif /* QAK */
/* Check for offset in first row */
if(off < dtable->num_id_first_row) {
*row = 0;
H5_CHECKED_ASSIGN(*col, unsigned, (off / dtable->cparam.start_block_size), hsize_t);
} /* end if */
else {
unsigned high_bit = H5VM_log2_gen(off); /* Determine the high bit in the offset */
hsize_t off_mask = ((hsize_t)1) << high_bit; /* Compute mask for determining column */
#ifdef QAK
HDfprintf(stderr, "%s: high_bit = %u, off_mask = %Hu\n", "H5HF_dtable_lookup", high_bit, off_mask);
#endif /* QAK */
*row = (high_bit - dtable->first_row_bits) + 1;
H5_CHECKED_ASSIGN(*col, unsigned, ((off - off_mask) / dtable->row_block_size[*row]), hsize_t);
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5HF_dtable_lookup() */
/*-------------------------------------------------------------------------
* Function: H5HF_dtable_dest
*
* Purpose: Release information for doubling table
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Mar 27 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_dtable_dest(H5HF_dtable_t *dtable)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
/*
* Check arguments.
*/
HDassert(dtable);
/* Free the block size lookup table for the doubling table */
H5MM_xfree(dtable->row_block_size);
/* Free the block offset lookup table for the doubling table */
H5MM_xfree(dtable->row_block_off);
/* Free the total direct block free space lookup table for the doubling table */
H5MM_xfree(dtable->row_tot_dblock_free);
/* Free the max. direct block free space lookup table for the doubling table */
H5MM_xfree(dtable->row_max_dblock_free);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5HF_dtable_dest() */
/*-------------------------------------------------------------------------
* Function: H5HF_dtable_size_to_row
*
* Purpose: Compute row that can hold block of a certain size
*
* Return: Non-negative on success (can't fail)
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Apr 25 2006
*
*-------------------------------------------------------------------------
*/
unsigned
H5HF_dtable_size_to_row(const H5HF_dtable_t *dtable, size_t block_size)
{
unsigned row = 0; /* Row where block will fit */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/*
* Check arguments.
*/
HDassert(dtable);
if(block_size == dtable->cparam.start_block_size)
row = 0;
else
row = (H5VM_log2_of2((uint32_t)block_size) - H5VM_log2_of2((uint32_t)dtable->cparam.start_block_size)) + 1;
FUNC_LEAVE_NOAPI(row)
} /* end H5HF_dtable_size_to_row() */
/*-------------------------------------------------------------------------
* Function: H5HF_dtable_size_to_rows
*
* Purpose: Compute # of rows of indirect block of a given size
*
* Return: Non-negative on success (can't fail)
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* May 31 2006
*
*-------------------------------------------------------------------------
*/
unsigned
H5HF_dtable_size_to_rows(const H5HF_dtable_t *dtable, hsize_t size)
{
unsigned rows = 0; /* # of rows required for indirect block */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/*
* Check arguments.
*/
HDassert(dtable);
rows = (H5VM_log2_gen(size) - dtable->first_row_bits) + 1;
FUNC_LEAVE_NOAPI(rows)
} /* end H5HF_dtable_size_to_rows() */
/*-------------------------------------------------------------------------
* Function: H5HF_dtable_span_size
*
* Purpose: Compute the size covered by a span of entries
*
* Return: Non-zero span size on success/zero on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* July 25 2006
*
*-------------------------------------------------------------------------
*/
hsize_t
H5HF_dtable_span_size(const H5HF_dtable_t *dtable, unsigned start_row,
unsigned start_col, unsigned num_entries)
{
unsigned start_entry; /* Entry for first block covered */
unsigned end_row; /* Row for last block covered */
unsigned end_col; /* Column for last block covered */
unsigned end_entry; /* Entry for last block covered */
hsize_t acc_span_size = 0; /* Accumulated span size */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/*
* Check arguments.
*/
HDassert(dtable);
HDassert(num_entries > 0);
/* Compute starting entry */
start_entry = (start_row * dtable->cparam.width) + start_col;
/* Compute ending entry, column & row */
end_entry = (start_entry + num_entries) - 1;
end_row = end_entry / dtable->cparam.width;
end_col = end_entry % dtable->cparam.width;
#ifdef QAK
HDfprintf(stderr, "%s: start_row = %u, start_col = %u, start_entry = %u\n", "H5HF_sect_indirect_span_size", start_row, start_col, start_entry);
HDfprintf(stderr, "%s: end_row = %u, end_col = %u, end_entry = %u\n", "H5HF_sect_indirect_span_size", end_row, end_col, end_entry);
#endif /* QAK */
/* Initialize accumulated span size */
acc_span_size = 0;
/* Compute span size covered */
/* Check for multi-row span */
if(start_row != end_row) {
/* Accommodate partial starting row */
if(start_col > 0) {
acc_span_size = dtable->row_block_size[start_row] *
(dtable->cparam.width - start_col);
start_row++;
} /* end if */
/* Accumulate full rows */
while(start_row < end_row) {
acc_span_size += dtable->row_block_size[start_row] *
dtable->cparam.width;
start_row++;
} /* end while */
/* Accommodate partial ending row */
acc_span_size += dtable->row_block_size[start_row] *
(end_col + 1);
} /* end if */
else {
/* Span is in same row */
acc_span_size = dtable->row_block_size[start_row] *
((end_col - start_col) + 1);
} /* end else */
#ifdef QAK
HDfprintf(stderr, "%s: acc_span_size = %Hu\n", "H5HF_dtable_span_size", acc_span_size);
#endif /* QAK */
FUNC_LEAVE_NOAPI(acc_span_size)
} /* end H5HF_sect_indirect_span_size() */