From bb42e21be274a71f6868ce2fc8fae2c15c3ecf66 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 24 Mar 2014 18:40:26 +0200 Subject: [PATCH] Change ginMergeItemPointers to return a palloc'd array. That seems nicer than making it the caller's responsibility to pass a suitable-sized array. All the callers were just palloc'ing an array anyway. --- src/backend/access/gin/gindatapage.c | 7 ++--- src/backend/access/gin/gininsert.c | 9 ++---- src/backend/access/gin/ginpostinglist.c | 40 +++++++++++++------------ src/include/access/gin_private.h | 6 ++-- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c index c6230f3bc5..313d53c354 100644 --- a/src/backend/access/gin/gindatapage.c +++ b/src/backend/access/gin/gindatapage.c @@ -1303,10 +1303,9 @@ addItemsToLeaf(disassembledLeaf *leaf, ItemPointer newItems, int nNewItems) 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; diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index cd9c7c120b..3bafb6471b 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -67,12 +67,9 @@ addItemPointersToLeafTuple(GinState *ginstate, /* 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; diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c index f532a3dbf0..4c4110d54b 100644 --- a/src/backend/access/gin/ginpostinglist.c +++ b/src/backend/access/gin/ginpostinglist.c @@ -346,20 +346,18 @@ ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int len, /* * 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 @@ -367,18 +365,22 @@ ginMergeItemPointers(ItemPointerData *dst, */ 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); @@ -401,8 +403,8 @@ ginMergeItemPointers(ItemPointerData *dst, while (bptr - b < nb) *dptr++ = *bptr++; - result = dptr - dst; + *nmerged = dptr - dst; } - return result; + return dst; } diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 009927282f..a7beed1f25 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -919,9 +919,9 @@ extern int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int totalsi 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, -- 2.40.0