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])
181 attr = &pslot->tts_tupleDescriptor->attrs[
i];
194 for (
int i = 0;
i < numkeys;
i++)
199 if (!pslot->tts_isnull[
i])
204 collations[
i], pslot->tts_values[
i]));
236 int numkeys = mstate->
nkeys;
244 for (
int i = 0;
i < numkeys;
i++)
248 if (tslot->tts_isnull[
i] != pslot->tts_isnull[
i])
255 if (tslot->tts_isnull[
i])
259 attr = &tslot->tts_tupleDescriptor->attrs[
i];
261 attr->attbyval, attr->attlen))
274 econtext->ecxt_innertuple = tslot;
275 econtext->ecxt_outertuple = pslot;
305 int numKeys = mstate->
nkeys;
317 for (
int i = 0;
i < numKeys;
i++)
346 uint64 freed_mem = 0;
348 while (tuple != NULL)
390 memoize_delete_item(mstate->
hashtable, entry);
403 uint64 evictions = mstate->
hashtable->members;
419 mstate->
entry = NULL;
439 bool specialkey_intact =
true;
441 uint64 evictions = 0;
473 entry = memoize_lookup(mstate->
hashtable, NULL);
481 elog(
ERROR,
"could not find memoization table entry");
492 if (
key == specialkey)
493 specialkey_intact =
false;
509 return specialkey_intact;
538 entry = memoize_insert(mstate->
hashtable, NULL, found);
597 if (entry->
status != memoize_SH_IN_USE || entry->
key !=
key)
606 entry = memoize_lookup(mstate->
hashtable, NULL);
676 if (entry->
status != memoize_SH_IN_USE || entry->
key !=
key)
877 elog(
ERROR,
"cache entry already complete");
929 elog(
ERROR,
"unrecognized memoize state: %d",
992 eqfuncoids =
palloc(nkeys *
sizeof(
Oid));
994 for (
i = 0;
i < nkeys;
i++)
996 Oid hashop = node->hashOperators[
i];
1002 elog(
ERROR,
"could not find hash function for hash operator %u",
1032 mstate->
entry = NULL;
1063 #ifdef USE_ASSERT_CHECKING
1074 while ((entry = memoize_iterate(node->
hashtable, &
i)) != NULL)
1079 while (tuple != NULL)
1082 tuple = tuple->
next;
1105 Assert(ParallelWorkerNumber <= node->shared_info->num_workers);
bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
uint32 datum_image_hash(Datum value, bool typByVal, int typLen)
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
elog(ERROR, "%s: %s", p2, msg)
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 ExecQualAndReset(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()
Assert(fmt[strlen(fmt) - 1] !='\n')
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
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)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static uint32 pg_rotate_left32(uint32 word, int n)
static void * list_nth(const List *list, int n)
static uint32 DatumGetUInt32(Datum X)
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)
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]
static MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
static void slot_getallattrs(TupleTableSlot *slot)