PostgreSQL Source Code  git master
integerset.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef struct IntegerSet IntegerSet
 

Functions

IntegerSetintset_create (void)
 
void intset_add_member (IntegerSet *intset, uint64 x)
 
bool intset_is_member (IntegerSet *intset, uint64 x)
 
uint64 intset_num_entries (IntegerSet *intset)
 
uint64 intset_memory_usage (IntegerSet *intset)
 
void intset_begin_iterate (IntegerSet *intset)
 
bool intset_iterate_next (IntegerSet *intset, uint64 *next)
 

Typedef Documentation

◆ IntegerSet

typedef struct IntegerSet IntegerSet

Definition at line 1 of file integerset.h.

Function Documentation

◆ intset_add_member()

void intset_add_member ( IntegerSet intset,
uint64  x 
)

Definition at line 370 of file integerset.c.

371 {
372  if (intset->iter_active)
373  elog(ERROR, "cannot add new values to integer set while iteration is in progress");
374 
375  if (x <= intset->highest_value && intset->num_entries > 0)
376  elog(ERROR, "cannot add value to integer set out of order");
377 
378  if (intset->num_buffered_values >= MAX_BUFFERED_VALUES)
379  {
380  /* Time to flush our buffer */
382  Assert(intset->num_buffered_values < MAX_BUFFERED_VALUES);
383  }
384 
385  /* Add it to the buffer of newly-added values */
386  intset->buffered_values[intset->num_buffered_values] = x;
387  intset->num_buffered_values++;
388  intset->num_entries++;
389  intset->highest_value = x;
390 }
Datum intset(PG_FUNCTION_ARGS)
Definition: _int_op.c:179
#define Assert(condition)
Definition: c.h:858
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define MAX_BUFFERED_VALUES
Definition: integerset.c:187
static void intset_flush_buffered_values(IntegerSet *intset)
Definition: integerset.c:396
int x
Definition: isn.c:71

References Assert, elog, ERROR, intset(), intset_flush_buffered_values(), MAX_BUFFERED_VALUES, and x.

Referenced by gistvacuumpage(), test_huge_distances(), test_pattern(), test_single_value(), and test_single_value_and_filler().

◆ intset_begin_iterate()

void intset_begin_iterate ( IntegerSet intset)

Definition at line 624 of file integerset.c.

625 {
626  /* Note that we allow an iteration to be abandoned midway */
627  intset->iter_active = true;
628  intset->iter_node = intset->leftmost_leaf;
629  intset->iter_itemno = 0;
630  intset->iter_valueno = 0;
631  intset->iter_num_values = 0;
632  intset->iter_values = intset->iter_values_buf;
633 }

References intset().

Referenced by gistvacuum_delete_empty_pages(), test_empty(), test_huge_distances(), test_pattern(), test_single_value(), and test_single_value_and_filler().

◆ intset_create()

IntegerSet* intset_create ( void  )

Definition at line 284 of file integerset.c.

285 {
287 
288  intset = (IntegerSet *) palloc(sizeof(IntegerSet));
289  intset->context = CurrentMemoryContext;
290  intset->mem_used = GetMemoryChunkSpace(intset);
291 
292  intset->num_entries = 0;
293  intset->highest_value = 0;
294 
295  intset->num_levels = 0;
296  intset->root = NULL;
297  memset(intset->rightmost_nodes, 0, sizeof(intset->rightmost_nodes));
298  intset->leftmost_leaf = NULL;
299 
300  intset->num_buffered_values = 0;
301 
302  intset->iter_active = false;
303  intset->iter_node = NULL;
304  intset->iter_itemno = 0;
305  intset->iter_valueno = 0;
306  intset->iter_num_values = 0;
307  intset->iter_values = NULL;
308 
309  return intset;
310 }
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
void * palloc(Size size)
Definition: mcxt.c:1316

References CurrentMemoryContext, GetMemoryChunkSpace(), intset(), and palloc().

Referenced by gistvacuumscan(), test_empty(), test_huge_distances(), test_pattern(), test_single_value(), and test_single_value_and_filler().

◆ intset_is_member()

bool intset_is_member ( IntegerSet intset,
uint64  x 
)

Definition at line 554 of file integerset.c.

