Author: jukka
Date: Mon Sep 30 16:28:34 2013
New Revision: 1527635
URL: http://svn.apache.org/r1527635
Log:
OAK-1031: SegmentMK: Fewer segment lookups
Move functionality from Template to SegmentNodeState to better leverage the
Record base class
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/PropertyTemplate.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/PropertyTemplate.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/PropertyTemplate.java?rev=1527635&r1=1527634&r2=1527635&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/PropertyTemplate.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/PropertyTemplate.java
Mon Sep 30 16:28:34 2013
@@ -25,21 +25,29 @@ import com.google.common.collect.Compari
class PropertyTemplate implements Comparable<PropertyTemplate> {
+ private final int index;
+
private final String name;
private final Type<?> type;
- PropertyTemplate(String name, Type<?> type) {
+ PropertyTemplate(int index, String name, Type<?> type) {
+ this.index = index;
this.name = checkNotNull(name);
this.type = checkNotNull(type);
}
PropertyTemplate(PropertyState state) {
checkNotNull(state);
+ this.index = 0; // TODO: is this used anywhere
this.name = state.getName();
this.type = state.getType();
}
+ public int getIndex() {
+ return index;
+ }
+
public String getName() {
return name;
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java?rev=1527635&r1=1527634&r2=1527635&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
Mon Sep 30 16:28:34 2013
@@ -316,7 +316,7 @@ public class Segment {
offset += Segment.RECORD_ID_BYTES;
byte type = readByte(offset++);
properties[i] = new PropertyTemplate(
- readString(propertyNameId),
+ i, readString(propertyNameId),
Type.fromTag(Math.abs(type), type < 0));
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java?rev=1527635&r1=1527634&r2=1527635&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
Mon Sep 30 16:28:34 2013
@@ -18,10 +18,14 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayListWithCapacity;
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
import java.util.Collections;
+import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -80,24 +84,85 @@ public class SegmentNodeState extends Re
@Override
public long getPropertyCount() {
- return getTemplate().getPropertyCount();
+ Template template = getTemplate();
+ long count = template.getPropertyTemplates().length;
+ if (template.getPrimaryType() != null) {
+ count++;
+ }
+ if (template.getMixinTypes() != null) {
+ count++;
+ }
+ return count;
}
@Override
public boolean hasProperty(String name) {
checkNotNull(name);
- return getTemplate().hasProperty(name);
+ Template template = getTemplate();
+ if (JCR_PRIMARYTYPE.equals(name)) {
+ return template.getPrimaryType() != null;
+ } else if (JCR_MIXINTYPES.equals(name)) {
+ return template.getMixinTypes() != null;
+ } else {
+ return template.getPropertyTemplate(name) != null;
+ }
}
@Override @CheckForNull
public PropertyState getProperty(String name) {
checkNotNull(name);
- return getTemplate().getProperty(name, getSegment(), getRecordId());
+ Template template = getTemplate();
+ if (JCR_PRIMARYTYPE.equals(name)) {
+ return template.getPrimaryType();
+ } else if (JCR_MIXINTYPES.equals(name)) {
+ return template.getMixinTypes();
+ } else {
+ PropertyTemplate propertyTemplate =
+ template.getPropertyTemplate(name);
+ if (propertyTemplate != null) {
+ Segment segment = getSegment();
+ int ids = 1 + propertyTemplate.getIndex();
+ if (template.getChildName() != Template.ZERO_CHILD_NODES) {
+ ids++;
+ }
+ return new SegmentPropertyState(
+ segment, segment.readRecordId(getOffset(0, ids)),
+ propertyTemplate);
+ } else {
+ return null;
+ }
+ }
}
@Override @Nonnull
public Iterable<PropertyState> getProperties() {
- return getTemplate().getProperties(getSegment(), getRecordId());
+ Template template = getTemplate();
+ PropertyTemplate[] propertyTemplates = template.getPropertyTemplates();
+ List<PropertyState> list =
+ newArrayListWithCapacity(propertyTemplates.length + 2);
+
+ PropertyState primaryType = template.getPrimaryType();
+ if (primaryType != null) {
+ list.add(primaryType);
+ }
+
+ PropertyState mixinTypes = template.getMixinTypes();
+ if (mixinTypes != null) {
+ list.add(mixinTypes);
+ }
+
+ Segment segment = getSegment();
+ int ids = 1;
+ if (template.getChildName() != Template.ZERO_CHILD_NODES) {
+ ids++;
+ }
+ for (int i = 0; i < propertyTemplates.length; i++) {
+ RecordId propertyId = segment.readRecordId(getOffset(0, ids++));
+ list.add(new SegmentPropertyState(
+ segment, propertyId, propertyTemplates[i]));
+ }
+
+ return list;
}
@Override
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java?rev=1527635&r1=1527634&r2=1527635&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
Mon Sep 30 16:28:34 2013
@@ -25,6 +25,8 @@ import static com.google.common.base.Pre
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.emptyMap;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.NAMES;
import static
org.apache.jackrabbit.oak.plugins.segment.MapRecord.BUCKETS_PER_LEVEL;
import static
org.apache.jackrabbit.oak.plugins.segment.Segment.MAX_SEGMENT_SIZE;
@@ -620,17 +622,19 @@ public class SegmentWriter {
int head = 0;
RecordId primaryId = null;
- if (template.hasPrimaryType()) {
+ PropertyState primaryType = template.getPrimaryType();
+ if (primaryType != null) {
head |= 1 << 31;
- primaryId = writeString(template.getPrimaryType());
+ primaryId = writeString(primaryType.getValue(NAME));
ids.add(primaryId);
}
List<RecordId> mixinIds = null;
- if (template.hasMixinTypes()) {
+ PropertyState mixinTypes = template.getMixinTypes();
+ if (mixinTypes != null) {
head |= 1 << 30;
mixinIds = Lists.newArrayList();
- for (String mixin : template.getMixinTypes()) {
+ for (String mixin : mixinTypes.getValue(NAMES)) {
mixinIds.add(writeString(mixin));
}
ids.addAll(mixinIds);
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java?rev=1527635&r1=1527634&r2=1527635&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
Mon Sep 30 16:28:34 2013
@@ -120,32 +120,42 @@ public class Template {
}
}
- public boolean hasPrimaryType() {
- return primaryType != null;
+ PropertyState getPrimaryType() {
+ return primaryType;
}
- public String getPrimaryType() {
- if (primaryType != null) {
- return primaryType.getValue(Type.NAME);
- } else {
- return null;
- }
+ PropertyState getMixinTypes() {
+ return mixinTypes;
}
- public boolean hasMixinTypes() {
- return mixinTypes != null;
+ PropertyTemplate[] getPropertyTemplates() {
+ return properties;
}
- public Iterable<String> getMixinTypes() {
- if (mixinTypes != null) {
- return mixinTypes.getValue(Type.NAMES);
- } else {
- return null;
+ /**
+ * Returns the template of the named property, or {@code null} if no such
+ * property exists. Use the {@link #getPrimaryType()} and
+ * {@link #getMixinTypes()} for accessing the JCR type properties, as
+ * they don't have templates.
+ *
+ * @param name property name
+ * @return property template, or {@code} null if not found
+ */
+ PropertyTemplate getPropertyTemplate(String name) {
+ int hash = name.hashCode();
+ int index = 0;
+ while (index < properties.length
+ && properties[index].getName().hashCode() < hash) {
+ index++;
+ }
+ while (index < properties.length
+ && properties[index].getName().hashCode() == hash) {
+ if (name.equals(properties[index].getName())) {
+ return properties[index];
+ }
+ index++;
}
- }
-
- public PropertyTemplate[] getPropertyTemplates() {
- return properties;
+ return null;
}
public boolean hasNoChildNodes() {
@@ -164,7 +174,7 @@ public class Template {
return childName;
}
- public int getPropertyCount() {
+ int getPropertyCount() {
if (primaryType != null && mixinTypes != null) {
return properties.length + 2;
} else if (primaryType != null || mixinTypes != null) {