Part of the research plan for #4350 (see anchor comment there for the full decomposition).
All call sites identified in the sibling sub-issues should go through one shared helper, so semantics, chunking, and cross-DB handling are implemented once. Proposed home: plone.base (it already depends on the relevant stack; five.intid is only needed lazily for relation input).
Sketch
def prefetch(items, context=None) -> int:
"""Batch-hint the storage about soon-needed objects.
Safe no-op without storage support. Returns the number of oids hinted.
"""
Accepted inputs (mixed iterable, dispatched per item):
RelationValue — wake-free oid via intids.refs[to_id].oid; five.intid's KeyReferenceToPersistent stores the oid as a plain attribute (five/intid/keyreference.py:103, five.intid 3.1.0). Fallback for plain zope.keyreference keyrefs: keyref.object._p_oid — also wake-free, since _p_oid access does not activate a ghost.
- persistent objects / ghosts — via
_p_oid
- raw oids (bytes)
- intid tokens (int) — resolved through
intids.refs
Design points to settle
Deliverable: implementation + tests in plone.base, used by the relations and folder sub-issues.
Part of the research plan for #4350 (see anchor comment there for the full decomposition).
All call sites identified in the sibling sub-issues should go through one shared helper, so semantics, chunking, and cross-DB handling are implemented once. Proposed home:
plone.base(it already depends on the relevant stack;five.intidis only needed lazily for relation input).Sketch
Accepted inputs (mixed iterable, dispatched per item):
RelationValue— wake-free oid viaintids.refs[to_id].oid;five.intid'sKeyReferenceToPersistentstores the oid as a plain attribute (five/intid/keyreference.py:103, five.intid 3.1.0). Fallback for plainzope.keyreferencekeyrefs:keyref.object._p_oid— also wake-free, since_p_oidaccess does not activate a ghost._p_oidintids.refsDesign points to settle
context._p_jar, falling back to the site's jar. Document that prefetch is connection-bound (MVCC tid, seeZODB/mvccadapter.py:192).five.intidkeyrefs carrydbname(five/intid/keyreference.py:101-107); skip oids whose dbname differs from the target connection's.jar.prefetchin windows (issue Research: use ZODB Connection.prefetch to batch object loads (relations, contentlisting, catalog results) — eliminate common N+1 patterns #4350's helper uses 500; plone-pgcatalog uses a window of 100 — pick and document a default).plone.api.prefetch? (discoverability vs. keeping plone.api slim)Deliverable: implementation + tests in
plone.base, used by the relations and folder sub-issues.