/*------------------------------------------------------------------------- * Function: test_3 * * Purpose: Creates a few global heap objects and then removes them all. * The collection should also be removed. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Tuesday, March 31, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int test_3 (hid_t fapl) { hid_t file = -1; H5F_t *f = NULL; H5HG_t obj[1024]; uint8_t out[1024]; int i; size_t size; herr_t status; int nerrors = 0; char filename[1024]; TESTING("complete object removal"); /* Open a clean file */ h5_fixname(FILENAME[2], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to create file"); goto error; } /* Create some stuff */ for (i=0; i<1024; i++) { size = i%30+100; memset (out, 'A'+i%26, size); H5Eclear2(H5E_DEFAULT); status = H5HG_insert (f, H5P_DATASET_XFER_DEFAULT, size, out, obj+i); if (status<0) { H5_FAILED(); puts(" Unable to insert object into global heap"); nerrors++; } } /* Remove everything */ for (i=0; i<1024; i++) { status = H5HG_remove (f, H5P_DATASET_XFER_DEFAULT, obj+i); if (status<0) { H5_FAILED(); puts(" Unable to remove object"); nerrors++; } } if (H5Fclose(file)<0) goto error; if (nerrors) goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return MAX(1, nerrors); }
/*-------------------------------------------------------------------------- NAME H5R__create PURPOSE Creates a particular kind of reference for the user USAGE herr_t H5R__create(ref, loc, name, ref_type, space) void *ref; OUT: Reference created H5G_loc_t *loc; IN: File location used to locate object pointed to const char *name; IN: Name of object at location LOC_ID of object pointed to H5R_type_t ref_type; IN: Type of reference to create H5S_t *space; IN: Dataspace ID with selection, used for Dataset Region references. RETURNS Non-negative on success/Negative on failure DESCRIPTION Creates a particular type of reference specified with REF_TYPE, in the space pointed to by REF. The LOC_ID and NAME are used to locate the object pointed to and the SPACE_ID is used to choose the region pointed to (for Dataset Region references). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ herr_t H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space) { H5G_loc_t obj_loc; /* Group hier. location of object */ H5G_name_t path; /* Object group hier. path */ H5O_loc_t oloc; /* Object object location */ hbool_t obj_found = FALSE; /* Object location found */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_VOL HDassert(_ref); HDassert(loc); HDassert(name); HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); /* Set up object location to fill in */ obj_loc.oloc = &oloc; obj_loc.path = &path; H5G_loc_reset(&obj_loc); /* Find the object */ if(H5G_loc_find(loc, name, &obj_loc) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") obj_found = TRUE; switch (ref_type) { case H5R_OBJECT: { hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */ *ref = obj_loc.oloc->addr; break; } case H5R_DATASET_REGION: { H5HG_t hobjid; /* Heap object ID */ hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ hssize_t buf_size; /* Size of buffer needed to serialize selection */ uint8_t *p; /* Pointer to OID to store */ uint8_t *buf; /* Buffer to store serialized selection in */ unsigned heapid_found; /* Flag for non-zero heap ID found */ unsigned u; /* local index */ /* Set up information for dataset region */ /* Return any previous heap block to the free list if we are * garbage collecting */ if (H5F_GC_REF(loc->oloc->file)) { /* Check for an existing heap ID in the reference */ for (u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++) if (p[u] != 0) { heapid_found = 1; break; } if (heapid_found != 0) { /* Return heap block to free list */ } } /* Zero the heap ID out, may leak heap space if user is re-using * reference and doesn't have garbage collection turned on */ HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE); /* Get the amount of space required to serialize the selection */ if ((buf_size = H5S_SELECT_SERIAL_SIZE(space, loc->oloc->file)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection") /* Increase buffer size to allow for the dataset OID */ buf_size += (hssize_t)sizeof(haddr_t); /* Allocate the space to store the serialized information */ H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); if (NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Serialize information for dataset OID into heap buffer */ p = (uint8_t *)buf; H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); /* Serialize the selection into heap buffer */ if (H5S_SELECT_SERIALIZE(space, &p, loc->oloc->file) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") /* Save the serialized buffer for later */ H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); if(H5HG_insert(loc->oloc->file, (size_t)buf_size, buf, &hobjid) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection") /* Serialize the heap ID and index for storage in the file */ p = (uint8_t *)ref; H5F_addr_encode(loc->oloc->file, &p, hobjid.addr); UINT32ENCODE(p, hobjid.idx); /* Free the buffer we serialized data in */ H5MM_xfree(buf); break; } /* end case H5R_DATASET_REGION */ case H5R_BADTYPE: case H5R_MAXTYPE: default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ done: if (obj_found) H5G_loc_free(&obj_loc); FUNC_LEAVE_NOAPI_VOL(ret_value) } /* end H5R__create() */
/*------------------------------------------------------------------------- * Function: test_1 * * Purpose: Writes a sequence of objects to the global heap where each * object is larger than the one before. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Tuesday, March 31, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int test_1 (hid_t fapl) { hid_t file = -1; H5F_t *f = NULL; H5HG_t obj[1024]; uint8_t out[1024]; uint8_t in[1024]; int i; size_t size; herr_t status; int nerrors = 0; char filename[1024]; TESTING("monotonically increasing lengths"); /* Open a clean file */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to create file"); goto error; } /* * Write the objects, monotonically increasing in length. Since this is * a clean file, the addresses allocated for the collections should also * be monotonically increasing. */ for(i = 0; i < 1024; i++) { size = i + 1; HDmemset(out, 'A' + i % 26, size); H5Eclear2(H5E_DEFAULT); status = H5HG_insert(f, H5P_DATASET_XFER_DEFAULT, size, out, obj + i); if(status < 0) { H5_FAILED(); puts(" Unable to insert object into global heap"); nerrors++; } else if(i && H5F_addr_gt(obj[i - 1].addr, obj[i].addr)) { H5_FAILED(); puts(" Collection addresses are not monotonically increasing"); nerrors++; } } /* * Now try to read each object back. */ for(i = 0; i < 1024; i++) { size = i + 1; HDmemset(out, 'A' + i % 26, size); H5Eclear2(H5E_DEFAULT); if(NULL == H5HG_read(f, H5P_DATASET_XFER_DEFAULT, obj + i, in, NULL)) { H5_FAILED(); puts(" Unable to read object"); nerrors++; } else if(HDmemcmp(in, out, size)) { H5_FAILED(); puts(" Value read doesn't match value written"); nerrors++; } } if(H5Fclose(file) < 0) goto error; if(nerrors) goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return MAX(1, nerrors); }
/*------------------------------------------------------------------------- * Function: test_ooo_indices * * Purpose: Tests that indices can be stored out of order. This can * happen when the indices "wrap around" due to many * insertions and deletions (for example, from rewriting a * VL dataset). * * Return: Success: 0 * * Failure: number of errors * * Programmer: Neil Fortner * Monday, October 26, 2009 * * Modifications: * *------------------------------------------------------------------------- */ static int test_ooo_indices(hid_t fapl) { hid_t file = -1; H5F_t *f = NULL; unsigned i, j; H5HG_t *obj = NULL; herr_t status; int nerrors=0; char filename[1024]; TESTING("out of order indices"); if(NULL == (obj = (H5HG_t *)HDmalloc(2000 * sizeof(*obj)))) goto error; /* Open a clean file */ h5_fixname(FILENAME[4], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to create file"); goto error; } /* end if */ /* Alternately insert 1000 entries and remove the previous group of 1000 * entries, until the indices wrap around */ for(i=0; i<66; i++) { /* Insert 1000 entries. The index into the obj array will alternate up * and down by 1000 so the previous set of insertions is preserved and * can be deleted. */ for(j=1000*((~i&1)); j<1000*((~i&1)+1); j++) { H5Eclear2(H5E_DEFAULT); status = H5HG_insert(f, H5P_DATASET_XFER_DEFAULT, sizeof(j), &j, &obj[j]); if (status<0) GHEAP_REPEATED_ERR(" Unable to insert object into global heap") /* Check that the index is as expected */ if(obj[j].idx != ((1000 * i) + j - (1000 * ((~i & 1)))) % ((1u << 16) - 1) + 1) GHEAP_REPEATED_ERR(" Unexpected global heap index"); } /* end for */ /* Remove the previous 1000 entries */ if(i>0) for(j=1000*(i&1); j<1000*((i&1)+1); j++) { H5Eclear2(H5E_DEFAULT); status = H5HG_remove(f, H5P_DATASET_XFER_DEFAULT, &obj[j]); if (status<0) GHEAP_REPEATED_ERR(" Unable to remove object from global heap"); } /* end for */ } /* end for */ /* The indices should have "wrapped around" on the last iteration */ HDassert(obj[534].idx == 65535); HDassert(obj[535].idx == 1); /* Reopen the file */ if (H5Fclose(file)<0) goto error; if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to open file"); goto error; } /* end if */ /* Read the objects to make sure the heap is still readable */ for(i=0; i<1000; i++) { if(NULL == H5HG_read(f, H5P_DATASET_XFER_DEFAULT, &obj[i], &j, NULL)) goto error; if(i != j) { H5_FAILED(); puts(" Incorrect read value"); goto error; } /* end if */ } /* end for */ if (H5Fclose(file)<0) goto error; if (nerrors) goto error; HDfree(obj); obj = NULL; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; if(obj) HDfree(obj); return MAX(1, nerrors); } /* end test_ooo_indices */
/*------------------------------------------------------------------------- * Function: test_4 * * Purpose: Tests the H5HG_remove() feature by writing lots of objects * and occassionally removing some. When we're done they're all * removed. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Tuesday, March 31, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int test_4 (hid_t fapl) { hid_t file = -1; H5F_t *f = NULL; H5HG_t obj[1024]; uint8_t out[1024]; int i; size_t size; herr_t status; int nerrors = 0; char filename[1024]; TESTING("partial object removal"); /* Open a clean file */ h5_fixname(FILENAME[3], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to create file"); goto error; } for (i=0; i<1024; i++) { /* Insert */ size = i%30+100; memset (out, 'A'+i%26, size); H5Eclear2(H5E_DEFAULT); status = H5HG_insert (f, H5P_DATASET_XFER_DEFAULT, size, out, obj+i); if (status<0) { H5_FAILED(); puts(" Unable to insert object into global heap"); nerrors++; } /* * Remove every third one beginning with the second, but after the * next one has already been inserted. That is, insert A, B, C; * remove B, insert D, E, F; remove E; etc. */ if (1==i%3) { H5Eclear2(H5E_DEFAULT); status = H5HG_remove (f, H5P_DATASET_XFER_DEFAULT, obj+i-1); if (status<0) { H5_FAILED(); puts(" Unable to remove object"); nerrors++; } memset (obj+i-1, 0, sizeof *obj); } } if (H5Fclose(file)<0) goto error; if (nerrors) goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return MAX(1, nerrors); }
/*------------------------------------------------------------------------- * Function: test_2 * * Purpose: Writes a sequence of objects to the global heap where each * object is smaller than the one before. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Tuesday, March 31, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int test_2 (hid_t fapl) { hid_t file = -1; H5F_t *f = NULL; H5HG_t obj[1024]; uint8_t out[1024]; uint8_t in[1024]; int i; size_t size; int nerrors = 0; char filename[1024]; TESTING("monotonically decreasing lengths"); /* Open a clean file */ h5_fixname(FILENAME[1], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to create file"); goto error; } /* * Write the objects, monotonically decreasing in length. */ for (i=0; i<1024; i++) { size = 1024-i; memset (out, 'A'+i%26, size); H5Eclear2(H5E_DEFAULT); if (H5HG_insert (f, H5P_DATASET_XFER_DEFAULT, size, out, obj+i)<0) { H5_FAILED(); puts(" Unable to insert object into global heap"); nerrors++; } } /* * Now try to read each object back. */ for (i=0; i<1024; i++) { size = 1024-i; memset (out, 'A'+i%26, size); H5Eclear2(H5E_DEFAULT); if (NULL==H5HG_read (f, H5P_DATASET_XFER_DEFAULT, obj+i, in, NULL)) { H5_FAILED(); puts(" Unable to read object"); nerrors++; } else if (memcmp (in, out, size)) { H5_FAILED(); puts(" Value read doesn't match value written"); nerrors++; } } if (H5Fclose(file)<0) goto error; if (nerrors) goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return MAX(1, nerrors); }