PostgreSQL Source Code  git master
ginpostinglist.c File Reference
#include "postgres.h"
#include "access/gin_private.h"
Include dependency graph for ginpostinglist.c:

Go to the source code of this file.

Macros

#define MaxHeapTuplesPerPageBits   11
 
#define MaxBytesPerInteger   7
 

Functions

static uint64 itemptr_to_uint64 (const ItemPointer iptr)
 
static void uint64_to_itemptr (uint64 val, ItemPointer iptr)
 
static void encode_varbyte (uint64 val, unsigned char **ptr)
 
static uint64 decode_varbyte (unsigned char **ptr)
 
GinPostingListginCompressPostingList (const ItemPointer ipd, int nipd, int maxsize, int *nwritten)
 
ItemPointer ginPostingListDecode (GinPostingList *plist, int *ndecoded)
 
ItemPointer ginPostingListDecodeAllSegments (GinPostingList *segment, int len, int *ndecoded_out)
 
int ginPostingListDecodeAllSegmentsToTbm (GinPostingList *ptr, int len, TIDBitmap *tbm)
 
ItemPointer ginMergeItemPointers (ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb, int *nmerged)
 

Macro Definition Documentation

◆ MaxBytesPerInteger

#define MaxBytesPerInteger   7

Definition at line 84 of file ginpostinglist.c.

Referenced by ginCompressPostingList().

◆ MaxHeapTuplesPerPageBits

#define MaxHeapTuplesPerPageBits   11

Definition at line 81 of file ginpostinglist.c.

Referenced by itemptr_to_uint64(), and uint64_to_itemptr().

Function Documentation

◆ decode_varbyte()

static uint64 decode_varbyte ( unsigned char **  ptr)
static

Definition at line 133 of file ginpostinglist.c.

References Assert, and val.

Referenced by ginPostingListDecodeAllSegments().

134 {
135  uint64 val;
136  unsigned char *p = *ptr;
137  uint64 c;
138 
139  /* 1st byte */
140  c = *(p++);
141  val = c & 0x7F;
142  if (c & 0x80)
143  {
144  /* 2nd byte */
145  c = *(p++);
146  val |= (c & 0x7F) << 7;
147  if (c & 0x80)
148  {
149  /* 3rd byte */
150  c = *(p++);
151  val |= (c & 0x7F) << 14;
152  if (c & 0x80)
153  {
154  /* 4th byte */
155  c = *(p++);
156  val |= (c & 0x7F) << 21;
157  if (c & 0x80)
158  {
159  /* 5th byte */
160  c = *(p++);
161  val |= (c & 0x7F) << 28;
162  if (c & 0x80)
163  {
164  /* 6th byte */
165  c = *(p++);
166  val |= (c & 0x7F) << 35;
167  if (c & 0x80)
168  {
169  /* 7th byte, should not have continuation bit */
170  c = *(p++);
171  val |= c << 42;
172  Assert((c & 0x80) == 0);
173  }
174  }
175  }
176  }
177  }
178  }
179 
180  *ptr = p;
181 
182  return val;
183 }
char * c
#define Assert(condition)
Definition: c.h:732
long val
Definition: informix.c:684

◆ encode_varbyte()

static void encode_varbyte ( uint64  val,
unsigned char **  ptr 
)
static

Definition at line 115 of file ginpostinglist.c.

References val.

Referenced by ginCompressPostingList().

116 {
117  unsigned char *p = *ptr;
118 
119  while (val > 0x7F)
120  {
121  *(p++) = 0x80 | (val & 0x7F);
122  val >>= 7;
123  }
124  *(p++) = (unsigned char) val;
125 
126  *ptr = p;
127 }
long val
Definition: informix.c:684

◆ ginCompressPostingList()

GinPostingList* ginCompressPostingList ( const ItemPointer  ipd,
int  nipd,
int  maxsize,
int *  nwritten 
)

Definition at line 197 of file ginpostinglist.c.

References Assert, buf, generate_unaccent_rules::bytes(), GinPostingList::bytes, encode_varbyte(), GinPostingList::first, ginPostingListDecode(), i, itemptr_to_uint64(), MaxBytesPerInteger, GinPostingList::nbytes, offsetof, palloc(), pfree(), SHORTALIGN, SHORTALIGN_DOWN, SizeOfGinPostingList, and val.

