/* array for verification of some tests */ typedefstruct ItemArray
{
ItemPointerData *insert_tids;
ItemPointerData *lookup_tids;
ItemPointerData *iter_tids; int max_tids; int num_tids;
} ItemArray;
/* *Remainattacheduntilendofbackendorexplicitlydetachedsothat *thesameprocessusethetidstoreforsubsequenttests.
*/
dsa_pin_mapping(TidStoreGetDSA(tidstore));
} else /* VACUUM uses insert only, so we test the other option. */
tidstore = TidStoreCreateLocal(tidstore_max_size, false);
staticvoid
sanity_check_array(ArrayType *ta)
{ if (ARR_HASNULL(ta) && array_contains_nulls(ta))
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("array must not contain nulls")));
if (ARR_NDIM(ta) > 1)
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
errmsg("argument must be empty or one-dimensional array")));
}
staticvoid
check_tidstore_available(void)
{ if (tidstore == NULL)
elog(ERROR, "tidstore is not created");
}
staticvoid
purge_from_verification_array(BlockNumber blkno)
{ int dst = 0;
for (int src = 0; src < items.num_tids; src++) if (ItemPointerGetBlockNumber(&items.insert_tids[src]) != blkno)
items.insert_tids[dst++] = items.insert_tids[src];
items.num_tids = dst;
}
/* Set the given block and offsets pairs */
Datum
do_set_block_offsets(PG_FUNCTION_ARGS)
{
BlockNumber blkno = PG_GETARG_INT64(0);
ArrayType *ta = PG_GETARG_ARRAYTYPE_P_COPY(1);
OffsetNumber *offs; int noffs;
/* TidStoreSetBlockOffsets() requires offsets to be strictly ascending. */
qsort(offs, noffs, sizeof(OffsetNumber), offsetnumber_cmp);
/* Set TIDs in the store */
TidStoreLockExclusive(tidstore);
TidStoreSetBlockOffsets(tidstore, blkno, offs, noffs);
TidStoreUnlock(tidstore);
/* Remove the existing items of blkno from the verification array */
purge_from_verification_array(blkno);
/* Set TIDs in verification array */ for (int i = 0; i < noffs; i++)
{
ItemPointer tid; int idx = items.num_tids + i;
/* Enlarge the TID arrays if necessary */ if (idx >= items.max_tids)
{
items.max_tids *= 2;
items.insert_tids = repalloc(items.insert_tids, sizeof(ItemPointerData) * items.max_tids);
items.lookup_tids = repalloc(items.lookup_tids, sizeof(ItemPointerData) * items.max_tids);
items.iter_tids = repalloc(items.iter_tids, sizeof(ItemPointerData) * items.max_tids);
}
tid = &(items.insert_tids[idx]);
ItemPointerSet(tid, blkno, offs[i]);
}
/* Update statistics */
items.num_tids += noffs;
PG_RETURN_INT64(blkno);
}
/* *VerifyTIDsinstoreagainstthearray.
*/
Datum
check_set_block_offsets(PG_FUNCTION_ARGS)
{
TidStoreIter *iter;
TidStoreIterResult *iter_result; int num_iter_tids = 0; int num_lookup_tids = 0;
BlockNumber prevblkno = 0;
check_tidstore_available();
/* lookup each member in the verification array */ for (int i = 0; i < items.num_tids; i++) if (!TidStoreIsMember(tidstore, &items.insert_tids[i]))
elog(ERROR, "missing TID with block %u, offset %u",
ItemPointerGetBlockNumber(&items.insert_tids[i]),
ItemPointerGetOffsetNumber(&items.insert_tids[i]));
TidStoreLockShare(tidstore); if (TidStoreIsMember(tidstore, &tid))
ItemPointerSet(&items.lookup_tids[num_lookup_tids++], blkno, offset);
TidStoreUnlock(tidstore);
}
prevblkno = blkno;
}
/* Collect TIDs stored in the tidstore, in order */
TidStoreLockShare(tidstore);
iter = TidStoreBeginIterate(tidstore); while ((iter_result = TidStoreIterateNext(iter)) != NULL)
{
OffsetNumber offsets[MaxOffsetNumber]; int num_offsets;
num_offsets = TidStoreGetBlockOffsets(iter_result, offsets, lengthof(offsets));
Assert(num_offsets <= lengthof(offsets)); for (int i = 0; i < num_offsets; i++)
ItemPointerSet(&(items.iter_tids[num_iter_tids++]), iter_result->blkno,
offsets[i]);
}
TidStoreEndIterate(iter);
TidStoreUnlock(tidstore);
if (num_lookup_tids != items.num_tids)
elog(ERROR, "should have %d TIDs, have %d", items.num_tids, num_lookup_tids); if (num_iter_tids != items.num_tids)
elog(ERROR, "should have %d TIDs, have %d", items.num_tids, num_iter_tids);
qsort(items.insert_tids, items.num_tids, sizeof(ItemPointerData), itemptr_cmp);
qsort(items.lookup_tids, items.num_tids, sizeof(ItemPointerData), itemptr_cmp); for (int i = 0; i < items.num_tids; i++)
{ if (itemptr_cmp(&items.insert_tids[i], &items.iter_tids[i]) != 0)
elog(ERROR, "TID iter array doesn't match verification array, got (%u,%u) expected (%u,%u)",
ItemPointerGetBlockNumber(&items.iter_tids[i]),
ItemPointerGetOffsetNumber(&items.iter_tids[i]),
ItemPointerGetBlockNumber(&items.insert_tids[i]),
ItemPointerGetOffsetNumber(&items.insert_tids[i])); if (itemptr_cmp(&items.insert_tids[i], &items.lookup_tids[i]) != 0)
elog(ERROR, "TID lookup array doesn't match verification array, got (%u,%u) expected (%u,%u)",
ItemPointerGetBlockNumber(&items.lookup_tids[i]),
ItemPointerGetOffsetNumber(&items.lookup_tids[i]),
ItemPointerGetBlockNumber(&items.insert_tids[i]),
ItemPointerGetOffsetNumber(&items.insert_tids[i]));
}
PG_RETURN_VOID();
}
/* *Inrealworlduse,wecareifthememoryusageisgreaterthan *someconfiguredlimit.Herewejustwanttoverifythat *TidStoreMemoryUsageisnotbroken.
*/
Datum
test_is_full(PG_FUNCTION_ARGS)
{ bool is_full;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.