You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2026/10/14 01:09:51 UTC
(cayenne) 02/02: Do not wrap IDs in a TreeMap when assembling prefetches
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 858fed41e903daf7b293979078d6a41d6c962bf9
Author: Andrus Adamchik <an...@objectstyle.com>
AuthorDate: Tue Oct 13 19:27:08 2026 -0400
Do not wrap IDs in a TreeMap when assembling prefetches
This is an opportunistic performance improvement
---
.../cayenne/access/HierarchicalObjectResolver.java | 2 +-
.../cayenne/access/PrefetchProcessorJointNode.java | 35 ++++++++++++++--------
2 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java b/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
index 20e40ba02..ea5cf38b7 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
@@ -447,7 +447,7 @@ class HierarchicalObjectResolver {
PrefetchProcessorJointNode processorNode = (PrefetchProcessorJointNode) node;
// find existing object, if found skip further processing
- Map<String, Object> id = processorNode.idFromFlatRow(currentFlatRow);
+ Object id = processorNode.idFromFlatRow(currentFlatRow);
Persistent object = processorNode.getResolved(id);
DataRow row = null;
if (object == null) {
diff --git a/cayenne/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java b/cayenne/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java
index e109a2890..e360da4d7 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java
@@ -58,7 +58,7 @@ class PrefetchProcessorJointNode extends PrefetchProcessorNode {
RSColumn[] columns;
int[] idIndices;
- Map<Map, Persistent> resolved;
+ Map<Object, Persistent> resolved;
List<DataRow> resolvedRows;
// the layout of this node's rows, keyed by the columns' result set names
@@ -102,23 +102,32 @@ class PrefetchProcessorJointNode extends PrefetchProcessorNode {
}
/**
- * Returns an ObjectId map from the flat row.
+ * Returns a key of the flat row's object for {@link #getResolved(Object)} and {@link #putResolved(Object,
+ * Persistent)}: the PK value of a single-column PK, or a list of the PK values in the PK column order. The key
+ * is only meaningful within this node, as the column names are not a part of it.
*/
- Map<String, Object> idFromFlatRow(DataRow flatRow) {
+ Object idFromFlatRow(DataRow flatRow) {
// TODO: should we also check for nulls in ID (and skip such rows) - this will
// likely be an indicator of an outer join ... and considering SQLTemplate,
// this is reasonable to expect...
- Map<String, Object> id = new TreeMap<>();
int[] indexes = flatRow.getLayout() != null ? flatIndexes(flatRow) : null;
- for (int idIndex : idIndices) {
- RSColumn column = columns[idIndex];
- Object value = indexes != null ? valueAt(flatRow, indexes[idIndex]) : flatRow.get(column.dataRowName());
- id.put(column.rsName(), value);
+ if (idIndices.length == 1) {
+ return idValue(flatRow, indexes, idIndices[0]);
}
- return id;
+ Object[] id = new Object[idIndices.length];
+ for (int i = 0; i < id.length; i++) {
+ id[i] = idValue(flatRow, indexes, idIndices[i]);
+ }
+
+ // Arrays.asList: a value-based key, unlike List.of it allows nulls, which an outer join produces
+ return Arrays.asList(id);
+ }
+
+ private Object idValue(DataRow flatRow, int[] indexes, int idIndex) {
+ return indexes != null ? valueAt(flatRow, indexes[idIndex]) : flatRow.get(columns[idIndex].dataRowName());
}
/**
@@ -142,10 +151,10 @@ class PrefetchProcessorJointNode extends PrefetchProcessorNode {
}
/**
- * Looks up a previously resolved object using an ObjectId map as a key. Returns null
- * if no matching object exists.
+ * Looks up a previously resolved object by the key returned by {@link #idFromFlatRow(DataRow)}. Returns null if
+ * no matching object exists.
*/
- Persistent getResolved(Map id) {
+ Persistent getResolved(Object id) {
return resolved.get(id);
}
@@ -153,7 +162,7 @@ class PrefetchProcessorJointNode extends PrefetchProcessorNode {
* Registers an object in a map of resolved objects, connects this object to parent if
* parent exists.
*/
- void putResolved(Map id, Persistent object) {
+ void putResolved(Object id, Persistent object) {
resolved.put(id, object);
}