Referenced by addItemPointersToLeafTuple(), buildFreshLeafTuple(), createPostingTree(), ginRedoRecompress(), ginVacuumEntryPage(), ginVacuumPostingTreeLeaf(), leafRepackItems(), and test_itemptr_pair().

199 {
200  uint64 prev;
201  int totalpacked = 0;
202  int maxbytes;
203  GinPostingList *result;
204  unsigned char *ptr;
205  unsigned char *endptr;
206 
207  maxsize = SHORTALIGN_DOWN(maxsize);
208 
209  result = palloc(maxsize);
210 
211  maxbytes = maxsize - offsetof(GinPostingList, bytes);
212  Assert(maxbytes > 0);
213 
214  /* Store the first special item */
215  result->first = ipd[0];
216 
217  prev = itemptr_to_uint64(&result->first);
218 
219  ptr = result->bytes;
220  endptr = result->bytes + maxbytes;
221  for (totalpacked = 1; totalpacked < nipd; totalpacked++)
222  {
223  uint64 val = itemptr_to_uint64(&ipd[totalpacked]);
224  uint64 delta = val - prev;
225 
226  Assert(val > prev);
227 
228  if (endptr - ptr >= MaxBytesPerInteger)
229  encode_varbyte(delta, &ptr);
230  else
231  {
232  /*
233  * There are less than 7 bytes left. Have to check if the next
234  * item fits in that space before writing it out.
235  */
236  unsigned char buf[MaxBytesPerInteger];
237  unsigned char *p = buf;
238 
239  encode_varbyte(delta, &p);
240  if (p - buf > (endptr - ptr))
241  break; /* output is full */
242 
243  memcpy(ptr, buf, p - buf);
244  ptr += (p - buf);
245  }
246  prev = val;
247  }
248  result->nbytes = ptr - result->bytes;
249 
250  /*
251  * If we wrote an odd number of bytes, zero out the padding byte at the
252  * end.
253  */
254  if (result->nbytes != SHORTALIGN(result->nbytes))
255  result->bytes[result->nbytes] = 0;
256 
257  if (nwritten)
258  *nwritten = totalpacked;
259 
260  Assert(SizeOfGinPostingList(result) <= maxsize);
261 
262  /*
263  * Check that the encoded segment decodes back to the original items.
264  */
265 #if defined (CHECK_ENCODING_ROUNDTRIP)
266  {
267  int ndecoded;
268  ItemPointer tmp = ginPostingListDecode(result, &ndecoded);
269  int i;
270 
271  Assert(ndecoded == totalpacked);
272  for (i = 0; i < ndecoded; i++)
273  Assert(memcmp(&tmp[i], &ipd[i], sizeof(ItemPointerData)) == 0);
274  pfree(tmp);
275  }
276 #endif
277 
278  return result;
279 }
ItemPointer ginPostingListDecode(GinPostingList *plist, int *ndecoded)
def bytes(source, encoding='ascii', errors='strict')
#define SHORTALIGN_DOWN(LEN)
Definition: c.h:693
ItemPointerData first
Definition: ginblock.h:338
void pfree(void *pointer)
Definition: mcxt.c:1056
unsigned char bytes[FLEXIBLE_ARRAY_MEMBER]
Definition: ginblock.h:340
#define MaxBytesPerInteger
static char * buf
Definition: pg_test_fsync.c:68
uint16 nbytes
Definition: ginblock.h:339
#define Assert(condition)
Definition: c.h:732
static uint64 itemptr_to_uint64(const ItemPointer iptr)
static void encode_varbyte(uint64 val, unsigned char **ptr)
void * palloc(Size size)
Definition: mcxt.c:949
#define SizeOfGinPostingList(plist)
Definition: ginblock.h:343
int i
#define SHORTALIGN(LEN)
Definition: c.h:681
long val
Definition: informix.c:684
#define offsetof(type, field)
Definition: c.h:655

◆ ginMergeItemPointers()

ItemPointer ginMergeItemPointers ( ItemPointerData a,
uint32  na,
ItemPointerData b,
uint32  nb,
int *  nmerged 
)

Definition at line 380 of file ginpostinglist.c.

References cmp(), ginCompareItemPointers(), and palloc().

Referenced by addItemPointersToLeafTuple(), addItemsToLeaf(), ginRedoRecompress(), and leafRepackItems().