555 {
556  intset_node *node;
557  intset_leaf_node *leaf;
558  int level;
559  int itemno;
560  leaf_item *item;
561 
562  /*
563  * The value might be in the buffer of newly-added values.
564  */
565  if (intset->num_buffered_values > 0 && x >= intset->buffered_values[0])
566  {
567  itemno = intset_binsrch_uint64(x,
568  intset->buffered_values,
569  intset->num_buffered_values,
570  false);
571  if (itemno >= intset->num_buffered_values)
572  return false;
573  else
574  return (intset->buffered_values[itemno] == x);
575  }
576 
577  /*
578  * Start from the root, and walk down the B-tree to find the right leaf
579  * node.
580  */
581  if (!intset->root)
582  return false;
583  node = intset->root;
584  for (level = intset->num_levels - 1; level > 0; level--)
585  {
587 
588  Assert(node->level == level);
589 
590  itemno = intset_binsrch_uint64(x, n->values, n->num_items, true);
591  if (itemno == 0)
592  return false;
593  node = n->downlinks[itemno - 1];
594  }
595  Assert(node->level == 0);
596  leaf = (intset_leaf_node *) node;
597 
598  /*
599  * Binary search to find the right item on the leaf page
600  */
601  itemno = intset_binsrch_leaf(x, leaf->items, leaf->num_items, true);
602  if (itemno == 0)
603  return false;
604  item = &leaf->items[itemno - 1];
605 
606  /* Is this a match to the first value on the item? */
607  if (item->first == x)
608  return true;
609  Assert(x > item->first);
610 
611  /* Is it in the packed codeword? */
612  if (simple8b_contains(item->codeword, x, item->first))
613  return true;
614 
615  return false;
616 }
static int intset_binsrch_uint64(uint64 item, uint64 *arr, int arr_elems, bool nextkey)
Definition: integerset.c:714
static int intset_binsrch_leaf(uint64 item, leaf_item *arr, int arr_elems, bool nextkey)
Definition: integerset.c:747
static bool simple8b_contains(uint64 codeword, uint64 key, uint64 base)
Definition: integerset.c:1004
intset_node * downlinks[MAX_INTERNAL_ITEMS]
Definition: integerset.c:157
uint64 values[MAX_INTERNAL_ITEMS]
Definition: integerset.c:156
leaf_item items[MAX_LEAF_ITEMS]
Definition: integerset.c:177
uint16 level
Definition: integerset.c:141
uint64 codeword
Definition: integerset.c:164
uint64 first
Definition: integerset.c:163

References Assert, leaf_item::codeword, intset_internal_node::downlinks, leaf_item::first, intset(), intset_binsrch_leaf(), intset_binsrch_uint64(), intset_leaf_node::items, intset_node::level, intset_internal_node::num_items, intset_leaf_node::num_items, simple8b_contains(), intset_internal_node::values, and x.

Referenced by check_with_filler(), gistvacuum_delete_empty_pages(), test_empty(), test_huge_distances(), test_pattern(), and test_single_value().

◆ intset_iterate_next()

bool intset_iterate_next ( IntegerSet intset,
uint64 *  next 
)

Definition at line 643 of file integerset.c.

644 {
645  Assert(intset->iter_active);
646  for (;;)
647  {
648  /* Return next iter_values[] entry if any */
649  if (intset->iter_valueno < intset->iter_num_values)
650  {
651  *next = intset->iter_values[intset->iter_valueno++];
652  return true;
653  }
654 
655  /* Decode next item in current leaf node, if any */
656  if (intset->iter_node &&
657  intset->iter_itemno < intset->iter_node->num_items)
658  {
659  leaf_item *item;
660  int num_decoded;
661 
662  item = &intset->iter_node->items[intset->iter_itemno++];
663 
664  intset->iter_values_buf[0] = item->first;
665  num_decoded = simple8b_decode(item->codeword,
666  &intset->iter_values_buf[1],
667  item->first);
668  intset->iter_num_values = num_decoded + 1;
669  intset->iter_valueno = 0;
670  continue;
671  }
672 
673  /* No more items on this leaf, step to next node */
674  if (intset->iter_node)
675  {
676  intset->iter_node = intset->iter_node->next;
677  intset->iter_itemno = 0;
678  continue;
679  }
680 
681  /*
682  * We have reached the end of the B-tree. But we might still have
683  * some integers in the buffer of newly-added values.
684  */
685  if (intset->iter_values == (const uint64 *) intset->iter_values_buf)
686  {
687  intset->iter_values = intset->buffered_values;
688  intset->iter_num_values = intset->num_buffered_values;
689  intset->iter_valueno = 0;
690  continue;
691  }
692 
693  break;
694  }
695 
696  /* No more results. */
697  intset->iter_active = false;
698  *next = 0; /* prevent uninitialized-variable warnings */
699  return false;
700 }
static int32 next
Definition: blutils.c:221
static int simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base)
Definition: integerset.c:975

References Assert, leaf_item::codeword, leaf_item::first, intset(), next, and simple8b_decode().

Referenced by gistvacuum_delete_empty_pages(), test_empty(), test_huge_distances(), test_pattern(), test_single_value(), and test_single_value_and_filler().

◆ intset_memory_usage()

uint64 intset_memory_usage ( IntegerSet intset)

Definition at line 359 of file integerset.c.

360 {
361  return intset->mem_used;
362 }

References intset().

Referenced by test_pattern(), and test_single_value_and_filler().

◆ intset_num_entries()

uint64 intset_num_entries ( IntegerSet intset)

Definition at line 350 of file integerset.c.

351 {
352  return intset->num_entries;
353 }

References intset().

Referenced by gistvacuum_delete_empty_pages(), test_pattern(), test_single_value(), and test_single_value_and_filler().