if (!cur->items)
cur->items = ginPostingListDecode(cur->seg, &cur->nitems);
- tmpitems = palloc((cur->nitems + nthis) * sizeof(ItemPointerData));
- ntmpitems = ginMergeItemPointers(tmpitems,
- cur->items, cur->nitems,
- nextnew, nthis);
+ tmpitems = ginMergeItemPointers(cur->items, cur->nitems,
+ nextnew, nthis,
+ &ntmpitems);
if (ntmpitems != cur->nitems)
{
cur->items = tmpitems;
/* merge the old and new posting lists */
oldItems = ginReadTuple(ginstate, attnum, old, &oldNPosting);
- newNPosting = oldNPosting + nitem;
- newItems = (ItemPointerData *) palloc(sizeof(ItemPointerData) * newNPosting);
-
- newNPosting = ginMergeItemPointers(newItems,
- items, nitem,
- oldItems, oldNPosting);
+ newItems = ginMergeItemPointers(items, nitem,
+ oldItems, oldNPosting,
+ &newNPosting);
/* Compress the posting list, and try to a build tuple with room for it */
res = NULL;
/*
* Merge two ordered arrays of itempointers, eliminating any duplicates.
- * Returns the number of items in the result.
- * Caller is responsible that there is enough space at *dst.
*
- * It's OK if 'dst' overlaps with the *beginning* of one of the arguments.
+ * Returns a palloc'd array, and *nmerged is set to the number of items in
+ * the result, after eliminating duplicates.
*/
-int
-ginMergeItemPointers(ItemPointerData *dst,
- ItemPointerData *a, uint32 na,
- ItemPointerData *b, uint32 nb)
+ItemPointer
+ginMergeItemPointers(ItemPointerData *a, uint32 na,
+ ItemPointerData *b, uint32 nb,
+ int *nmerged)
{
- ItemPointerData *dptr = dst;
- ItemPointerData *aptr = a,
- *bptr = b;
- int result;
+ ItemPointerData *dst;
+
+ dst = (ItemPointer) palloc((na + nb) * sizeof(ItemPointerData));
/*
* If the argument arrays don't overlap, we can just append them to
*/
if (na == 0 || nb == 0 || ginCompareItemPointers(&a[na - 1], &b[0]) < 0)
{
- memmove(dst, a, na * sizeof(ItemPointerData));
- memmove(&dst[na], b, nb * sizeof(ItemPointerData));
- result = na + nb;
+ memcpy(dst, a, na * sizeof(ItemPointerData));
+ memcpy(&dst[na], b, nb * sizeof(ItemPointerData));
+ *nmerged = na + nb;
}
else if (ginCompareItemPointers(&b[nb - 1], &a[0]) < 0)
{
- memmove(dst, b, nb * sizeof(ItemPointerData));
- memmove(&dst[nb], a, na * sizeof(ItemPointerData));
- result = na + nb;
+ memcpy(dst, b, nb * sizeof(ItemPointerData));
+ memcpy(&dst[nb], a, na * sizeof(ItemPointerData));
+ *nmerged = na + nb;
}
else
{
+ ItemPointerData *dptr = dst;
+ ItemPointerData *aptr = a;
+ ItemPointerData *bptr = b;
+
while (aptr - a < na && bptr - b < nb)
{
int cmp = ginCompareItemPointers(aptr, bptr);
while (bptr - b < nb)
*dptr++ = *bptr++;
- result = dptr - dst;
+ *nmerged = dptr - dst;
}
- return result;
+ return dst;
}
extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *ptr, int len, int *ndecoded);
extern ItemPointer ginPostingListDecode(GinPostingList *ptr, int *ndecoded);
-extern int ginMergeItemPointers(ItemPointerData *dst,
- ItemPointerData *a, uint32 na,
- ItemPointerData *b, uint32 nb);
+extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na,
+ ItemPointerData *b, uint32 nb,
+ int *nmerged);
/*
* Merging the results of several gin scans compares item pointers a lot,