Part of the research plan for #4350 (see anchor comment there for the full decomposition).
Folder children are wake-free prefetch candidates: children obtained from plone.folder's _tree (or OFS attribute storage) are ghosts whose _p_oid is readable without activation — collect ghosts, prefetch, then iterate.
Findings (Plone 6.2 coredev scan, 2026-07-06)
| # |
Call site |
Pattern |
| C1 |
plone.folder 5.0.0 ordered.py:93-105 objectValues/objectItems |
LazyMap → _getOb per child on access |
| C2 |
plone.folder default.py:130,136 and partial.py:149 orderObjects |
wakes every child to read the sort key |
| C3 |
OFS/ObjectManager.py:436-449 |
list comprehension, _getOb per child |
C2 is the cleanest bounded win: reordering a large folder by attribute currently loads all children sequentially; a ghost-collection prefetch before the sort batches this into one round-trip on capable storages.
Tasks
Part of the research plan for #4350 (see anchor comment there for the full decomposition).
Folder children are wake-free prefetch candidates: children obtained from
plone.folder's_tree(or OFS attribute storage) are ghosts whose_p_oidis readable without activation — collect ghosts, prefetch, then iterate.Findings (Plone 6.2 coredev scan, 2026-07-06)
plone.folder5.0.0ordered.py:93-105objectValues/objectItemsLazyMap→_getObper child on accessplone.folderdefault.py:130,136andpartial.py:149orderObjectsOFS/ObjectManager.py:436-449_getObper childC2 is the cleanest bounded win: reordering a large folder by attribute currently loads all children sequentially; a ghost-collection prefetch before the sort batches this into one round-trip on capable storages.
Tasks
orderObjects: collect child ghosts from_tree,prefetch(), then sort (uses theplone.basehelper sub-issue).objectValues/objectItems-heavy paths — the full id list is materialized anyway; question is whether an opt-in (prefetch=True) or automatic-with-threshold is appropriate, since not every caller iterates the whole LazyMap.plone.folderchanges are Plone-owned;OFS.ObjectManagerwould need Zope buy-in — likely out of scope for v1.