383 {
384  ItemPointerData *dst;
385 
386  dst = (ItemPointer) palloc((na + nb) * sizeof(ItemPointerData));
387 
388  /*
389  * If the argument arrays don't overlap, we can just append them to each
390  * other.
391  */
392  if (na == 0 || nb == 0 || ginCompareItemPointers(&a[na - 1], &b[0]) < 0)
393  {
394  memcpy(dst, a, na * sizeof(ItemPointerData));
395  memcpy(&dst[na], b, nb * sizeof(ItemPointerData));
396  *nmerged = na + nb;
397  }
398  else if (ginCompareItemPointers(&b[nb - 1], &a[0]) < 0)
399  {
400  memcpy(dst, b, nb * sizeof(ItemPointerData));
401  memcpy(&dst[nb], a, na * sizeof(ItemPointerData));
402  *nmerged = na + nb;
403  }
404  else
405  {
406  ItemPointerData *dptr = dst;
407  ItemPointerData *aptr = a;
408  ItemPointerData *bptr = b;
409 
410  while (aptr - a < na && bptr - b < nb)
411  {
412  int cmp = ginCompareItemPointers(aptr, bptr);
413 
414  if (cmp > 0)
415  *dptr++ = *bptr++;
416  else if (cmp == 0)
417  {
418  /* only keep one copy of the identical items */
419  *dptr++ = *bptr++;
420  aptr++;
421  }
422  else
423  *dptr++ = *aptr++;
424  }
425 
426  while (aptr - a < na)
427  *dptr++ = *aptr++;
428 
429  while (bptr - b < nb)
430  *dptr++ = *bptr++;
431 
432  *nmerged = dptr - dst;
433  }
434 
435  return dst;
436 }
ItemPointerData * ItemPointer
Definition: itemptr.h:49
struct ItemPointerData ItemPointerData
static int ginCompareItemPointers(ItemPointer a, ItemPointer b)
Definition: gin_private.h:461
void * palloc(Size size)
Definition: mcxt.c:949
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ ginPostingListDecode()

ItemPointer ginPostingListDecode ( GinPostingList plist,
int *  ndecoded 
)

Definition at line 286 of file ginpostinglist.c.

References ginPostingListDecodeAllSegments(), and SizeOfGinPostingList.

Referenced by addItemsToLeaf(), dataBeginPlaceToPageLeaf(), gin_leafpage_items(), ginCompressPostingList(), ginReadTuple(), ginRedoRecompress(), ginVacuumEntryPage(), ginVacuumPostingTreeLeaf(), leafRepackItems(), and test_itemptr_pair().

287 {
288  return ginPostingListDecodeAllSegments(plist,
289  SizeOfGinPostingList(plist),
290  ndecoded);
291 }
#define SizeOfGinPostingList(plist)
Definition: ginblock.h:343
ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_out)

◆ ginPostingListDecodeAllSegments()

ItemPointer ginPostingListDecodeAllSegments ( GinPostingList segment,
int  len,
int *  ndecoded_out 
)

Definition at line 299 of file ginpostinglist.c.

References Assert, GinPostingList::bytes, decode_varbyte(), GinPostingList::first, ginCompareItemPointers(), GinNextPostingListSegment, ItemPointerGetOffsetNumber, itemptr_to_uint64(), GinPostingList::nbytes, OffsetNumberIsValid, palloc(), repalloc(), uint64_to_itemptr(), and val.

Referenced by GinDataLeafPageGetItems(), ginPostingListDecode(), and ginPostingListDecodeAllSegmentsToTbm().

