diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2013-06-14 00:30:20 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2013-06-14 00:30:20 (GMT) |
commit | 373038013ea82651f9fe587a0439cab710ede0b8 (patch) | |
tree | e61a32d511c5c6c3f56fbfccf0840ea244c2a308 /src | |
parent | 07ccc1ab5a7c1de2b2a49ff1890ee8153663a47e (diff) | |
download | hdf5-373038013ea82651f9fe587a0439cab710ede0b8.zip hdf5-373038013ea82651f9fe587a0439cab710ede0b8.tar.gz hdf5-373038013ea82651f9fe587a0439cab710ede0b8.tar.bz2 |
[svn-r23769] add property to indicate append
add a new version of checksum algorithm to correctly save the state
other updates...
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Pdxpl.c | 16 | ||||
-rw-r--r-- | src/H5Sprivate.h | 2 | ||||
-rw-r--r-- | src/H5Sselect.c | 75 | ||||
-rw-r--r-- | src/H5VLiod.c | 53 | ||||
-rw-r--r-- | src/H5VLiod.h | 3 | ||||
-rw-r--r-- | src/H5VLiod_client.c | 14 | ||||
-rw-r--r-- | src/H5VLiod_client.h | 4 | ||||
-rw-r--r-- | src/H5VLiod_server.c | 19 | ||||
-rw-r--r-- | src/H5checksum.c | 169 | ||||
-rw-r--r-- | src/H5private.h | 1 | ||||
-rw-r--r-- | src/H5public.h | 9 |
11 files changed, 351 insertions, 14 deletions
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index e5578f9..146ae96 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -48,6 +48,7 @@ /****************/ #ifdef H5_HAVE_EFF + #define H5D_XFER_INJECT_BAD_CHECKSUM_SIZE sizeof(hbool_t) #define H5D_XFER_INJECT_BAD_CHECKSUM_DEF FALSE #define H5D_XFER_INJECT_BAD_CHECKSUM_ENC H5P__encode_hbool_t @@ -57,6 +58,12 @@ #define H5D_XFER_CHECKSUM_DEF 0 #define H5D_XFER_CHECKSUM_ENC H5P__encode_unsigned #define H5D_XFER_CHECKSUM_DEC H5P__decode_unsigned + +#define H5D_XFER_APPEND_ONLY_SIZE sizeof(hbool_t) +#define H5D_XFER_APPEND_ONLY_DEF FALSE +#define H5D_XFER_APPEND_ONLY_ENC H5P__encode_hbool_t +#define H5D_XFER_APPEND_ONLY_DEC H5P__decode_hbool_t + #endif /* H5_HAVE_EFF */ /* ======== Data transfer properties ======== */ @@ -252,6 +259,7 @@ const H5P_libclass_t H5P_CLS_DXFR[1] = {{ #ifdef H5_HAVE_EFF static const hbool_t H5D_def_inject_bad_checksum_g = H5D_XFER_INJECT_BAD_CHECKSUM_DEF; static const uint32_t H5D_def_checksum_g = H5D_XFER_CHECKSUM_DEF; +static const hbool_t H5D_def_append_only_g = H5D_XFER_APPEND_ONLY_DEF; #endif /* H5_HAVE_EFF */ /* Property value defaults */ @@ -307,6 +315,7 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) FUNC_ENTER_STATIC #ifdef H5_HAVE_EFF + if(H5P_register_real(pclass, H5D_XFER_INJECT_BAD_CHECKSUM_NAME, H5D_XFER_INJECT_BAD_CHECKSUM_SIZE, &H5D_def_inject_bad_checksum_g, NULL, NULL, NULL, H5D_XFER_INJECT_BAD_CHECKSUM_ENC, H5D_XFER_INJECT_BAD_CHECKSUM_DEC, @@ -318,6 +327,13 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, H5D_XFER_CHECKSUM_ENC, H5D_XFER_CHECKSUM_DEC, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + if(H5P_register_real(pclass, H5D_XFER_APPEND_ONLY_NAME, H5D_XFER_APPEND_ONLY_SIZE, + &H5D_def_append_only_g, + NULL, NULL, NULL, H5D_XFER_APPEND_ONLY_ENC, H5D_XFER_APPEND_ONLY_DEC, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + #endif /* H5_HAVE_EFF */ /* Register the max. temp buffer size property */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 63b31bc..34fc07f 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -272,6 +272,8 @@ H5_DLL H5S_t *H5S_decode(const unsigned char *buf); H5_DLL herr_t H5S_get_offsets(const H5S_t *space, size_t elmt_size, size_t nelmts, hsize_t **_off, size_t **_len, size_t *_num_entries); +H5_DLL uint32_t H5S_checksum(const void *buf, size_t elmt_size, size_t nelmts, + const H5S_t *space); #ifdef H5_HAVE_PARALLEL /* Global vars whose value comes from environment variable */ diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 23f87b1..1d6c63d 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -2143,3 +2143,78 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_get_offsets() */ + + +/*------------------------------------------------------------------------- + * Function: H5S_checksum + * + * Purpose: Computes a checksum for a buffer with a dataspace + * selection using the HDF5 fletcher checksume routines. + * + * Return: Returns a 32-bit value. Every bit of the key affects every bit of + * the return value. Two keys differing by one or two bits will have + * totally different hash values. + * + * Programmer: Mohamad Chaarawi + * June 2013 + * + *------------------------------------------------------------------------- + */ +uint32_t +H5S_checksum(const void *buf, size_t elmt_size, size_t nelmts, const H5S_t *space) +{ + hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */ + hsize_t *off = NULL; /* Pointer to sequence offsets in memory */ + size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */ + size_t *len = NULL; /* Pointer to sequence lengths in memory */ + H5S_sel_iter_t iter; /* Memory selection iteration info */ + hbool_t iter_init = 0; /* Memory selection iteration info has been initialized */ + size_t nseq; /* Number of sequences generated */ + uint32_t ret_value = 0; + + FUNC_ENTER_NOAPI_NOINIT + + len = _len; + off = _off; + + /* Check for only one element in selection */ + if(nelmts == 1) { + size_t buf_size = elmt_size * nelmts; + + if(H5S_SELECT_OFFSET(space, off) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, 0, "can't retrieve memory selection offset"); + + ret_value = H5_checksum_lookup3(buf, buf_size, ret_value); + } /* end if */ + else { + size_t nelem; /* Number of elements used in sequences */ + size_t i; + + /* Initialize iterator */ + if(H5S_select_iter_init(&iter, space, elmt_size) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, 0, "unable to initialize selection iterator") + iter_init = 1; + + nseq = 0; + + /* Loop, until all bytes are processed */ + while(nelmts > 0) { + /* Get sequences for selection */ + if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, H5D_IO_VECTOR_SIZE, nelmts, &nseq, + &nelem, off, len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed"); + + for(i=0 ; i<nseq ; i++) { + ret_value = H5_checksum_lookup3(&((char *)buf)[0]+off[i], len[i], ret_value); + } + nelmts -= nelem; + } /* end while */ + } /* end else */ + +done: + /* Release memory selection iterator */ + if(iter_init) + if(H5S_SELECT_ITER_RELEASE(&iter) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, 0, "unable to release selection iterator") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_checksum */ diff --git a/src/H5VLiod.c b/src/H5VLiod.c index a8562e9..d479676 100644 --- a/src/H5VLiod.c +++ b/src/H5VLiod.c @@ -683,6 +683,48 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_dxpl_inject_bad_checksum() */ +herr_t +H5Pset_dxpl_append_only(hid_t dxpl_id, hbool_t flag) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(dxpl_id == H5P_DEFAULT) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list") + + /* Check arguments */ + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl") + + /* Set the transfer mode */ + if(H5P_set(plist, H5D_XFER_APPEND_ONLY_NAME, &flag) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_dxpl_append_only() */ + +herr_t +H5Pget_dxpl_append_only(hid_t dxpl_id, hbool_t *flag/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl") + + /* Get the transfer mode */ + if(flag) + if(H5P_get(plist, H5D_XFER_APPEND_ONLY_NAME, flag) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_dxpl_append_only() */ /*------------------------------------------------------------------------- @@ -2304,12 +2346,15 @@ H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id, /* setup info struct for I/O request. This is to manage the I/O operation once the wait is called. */ - if(NULL == (info = (H5VL_iod_io_info_t *)H5MM_malloc(sizeof(H5VL_iod_io_info_t)))) + if(NULL == (info = (H5VL_iod_io_info_t *)H5MM_calloc(sizeof(H5VL_iod_io_info_t)))) HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a request"); info->status = status; info->bulk_handle = bulk_handle; info->buf_ptr = buf; - info->buf_size = buf_size; + info->nelmts = nelmts; + info->type_size = type_size; + if(NULL == (info->space = H5S_copy(mem_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace") /* Get async request for operation */ if(do_async) { @@ -2451,7 +2496,7 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, buf_size = nelmts * type_size; /* calculate a checksum for the data */ - internal_cs = H5_checksum_fletcher32(buf, buf_size); + internal_cs = H5S_checksum(buf, type_size, nelmts, mem_space); /* Verify the checksum value if the dxpl contains a user defined checksum */ if(H5P_DATASET_XFER_DEFAULT != dxpl_id) { @@ -2552,7 +2597,7 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, /* setup info struct for I/O request This is to manage the I/O operation once the wait is called. */ - if(NULL == (info = (H5VL_iod_io_info_t *)H5MM_malloc(sizeof(H5VL_iod_io_info_t)))) + if(NULL == (info = (H5VL_iod_io_info_t *)H5MM_calloc(sizeof(H5VL_iod_io_info_t)))) HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a request"); info->status = status; info->bulk_handle = bulk_handle; diff --git a/src/H5VLiod.h b/src/H5VLiod.h index 773f51b..a813f59 100644 --- a/src/H5VLiod.h +++ b/src/H5VLiod.h @@ -51,6 +51,7 @@ extern "C" { #define H5D_XFER_INJECT_BAD_CHECKSUM_NAME "inject_bad_checksum" #define H5D_XFER_CHECKSUM_NAME "checksum" +#define H5D_XFER_APPEND_ONLY_NAME "append_only" H5_DLL H5VL_class_t *H5VL_iod_init(void); H5_DLL herr_t H5Pset_fapl_iod(hid_t fapl_id, MPI_Comm comm, MPI_Info info); @@ -61,6 +62,8 @@ H5_DLL herr_t H5Pset_dxpl_checksum(hid_t dxpl_id, uint32_t flag); H5_DLL herr_t H5Pget_dxpl_checksum(hid_t dxpl_id, uint32_t *flag); H5_DLL herr_t H5Pset_dxpl_inject_bad_checksum(hid_t dxpl_id, hbool_t flag); H5_DLL herr_t H5Pget_dxpl_inject_bad_checksum(hid_t dxpl_id, hbool_t *flag); +H5_DLL herr_t H5Pset_dxpl_append_only(hid_t dxpl_id, hbool_t flag); +H5_DLL herr_t H5Pget_dxpl_append_only(hid_t dxpl_id, hbool_t *flag); #endif /* H5_HAVE_EFF */ #ifdef __cplusplus diff --git a/src/H5VLiod_client.c b/src/H5VLiod_client.c index 022f5ab..a34521c 100644 --- a/src/H5VLiod_client.c +++ b/src/H5VLiod_client.c @@ -26,6 +26,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ +#include "H5Sprivate.h" /* Dataspaces */ #include "H5VLprivate.h" /* VOL plugins */ #include "H5VLiod.h" /* Iod VOL plugin */ #include "H5VLiod_common.h" @@ -346,7 +347,7 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) req->state = H5VL_IOD_COMPLETED; } if(HG_DSET_WRITE == req->type && SUCCEED != *((int *)info->status)) { - fprintf(stderr, "write failed %d\n", *((int *)info->status)); + fprintf(stderr, "Errrr! Dataset Write Failure Reported from Server\n"); req->status = H5AO_FAILED; req->state = H5VL_IOD_COMPLETED; } @@ -354,7 +355,7 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; if(SUCCEED != read_status->ret) { - fprintf(stderr, "read failed\n"); + fprintf(stderr, "Errrr! Dataset Read Failure Reported from Server\n"); req->status = H5AO_FAILED; req->state = H5VL_IOD_COMPLETED; } @@ -362,15 +363,18 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) uint32_t internal_cs; /* calculate a checksum for the data recieved */ - internal_cs = H5_checksum_fletcher32(info->buf_ptr, info->buf_size); + internal_cs = H5S_checksum(info->buf_ptr, info->type_size, + info->nelmts, info->space); /* verify data integrity */ if(internal_cs != read_status->cs) { - fprintf(stderr, "Errrrr! Data integrity failure (expecting %u got %u).\n", + fprintf(stderr, "Errrrr! Dataset Read integrity failure (expecting %u got %u).\n", read_status->cs, internal_cs); req->status = H5AO_FAILED; req->state = H5VL_IOD_COMPLETED; } + if(info->space && H5S_close(info->space) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") } } @@ -394,7 +398,7 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) req->state = H5VL_IOD_COMPLETED; } if(SUCCEED != *((int *)info->status)) { - fprintf(stderr, "write failed %d\n", *((int *)info->status)); + fprintf(stderr, "Attribute I/O Failure Reported from Server\n"); req->status = H5AO_FAILED; req->state = H5VL_IOD_COMPLETED; } diff --git a/src/H5VLiod_client.h b/src/H5VLiod_client.h index 1722690..9e10328 100644 --- a/src/H5VLiod_client.h +++ b/src/H5VLiod_client.h @@ -196,7 +196,9 @@ typedef struct H5VL_iod_io_info_t { void *status; hg_bulk_t *bulk_handle; void *buf_ptr; - size_t buf_size; + size_t nelmts; + size_t type_size; + struct H5S_t *space; } H5VL_iod_io_info_t; H5_DLL herr_t H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t *request); diff --git a/src/H5VLiod_server.c b/src/H5VLiod_server.c index dfd3516..63c60c1 100644 --- a/src/H5VLiod_server.c +++ b/src/H5VLiod_server.c @@ -3368,11 +3368,14 @@ H5VL_iod_server_dset_read_cb(AXE_engine_t UNUSED axe_engine, if(H5Tconvert(src_id, dst_id, nelmts, buf, NULL, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed"); - cs = H5_checksum_fletcher32(buf, size); + /* calculate a checksum for the data to be sent */ + cs = H5_checksum_lookup3(buf, size, 0); + + /* MSC - check if client requested to corrupt data */ if(dxpl_id != H5P_DEFAULT && H5Pget_dxpl_inject_bad_checksum(dxpl_id, &flag) < 0) HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read property list"); if(flag) { - fprintf(stderr, "Injecting a bad data value to generate a bad checksum \n"); + fprintf(stderr, "Injecting a bad data value to cause corruption \n"); buf_ptr[0] = 10; } } @@ -3391,7 +3394,7 @@ done: output.ret = ret_value; output.cs = cs; - fprintf(stderr, "Done with dset read, sending response to client\n"); + fprintf(stderr, "Done with dset read, checksum %u, sending response to client\n", cs); if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output)) HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client"); @@ -3444,6 +3447,7 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, size_t size, buf_size, src_size, dst_size; void *buf; size_t nelmts; + hbool_t flag = FALSE; na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); herr_t ret_value = SUCCEED; @@ -3495,11 +3499,18 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, if(HG_SUCCESS != HG_Bulk_block_handle_free(bulk_block_handle)) HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle"); + /* MSC - check if client requested to corrupt data */ + if(dxpl_id != H5P_DEFAULT && H5Pget_dxpl_inject_bad_checksum(dxpl_id, &flag) < 0) + HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read property list"); + if(flag) { + ((int *)buf)[0] = 10; + } + /* If client specified a checksum, verify it */ if(dxpl_id != H5P_DEFAULT && H5Pget_dxpl_checksum(dxpl_id, &data_cs) < 0) HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read property list"); if(data_cs != 0) { - cs = H5_checksum_fletcher32(buf, size); + cs = H5_checksum_lookup3(buf, size, 0); if(cs != data_cs) { fprintf(stderr, "Errrr.. Network transfer Data corruption. expecting %u, got %u\n", data_cs, cs); diff --git a/src/H5checksum.c b/src/H5checksum.c index ec8b2b0..de1e491 100644 --- a/src/H5checksum.c +++ b/src/H5checksum.c @@ -430,6 +430,175 @@ done: FUNC_LEAVE_NOAPI(c) } /* end H5_checksum_lookup3() */ +uint32_t +H5_checksum_lookup4(const void *key, size_t length, H5_checksum_seed_t *cs) +{ + const uint8_t *k = (const uint8_t *)key; + uint32_t position = 0; + uint32_t a, b, c; /* internal state */ + int pos = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(key); + HDassert(length > 0); + + /* Set up the internal state */ + if(cs) { + if(!cs->a && !cs->b && !cs->c) { + a = b = c = 0xdeadbeef + ((uint32_t)cs->total_length); + /* Compute new State */ + cs->state = 12 - (length % 12); + } + else { + a = cs->a; + b = cs->b; + c = cs->c; + + /* determine position to start up on */ + if(cs->state) { + position = 12 - cs->state + 1; + } + + /* Compute new State */ + cs->state = cs->state - (length % 12); + if(cs->state < 0) { + H5_lookup3_mix(a, b, c); + cs->state = 12 + cs->state; + } + + /* Move towards mod 12 */ + switch(position) /* all the case statements fall through */ + { + case 0 : + break; + case 1 : + a+=k[pos++]; + length --; + if(0 == length) + break; + case 2 : + a+=((uint32_t)k[pos++])<<8; + length --; + if(0 == length) + break; + case 3 : + a+=((uint32_t)k[pos++])<<16; + length --; + if(0 == length) + break; + case 4 : + a+=((uint32_t)k[pos++])<<24; + length --; + if(0 == length) + break; + case 5 : + b+=k[pos++]; + length --; + if(0 == length) + break; + case 6 : + b+=((uint32_t)k[pos++])<<8; + length --; + if(0 == length) + break; + case 7 : + b+=((uint32_t)k[pos++])<<16; + length --; + if(0 == length) + break; + case 8 : + b+=((uint32_t)k[pos++])<<24; + length --; + if(0 == length) + break; + case 9 : + c+=k[pos++]; + length --; + if(0 == length) + break; + case 10: + c+=((uint32_t)k[pos++])<<8; + length --; + if(0 == length) + break; + case 11: + c+=((uint32_t)k[pos++])<<16; + length --; + if(0 == length) + break; + case 12: + c+=((uint32_t)k[pos++])<<24; + length --; + H5_lookup3_mix(a, b, c); + break; + } + } + /* capture internal state if we are done at this stage */ + if(0 == length) { + cs->a = a; + cs->b = b; + cs->c = c; + H5_lookup3_final(a, b, c); + goto done; + } + } + else + a = b = c = 0xdeadbeef + ((uint32_t)length); + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0+pos]; + a += ((uint32_t)k[1+pos])<<8; + a += ((uint32_t)k[2+pos])<<16; + a += ((uint32_t)k[3+pos])<<24; + b += k[4+pos]; + b += ((uint32_t)k[5+pos])<<8; + b += ((uint32_t)k[6+pos])<<16; + b += ((uint32_t)k[7+pos])<<24; + c += k[8+pos]; + c += ((uint32_t)k[9+pos])<<8; + c += ((uint32_t)k[10+pos])<<16; + c += ((uint32_t)k[11+pos])<<24; + H5_lookup3_mix(a, b, c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11+pos])<<24; + case 11: c+=((uint32_t)k[10+pos])<<16; + case 10: c+=((uint32_t)k[9+pos])<<8; + case 9 : c+=k[8+pos]; + case 8 : b+=((uint32_t)k[7+pos])<<24; + case 7 : b+=((uint32_t)k[6+pos])<<16; + case 6 : b+=((uint32_t)k[5+pos])<<8; + case 5 : b+=k[4+pos]; + case 4 : a+=((uint32_t)k[3+pos])<<24; + case 3 : a+=((uint32_t)k[2+pos])<<16; + case 2 : a+=((uint32_t)k[1+pos])<<8; + case 1 : a+=k[pos]; + break; + case 0 : goto done; + } + + /* capture internal state */ + if(cs) { + cs->a = a; + cs->b = b; + cs->c = c; + } + + H5_lookup3_final(a, b, c); + +done: + FUNC_LEAVE_NOAPI(c) +} /* end H5_checksum_lookup3() */ + /*------------------------------------------------------------------------- * Function: H5_checksum_metadata diff --git a/src/H5private.h b/src/H5private.h index 46c02e7..42ea519 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -2361,6 +2361,7 @@ H5_DLL int H5Z_term_interface(void); H5_DLL uint32_t H5_checksum_fletcher32(const void *data, size_t len); H5_DLL uint32_t H5_checksum_crc(const void *data, size_t len); H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initval); +H5_DLL uint32_t H5_checksum_lookup4(const void *data, size_t len, H5_checksum_seed_t *cs); H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval); H5_DLL uint32_t H5_hash_string(const char *str); diff --git a/src/H5public.h b/src/H5public.h index deb4587..d0f3e78 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -301,6 +301,15 @@ typedef struct H5_ih_info_t { hsize_t heap_size; } H5_ih_info_t; +/* Internal Checksum state */ +typedef struct H5_checksum_seed_t { + uint32_t a; + uint32_t b; + uint32_t c; + int32_t state; + size_t total_length; +} H5_checksum_seed_t; + /* Functions in H5.c */ H5_DLL herr_t H5open(void); H5_DLL herr_t H5close(void); |