78 #define MEMO_CACHE_LOOKUP 1
79 #define MEMO_CACHE_FETCH_NEXT_TUPLE 2
80 #define MEMO_FILLING_CACHE 3
81 #define MEMO_CACHE_BYPASS_MODE 4
83 #define MEMO_END_OF_SCAN 5
87 #define EMPTY_ENTRY_MEMORY_BYTES(e) (sizeof(MemoizeEntry) + \
88 sizeof(MemoizeKey) + \
89 (e)->key->params->t_len);
90 #define CACHE_TUPLE_BYTES(t) (sizeof(MemoizeTuple) + \
126 #define SH_PREFIX memoize
127 #define SH_ELEMENT_TYPE MemoizeEntry
128 #define SH_KEY_TYPE MemoizeKey *
129 #define SH_SCOPE static inline
139 #define SH_PREFIX memoize
140 #define SH_ELEMENT_TYPE MemoizeEntry
141 #define SH_KEY_TYPE MemoizeKey *
143 #define SH_HASH_KEY(tb, key) MemoizeHash_hash(tb, key)
144 #define SH_EQUAL(tb, a, b) MemoizeHash_equal(tb, a, b)
145 #define SH_SCOPE static inline
146 #define SH_STORE_HASH
147 #define SH_GET_HASH(tb, a) a->hash
165 int numkeys = mstate->
nkeys;
171 for (
int i = 0;
i < numkeys;
i++)
176 if (!pslot->tts_isnull[
i])
194 for (
int i = 0;
i < numkeys;
i++)
199 if (!pslot->tts_isnull[
i])
204 collations[
i], pslot->tts_values[
i]));
235 int numkeys = mstate->
nkeys;
243 for (
int i = 0;
i < numkeys;
i++)
247 if (tslot->tts_isnull[
i] != pslot->tts_isnull[
i])
254 if (tslot->tts_isnull[
i])
260 attr->attbyval, attr->attlen))
272 econtext->ecxt_innertuple = tslot;
273 econtext->ecxt_outertuple = pslot;
306 int numKeys = mstate->
nkeys;
318 for (
int i = 0;
i < numKeys;
i++)
349 while (tuple != NULL)
391 memoize_delete_item(mstate->
hashtable, entry);
422 mstate->
entry = NULL;
442 bool specialkey_intact =
true;
476 entry = memoize_lookup(mstate->
hashtable, NULL);
484 elog(
ERROR,
"could not find memoization table entry");
495 if (
key == specialkey)
496 specialkey_intact =
false;
512 return specialkey_intact;
541 entry = memoize_insert(mstate->
hashtable, NULL, found);
600 if (entry->
status != memoize_SH_IN_USE || entry->
key !=
key)
609 entry = memoize_lookup(mstate->
hashtable, NULL);
679 if (entry->
status != memoize_SH_IN_USE || entry->
key !=
key)
893 elog(
ERROR,
"cache entry already complete");
945 elog(
ERROR,
"unrecognized memoize state: %d",
1008 eqfuncoids =
palloc(nkeys *
sizeof(
Oid));
1010 for (
i = 0;
i < nkeys;
i++)
1012 Oid hashop = node->hashOperators[
i];
1018 elog(
ERROR,
"could not find hash function for hash operator %u",
1048 mstate->
entry = NULL;
1082 #ifdef USE_ASSERT_CHECKING
1094 while ((entry = memoize_iterate(node->
hashtable, &
i)) != NULL)
1099 while (tuple != NULL)
1102 tuple = tuple->
next;
1125 Assert(ParallelWorkerNumber <= node->shared_info->num_workers);
bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
#define Assert(condition)
uint32 datum_image_hash(Datum value, bool typByVal, int typLen)
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
void ExecReScan(PlanState *node)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ExprState * ExecBuildParamSetEqual(TupleDesc desc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, const Oid *eqfunctions, const Oid *collations, const List *param_exprs, PlanState *parent)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
const TupleTableSlotOps TTSOpsVirtual
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
TupleDesc ExecTypeFromExprList(List *exprList)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
#define outerPlanState(node)
struct MemoizeInstrumentation MemoizeInstrumentation
#define EXEC_FLAG_BACKWARD
#define ResetExprContext(econtext)
static bool ExecQual(ExprState *state, ExprContext *econtext)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
static TupleTableSlot * ExecProcNode(PlanState *node)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
static uint32 murmurhash32(uint32 data)
static void dlist_init(dlist_head *head)
static void dlist_delete(dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
static void dlist_move_tail(dlist_head *head, dlist_node *node)
#define dlist_container(type, membername, ptr)
#define IsParallelWorker()
RegProcedure get_opcode(Oid opno)
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define CHECK_FOR_INTERRUPTS()
size_t get_hash_memory_limit(void)
#define MEMO_CACHE_LOOKUP
#define MEMO_CACHE_FETCH_NEXT_TUPLE
static bool cache_store_tuple(MemoizeState *mstate, TupleTableSlot *slot)
#define MEMO_CACHE_BYPASS_MODE
static uint32 MemoizeHash_hash(struct memoize_hash *tb, const MemoizeKey *key)
void ExecMemoizeInitializeDSM(MemoizeState *node, ParallelContext *pcxt)
static void cache_purge_all(MemoizeState *mstate)
MemoizeState * ExecInitMemoize(Memoize *node, EState *estate, int eflags)
void ExecReScanMemoize(MemoizeState *node)
double ExecEstimateCacheEntryOverheadBytes(double ntuples)
static bool cache_reduce_memory(MemoizeState *mstate, MemoizeKey *specialkey)
#define MEMO_FILLING_CACHE
static void prepare_probe_slot(MemoizeState *mstate, MemoizeKey *key)
static MemoizeEntry * cache_lookup(MemoizeState *mstate, bool *found)
#define CACHE_TUPLE_BYTES(t)
void ExecMemoizeEstimate(MemoizeState *node, ParallelContext *pcxt)
void ExecMemoizeRetrieveInstrumentation(MemoizeState *node)
struct MemoizeTuple MemoizeTuple
static void entry_purge_tuples(MemoizeState *mstate, MemoizeEntry *entry)
static void remove_cache_entry(MemoizeState *mstate, MemoizeEntry *entry)
void ExecMemoizeInitializeWorker(MemoizeState *node, ParallelWorkerContext *pwcxt)
struct MemoizeEntry MemoizeEntry
static void build_hash_table(MemoizeState *mstate, uint32 size)
static bool MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1, const MemoizeKey *key2)
#define EMPTY_ENTRY_MEMORY_BYTES(e)
void ExecEndMemoize(MemoizeState *node)
static TupleTableSlot * ExecMemoize(PlanState *pstate)
struct MemoizeKey MemoizeKey
#define castNode(_type_, nodeptr)
FormData_pg_attribute * Form_pg_attribute
static uint32 pg_rotate_left32(uint32 word, int n)
static void * list_nth(const List *list, int n)
static uint32 DatumGetUInt32(Datum X)
MemoryContextSwitchTo(old_ctx)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
static pg_noinline void Size size
MemoryContext ecxt_per_tuple_memory
TupleTableSlot * probeslot
SharedMemoizeInfo * shared_info
struct MemoizeEntry * entry
ExprState * cache_eq_expr
MemoizeInstrumentation stats
MemoryContext tableContext
struct memoize_hash * hashtable
TupleTableSlot * tableslot
struct MemoizeTuple * last_tuple
struct MemoizeTuple * next
shm_toc_estimator estimator
Instrumentation * instrument
ExprContext * ps_ExprContext
TupleTableSlot * ps_ResultTupleSlot
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER]
#define TupleDescAttr(tupdesc, i)
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
static void slot_getallattrs(TupleTableSlot *slot)