300 {
301  ItemPointer result;
302  int nallocated;
303  uint64 val;
304  char *endseg = ((char *) segment) + len;
305  int ndecoded;
306  unsigned char *ptr;
307  unsigned char *endptr;
308 
309  /*
310  * Guess an initial size of the array.
311  */
312  nallocated = segment->nbytes * 2 + 1;
313  result = palloc(nallocated * sizeof(ItemPointerData));
314 
315  ndecoded = 0;
316  while ((char *) segment < endseg)
317  {
318  /* enlarge output array if needed */
319  if (ndecoded >= nallocated)
320  {
321  nallocated *= 2;
322  result = repalloc(result, nallocated * sizeof(ItemPointerData));
323  }
324 
325  /* copy the first item */
327  Assert(ndecoded == 0 || ginCompareItemPointers(&segment->first, &result[ndecoded - 1]) > 0);
328  result[ndecoded] = segment->first;
329  ndecoded++;
330 
331  val = itemptr_to_uint64(&segment->first);
332  ptr = segment->bytes;
333  endptr = segment->bytes + segment->nbytes;
334  while (ptr < endptr)
335  {
336  /* enlarge output array if needed */
337  if (ndecoded >= nallocated)
338  {
339  nallocated *= 2;
340  result = repalloc(result, nallocated * sizeof(ItemPointerData));
341  }
342 
343  val += decode_varbyte(&ptr);
344 
345  uint64_to_itemptr(val, &result[ndecoded]);
346  ndecoded++;
347  }
348  segment = GinNextPostingListSegment(segment);
349  }
350 
351  if (ndecoded_out)
352  *ndecoded_out = ndecoded;
353  return result;
354 }
static uint64 decode_varbyte(unsigned char **ptr)
ItemPointerData first
Definition: ginblock.h:338
#define GinNextPostingListSegment(cur)
Definition: ginblock.h:344
static void uint64_to_itemptr(uint64 val, ItemPointer iptr)
unsigned char bytes[FLEXIBLE_ARRAY_MEMBER]
Definition: ginblock.h:340
uint16 nbytes
Definition: ginblock.h:339
#define Assert(condition)
Definition: c.h:732
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:117
static uint64 itemptr_to_uint64(const ItemPointer iptr)
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
static int ginCompareItemPointers(ItemPointer a, ItemPointer b)
Definition: gin_private.h:461
void * palloc(Size size)
Definition: mcxt.c:949
#define OffsetNumberIsValid(offsetNumber)
Definition: off.h:39
long val
Definition: informix.c:684

◆ ginPostingListDecodeAllSegmentsToTbm()

int ginPostingListDecodeAllSegmentsToTbm ( GinPostingList ptr,
int  len,
TIDBitmap tbm 
)

Definition at line 360 of file ginpostinglist.c.

References ginPostingListDecodeAllSegments(), pfree(), and tbm_add_tuples().

Referenced by GinDataLeafPageGetItemsToTbm().

362 {
363  int ndecoded;
364  ItemPointer items;
365 
366  items = ginPostingListDecodeAllSegments(ptr, len, &ndecoded);
367  tbm_add_tuples(tbm, items, ndecoded, false);
368  pfree(items);
369 
370  return ndecoded;
371 }
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
Definition: tidbitmap.c:376
void pfree(void *pointer)
Definition: mcxt.c:1056
ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_out)

◆ itemptr_to_uint64()

static uint64 itemptr_to_uint64 ( const ItemPointer  iptr)
inlinestatic

Definition at line 87 of file ginpostinglist.c.

References Assert, GinItemPointerGetBlockNumber, GinItemPointerGetOffsetNumber, ItemPointerIsValid, MaxHeapTuplesPerPageBits, and val.

Referenced by ginCompressPostingList(), and ginPostingListDecodeAllSegments().

88 {
89  uint64 val;
90 
93 
94  val = GinItemPointerGetBlockNumber(iptr);
96  val |= GinItemPointerGetOffsetNumber(iptr);
97 
98  return val;
99 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:82
#define GinItemPointerGetOffsetNumber(pointer)
Definition: ginblock.h:147
#define MaxHeapTuplesPerPageBits
#define Assert(condition)
Definition: c.h:732
#define GinItemPointerGetBlockNumber(pointer)
Definition: ginblock.h:144
long val
Definition: informix.c:684

◆ uint64_to_itemptr()

static void uint64_to_itemptr ( uint64  val,
ItemPointer  iptr 
)
inlinestatic

Definition at line 102 of file ginpostinglist.c.

References Assert, GinItemPointerSetBlockNumber, GinItemPointerSetOffsetNumber, ItemPointerIsValid, and MaxHeapTuplesPerPageBits.

Referenced by ginPostingListDecodeAllSegments().

103 {
107 
108  Assert(ItemPointerIsValid(iptr));
109 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:82
#define MaxHeapTuplesPerPageBits
#define Assert(condition)
Definition: c.h:732
#define GinItemPointerSetOffsetNumber(pointer, offnum)
Definition: ginblock.h:153
#define GinItemPointerSetBlockNumber(pointer, blkno)
Definition: ginblock.h:150
long val
Definition: informix.c:684