Last-Modified: Wed, 06 Nov 2024 22:13:07 GMT
Expires: Sat, 04 Nov 2034 22:13:07 GMT
/*
* Copyright (C) 1997-2001 NCSA
* All rights reserved.
*
* Programmer: Robb Matzke <matzke@llnl.gov>
* Wednesday, October 8, 1997
*
* Purpose: Indexed (chunked) I/O functions. The logical
* multi-dimensional data space is regularly partitioned into
* same-sized "chunks", the first of which is aligned with the
* logical origin. The chunks are given a multi-dimensional
* index which is used as a lookup key in a B-tree that maps
* chunk index to disk address. Each chunk can be compressed
* independently and the chunks may move around in the file as
* their storage requirements change.
*
* Cache: Disk I/O is performed in units of chunks and H5MF_alloc()
* contains code to optionally align chunks on disk block
* boundaries for performance.
*
* The chunk cache is an extendible hash indexed by a function
* of storage B-tree address and chunk N-dimensional offset
* within the dataset. Collisions are not resolved -- one of
* the two chunks competing for the hash slot must be preempted
* from the cache. All entries in the hash also participate in
* a doubly-linked list and entries are penalized by moving them
* toward the front of the list. When a new chunk is about to
* be added to the cache the heap is pruned by preempting
* entries near the front of the list to make room for the new
* entry which is added to the end of the list.
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#include "H5private.h"
#include "H5Dprivate.h"
#include "H5Eprivate.h"
#include "H5Fpkg.h"
#include "H5FLprivate.h" /*Free Lists */
#include "H5Iprivate.h"
#include "H5MFprivate.h"
#include "H5MMprivate.h"
#include "H5Oprivate.h"
#include "H5Pprivate.h"
#include "H5Vprivate.h"
/* MPIO driver needed for special checks */
#include "H5FDmpio.h"
/*
* Feature: If this constant is defined then every cache preemption and load
* causes a character to be printed on the standard error stream:
*
* `.': Entry was preempted because it has been completely read or
* completely written but not partially read and not partially
* written. This is often a good reason for preemption because such
* a chunk will be unlikely to be referenced in the near future.
*
* `:': Entry was preempted because it hasn't been used recently.
*
* `#': Entry was preempted because another chunk collided with it. This
* is usually a relatively bad thing. If there are too many of
* these then the number of entries in the cache can be increased.
*
* c: Entry was preempted because the file is closing.
*
* w: A chunk read operation was eliminated because the library is
* about to write new values to the entire chunk. This is a good
* thing, especially on files where the chunk size is the same as
* the disk block size, chunks are aligned on disk block boundaries,
* and the operating system can also eliminate a read operation.
*/
/* #define H5F_ISTORE_DEBUG */
/* Interface initialization */
#define PABLO_MASK H5Fistore_mask
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
/*
* Given a B-tree node return the dimensionality of the chunks pointed to by
* that node.
*/
#define H5F_ISTORE_NDIMS(X) ((intn)(((X)->sizeof_rkey-8)/8))
/* Raw data chunks are cached. Each entry in the cache is: */
typedef struct H5F_rdcc_ent_t {
hbool_t locked; /*entry is locked in cache */
hbool_t dirty; /*needs to be written to disk? */
H5O_layout_t *layout; /*the layout message */
double split_ratios[3];/*B-tree node splitting ratios */
H5O_pline_t *pline; /*filter pipeline message */
hssize_t offset[H5O_LAYOUT_NDIMS]; /*chunk name */
size_t rd_count; /*bytes remaining to be read */
size_t wr_count; /*bytes remaining to be written */
size_t chunk_size; /*size of a chunk */
size_t alloc_size; /*amount allocated for the chunk */
uint8_t *chunk; /*the unfiltered chunk data */
intn idx; /*index in hash table */
struct H5F_rdcc_ent_t *next;/*next item in doubly-linked list */
struct H5F_rdcc_ent_t *prev;/*previous item in doubly-linked list */
} H5F_rdcc_ent_t;
typedef H5F_rdcc_ent_t *H5F_rdcc_ent_ptr_t; /* For free lists */
/* Private prototypes */
static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata);
static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t, void *_lt_key,
void *_udata, void *_rt_key,
haddr_t*/*out*/);
static intn H5F_istore_cmp2(H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5F_istore_found(H5F_t *f, haddr_t addr, const void *_lt_key,
void *_udata, const void *_rt_key);
static H5B_ins_t H5F_istore_insert(H5F_t *f, haddr_t addr, void *_lt_key,
hbool_t *lt_key_changed, void *_md_key,
void *_udata, void *_rt_key,
hbool_t *rt_key_changed,
haddr_t *new_node/*out*/);
static herr_t H5F_istore_iterate(H5F_t *f, void *left_key, haddr_t addr,
void *right_key, void *_udata);
static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8_t *raw,
void *_key);
static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8_t *raw,
void *_key);
static herr_t H5F_istore_debug_key(FILE *stream, intn indent, intn fwidth,
const void *key, const void *udata);
#ifdef H5_HAVE_PARALLEL
static herr_t H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout,
const hssize_t offset[],
void *_udata/*out*/);
#endif
/*
* B-tree key. A key contains the minimum logical N-dimensional address and
* the logical size of the chunk to which this key refers. The
* fastest-varying dimension is assumed to reference individual bytes of the
* array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
* array with the slow varying dimension of size 100 and the fast varying
* dimension of size 4 (the storage dimensionality has very little to do with
* the real dimensionality).
*
* Only the first few values of the OFFSET and SIZE fields are actually
* stored on disk, depending on the dimensionality.
*
* The chunk's file address is part of the B-tree and not part of the key.
*/
typedef struct H5F_istore_key_t {
size_t nbytes; /*size of stored data */
hssize_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/
uintn filter_mask; /*excluded filters */
} H5F_istore_key_t;
typedef struct H5F_istore_ud1_t {
H5F_istore_key_t key; /*key values */
haddr_t addr; /*file address of chunk */
H5O_layout_t mesg; /*layout message */
hsize_t total_storage; /*output from iterator */
FILE *stream; /*debug output stream */
} H5F_istore_ud1_t;
/* inherits B-tree like properties from H5B */
|