You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2011/12/27 12:57:38 UTC
svn commit: r1224899 - in
/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk: ./
model/ store/ store/util/
Author: stefan
Date: Tue Dec 27 11:57:38 2011
New Revision: 1224899
URL: http://svn.apache.org/viewvc?rev=1224899&view=rev
Log:
flat hierarchy support (WIP)
Added:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNode.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntry.java
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/MutableNode.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeUtils.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/StoredNode.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/util/Serializer.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java Tue Dec 27 11:57:38 2011
@@ -20,6 +20,7 @@ import org.apache.jackrabbit.mk.api.Micr
import org.apache.jackrabbit.mk.api.MicroKernelException;
import org.apache.jackrabbit.mk.json.JsopBuilder;
import org.apache.jackrabbit.mk.json.JsopTokenizer;
+import org.apache.jackrabbit.mk.model.ChildNodeEntry;
import org.apache.jackrabbit.mk.model.Commit;
import org.apache.jackrabbit.mk.model.CommitBuilder;
import org.apache.jackrabbit.mk.model.Node;
@@ -36,6 +37,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -370,7 +372,7 @@ public class MicroKernelImpl implements
public String getNodes(String path, String revisionId, int depth, long offset, int count) throws MicroKernelException {
try {
JsopBuilder buf = new JsopBuilder().object();
- toJson(buf, rep.getNode(revisionId, path), depth, offset, count, true);
+ toJson(buf, rep.getNode(revisionId, path), depth, (int) offset, count, true);
return buf.endObject().toString();
} catch (Exception e) {
throw new MicroKernelException(e);
@@ -533,7 +535,7 @@ public class MicroKernelImpl implements
//-------------------------------------------------------< implementation >
- void toJson(JsopBuilder builder, Node node, int depth, long offset, int count, boolean inclVirtualProps) throws Exception {
+ void toJson(JsopBuilder builder, Node node, int depth, int offset, int count, boolean inclVirtualProps) throws Exception {
for (Map.Entry<String, String> prop : node.getProperties().entrySet()) {
builder.key(prop.getKey()).encodedValue(prop.getValue());
}
@@ -542,20 +544,13 @@ public class MicroKernelImpl implements
builder.key(":childNodeCount").value(childCount);
}
if (childCount > 0 && depth >= 0) {
- for (Map.Entry<String, String> child : node.getChildNodeEntries().entrySet()) {
- if (offset-- > 0) {
- continue;
- }
- if (count < 0 || count > 0) {
- count--;
- String childName = child.getKey();
- builder.key(childName).object();
- if (depth > 0) {
- String childId = child.getValue();
- toJson(builder, rep.getRevisionStore().getNode(childId), depth - 1, 0, -1, inclVirtualProps);
- }
- builder.endObject();
+ for (Iterator<ChildNodeEntry> it = node.getChildNodeEntries(offset, count); it.hasNext(); ) {
+ ChildNodeEntry cne = it.next();
+ builder.key(cne.getName()).object();
+ if (depth > 0) {
+ toJson(builder, rep.getRevisionStore().getNode(cne.getId()), depth - 1, 0, -1, inclVirtualProps);
}
+ builder.endObject();
}
}
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java Tue Dec 27 11:57:38 2011
@@ -17,6 +17,8 @@
package org.apache.jackrabbit.mk;
import java.io.File;
+
+import org.apache.jackrabbit.mk.model.ChildNodeEntry;
import org.apache.jackrabbit.mk.model.Commit;
import org.apache.jackrabbit.mk.model.CommitBuilder;
import org.apache.jackrabbit.mk.model.Node;
@@ -144,11 +146,11 @@ public class Repository {
String[] names = PathUtils.split(path);
Node parent = pm.getRootNode(revId);
for (int i = 0; i < names.length; i++) {
- String id = parent.getChildNodeEntries().get(names[i]);
- if (id == null) {
+ ChildNodeEntry cne = parent.getChildNodeEntry(names[i]);
+ if (cne == null) {
return false;
}
- parent = pm.getNode(id);
+ parent = pm.getNode(cne.getId());
}
return true;
} catch (Exception e) {
@@ -188,12 +190,12 @@ public class Repository {
Node parent = pm.getNode(ids[0]);
// traverse path and remember id of each element
for (int i = 0; i < names.length; i++) {
- String id = parent.getChildNodeEntries().get(names[i]);
- if (id == null) {
+ ChildNodeEntry cne = parent.getChildNodeEntry(names[i]);
+ if (cne == null) {
throw new NotFoundException(nodePath);
}
- ids[i + 1] = id;
- parent = pm.getNode(id);
+ ids[i + 1] = cne.getId();
+ parent = pm.getNode(cne.getId());
}
return ids;
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java Tue Dec 27 11:57:38 2011
@@ -20,58 +20,65 @@ import org.apache.jackrabbit.mk.store.Re
import org.apache.jackrabbit.mk.store.NotFoundException;
import org.apache.jackrabbit.mk.util.PathUtils;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
+import java.util.NoSuchElementException;
/**
*
*/
public abstract class AbstractNode implements Node {
- final protected Map<String, String> properties;
+ protected HashMap<String, String> properties;
// map keeping insertion order
- //final protected LinkedHashMap<String, Node> children;
- final protected LinkedHashMap<String, String> childEntries;
+ protected LinkedHashMap<String, ChildNodeEntry> childEntries;
protected AbstractNode() {
this.properties = new HashMap<String, String>();
- //this.children = new LinkedHashMap<String, Node>();
- this.childEntries = new LinkedHashMap<String, String>();
+ this.childEntries = new LinkedHashMap<String, ChildNodeEntry>();
}
protected AbstractNode(Node other) {
- this.properties = new HashMap<String, String>(other.getProperties());
- //this.children = new LinkedHashMap<String, Node>(other.getChildNodes(0, -1));
- this.childEntries = new LinkedHashMap<String, String>(other.getChildNodeEntries());
+ if (other instanceof AbstractNode) {
+ AbstractNode srcNode = (AbstractNode) other;
+ this.properties = (HashMap<String, String>) srcNode.properties.clone();
+ this.childEntries = (LinkedHashMap<String, ChildNodeEntry>) srcNode.childEntries.clone();
+ } else {
+ this.properties = new HashMap<String, String>(other.getProperties());
+ this.childEntries = new LinkedHashMap<String, ChildNodeEntry>(other.getChildNodeCount());
+ for (Iterator<ChildNodeEntry> it = other.getChildNodeEntries(); it.hasNext(); ) {
+ ChildNodeEntry cne = it.next();
+ this.childEntries.put(cne.getName(), cne);
+ }
+ }
}
public Map<String, String> getProperties() {
return properties;
}
- public List<String> getChildNodeNames(int offset, int count) {
- Set<String> keys = childEntries.keySet();
- List<String> names = new ArrayList(keys);
+ public ChildNodeEntry getChildNodeEntry(String name) {
+ return childEntries.get(name);
+ }
+
+ public Iterator<String> getChildNodeNames(int offset, int count) {
if (offset < 0 || count < -1) {
throw new IllegalArgumentException();
}
+
if (offset == 0 && count == -1) {
- return names;
+ return childEntries.keySet().iterator();
} else {
- if (offset >= names.size()) {
- return Collections.emptyList();
+ if (offset >= childEntries.size()) {
+ return new EmptyIterator<String>();
}
- int to = offset + count;
- if (to > names.size()) {
- to = names.size();
+ if (count == -1 || (offset + count) > childEntries.size()) {
+ count = childEntries.size() - offset;
}
- return names.subList(offset, to);
+ return new RangeIterator<String>(childEntries.keySet().iterator(), offset, count);
}
}
@@ -79,67 +86,54 @@ public abstract class AbstractNode imple
return childEntries.size();
}
- public Map<String, String> getChildNodeEntries() {
- return childEntries;
+ public Iterator<ChildNodeEntry> getChildNodeEntries() {
+ return getChildNodeEntries(0, -1);
}
- public Map<String, String> getChildNodeEntries(int offset, int count) {
+ public Iterator<ChildNodeEntry> getChildNodeEntries(int offset, int count) {
if (offset < 0 || count < -1) {
throw new IllegalArgumentException();
}
if (offset == 0 && count == -1) {
- return childEntries;
+ return childEntries.values().iterator();
} else {
if (offset >= childEntries.size()) {
- return Collections.emptyMap();
+ return new EmptyIterator<ChildNodeEntry>();
}
- int to = offset + count;
- if (to > childEntries.size()) {
- to = childEntries.size();
- count = to - offset;
- }
- Map<String, String> result = new LinkedHashMap<String, String>(count);
- for (Map.Entry<String, String> entry : childEntries.entrySet()) {
- if (offset-- > 0) {
- continue;
- }
- result.put(entry.getKey(), entry.getValue());
- if (--count <= 0) {
- break;
- }
+ if (count == -1 || (offset + count) > childEntries.size()) {
+ count = childEntries.size() - offset;
}
- return result;
+ return new RangeIterator<ChildNodeEntry>(childEntries.values().iterator(), offset, count);
}
}
- public Map<String, Node> getChildNodes(int offset, int count, RevisionProvider provider)
+ public Iterator<ChildNode> getChildNodes(int offset, int count, final RevisionProvider provider)
throws Exception {
if (offset < 0 || count < -1) {
throw new IllegalArgumentException();
}
if (offset >= childEntries.size()) {
- return Collections.emptyMap();
+ return new EmptyIterator<ChildNode>();
}
// todo support embedded/in-lined sub-trees
- int to = offset + count;
- if (to > childEntries.size()) {
- to = childEntries.size();
- count = to - offset;
- }
- Map<String, Node> result = new LinkedHashMap<String, Node>(count);
- for (Map.Entry<String, String> entry : childEntries.entrySet()) {
- if (offset-- > 0) {
- continue;
- }
- result.put(entry.getKey(), provider.getNode(entry.getValue()));
- if (--count <= 0) {
- break;
- }
+ if (count == -1 || (offset + count) > childEntries.size()) {
+ count = childEntries.size() - offset;
}
- return result;
+
+ return new AbstractRangeIterator<ChildNode>(childEntries.values().iterator(), offset, count) {
+ @Override
+ protected ChildNode doNext() {
+ ChildNodeEntry cne = (ChildNodeEntry) it.next();
+ try {
+ return new ChildNode(cne.getName(), provider.getNode(cne.getId()));
+ } catch (Exception e) {
+ throw new NoSuchElementException();
+ }
+ }
+ };
}
public Node getNode(String relPath, RevisionProvider provider)
@@ -148,11 +142,72 @@ public abstract class AbstractNode imple
Node node = this;
for (String name : names) {
- node = node.getChildNodes(0, -1, provider).get(name);
- if (node == null) {
+ ChildNodeEntry cne = node.getChildNodeEntry(name);
+ if (cne == null) {
throw new NotFoundException();
}
+ node = provider.getNode(cne.getId());
}
return node;
}
+
+ //--------------------------------------------------------< inner classes >
+
+ static class EmptyIterator<T> implements Iterator<T> {
+
+ public boolean hasNext() {
+ return false;
+ }
+
+ public T next() {
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static abstract class AbstractRangeIterator<T> implements Iterator<T> {
+
+ final Iterator<?> it;
+ int count;
+
+ public AbstractRangeIterator(Iterator<?> it, int offset, int count) {
+ while (offset-- > 0 && it.hasNext()) {
+ it.next();
+ }
+ this.count = count;
+ this.it = it;
+ }
+
+ public boolean hasNext() {
+ return (count > 0 && it.hasNext());
+ }
+
+ public T next() {
+ if (count-- > 0) {
+ return doNext();
+ }
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ protected abstract T doNext();
+ }
+
+ static class RangeIterator<T> extends AbstractRangeIterator<T> {
+
+ public RangeIterator(Iterator<T> it, int offset, int count) {
+ super(it, offset, count);
+ }
+
+ @Override
+ protected T doNext() {
+ return (T) it.next();
+ }
+ }
}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNode.java?rev=1224899&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNode.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNode.java Tue Dec 27 11:57:38 2011
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.mk.model;
+
+/**
+ *
+ */
+public class ChildNode {
+
+ private final String name;
+ private final Node node;
+
+ public ChildNode(String name, Node node) {
+ this.name = name;
+ this.node = node;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Node getNode() {
+ return node;
+ }
+}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntry.java?rev=1224899&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntry.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntry.java Tue Dec 27 11:57:38 2011
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.mk.model;
+
+/**
+ *
+ */
+public class ChildNodeEntry {
+
+ private final String name;
+ private final String id;
+
+ public ChildNodeEntry(String name, String id) {
+ this.name = name;
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getId() {
+ return id;
+ }
+}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java Tue Dec 27 11:57:38 2011
@@ -24,8 +24,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
/**
*
@@ -56,14 +58,14 @@ public class CommitBuilder {
public void addNode(String parentNodePath, String nodeName, Map<String, String> properties) throws Exception {
MutableNode modParent = getOrCreateStagedNode(parentNodePath);
- if (modParent.getChildNodeEntries().containsKey(nodeName)) {
+ if (modParent.getChildNodeEntry(nodeName) != null) {
throw new Exception("there's already a child node with name '" + nodeName + "'");
}
MutableNode newChild = new MutableNode();
newChild.getProperties().putAll(properties);
- // value will be computed on commit
- modParent.getChildNodeEntries().put(nodeName, "");
+ // id will be computed on commit
+ modParent.put(new ChildNodeEntry(nodeName, ""));
String newPath = PathUtils.concat(parentNodePath, nodeName);
staged.put(newPath, newChild);
// update change log
@@ -75,12 +77,10 @@ public class CommitBuilder {
String nodeName = PathUtils.getName(nodePath);
MutableNode parent = getOrCreateStagedNode(parentPath);
- if (!parent.getChildNodeEntries().containsKey(nodeName)) {
+ if (parent.remove(nodeName) == null) {
throw new NotFoundException(nodePath);
}
- parent.getChildNodeEntries().remove(nodeName);
-
// update staging area
removeStagedNodes(nodePath);
@@ -96,17 +96,16 @@ public class CommitBuilder {
String destNodeName = PathUtils.getName(destPath);
MutableNode srcParent = getOrCreateStagedNode(srcParentPath);
- String targetId = srcParent.getChildNodeEntries().get(srcNodeName);
- if (targetId == null) {
+ ChildNodeEntry srcCNE = srcParent.remove(srcNodeName);
+ if (srcCNE == null) {
throw new NotFoundException(srcPath);
}
- srcParent.getChildNodeEntries().remove(srcNodeName);
MutableNode destParent = getOrCreateStagedNode(destParentPath);
- if (destParent.getChildNodeEntries().containsKey(destNodeName)) {
+ if (destParent.getChildNodeEntry(destNodeName) != null) {
throw new Exception("node already exists at move destination path: " + destPath);
}
- destParent.getChildNodeEntries().put(destNodeName, targetId);
+ destParent.put(new ChildNodeEntry(destNodeName, srcCNE.getId()));
// update staging area
moveStagedNodes(srcPath, destPath);
@@ -123,13 +122,13 @@ public class CommitBuilder {
String destNodeName = PathUtils.getName(destPath);
MutableNode srcParent = getOrCreateStagedNode(srcParentPath);
- String targetId = srcParent.getChildNodeEntries().get(srcNodeName);
- if (targetId == null) {
+ ChildNodeEntry srcCNE = srcParent.getChildNodeEntry(srcNodeName);
+ if (srcCNE == null) {
throw new NotFoundException(srcPath);
}
MutableNode destParent = getOrCreateStagedNode(destParentPath);
- destParent.getChildNodeEntries().put(destNodeName, targetId);
+ destParent.put(new ChildNodeEntry(destNodeName, srcCNE.getId()));
// update change log
changeLog.add(new CopyNode(srcPath, destPath));
@@ -149,12 +148,7 @@ public class CommitBuilder {
changeLog.add(new SetProperty(nodePath, propName, propValue));
}
- public void setProperty(String nodePath, String propName, String[] propValues) throws Exception {
- // todo support MVPs
- }
-
public void setProperties(String nodePath, Map<String, String> properties) throws Exception {
- // todo support MVPs
MutableNode node = getOrCreateStagedNode(nodePath);
node.getProperties().clear();
@@ -164,6 +158,9 @@ public class CommitBuilder {
changeLog.add(new SetProperties(nodePath, properties));
}
+ //final static AtomicLong commitCount = new AtomicLong();
+ //final static AtomicLong mergeCount = new AtomicLong();
+
public String /* new revId */ doCommit() throws Exception {
if (staged.isEmpty()) {
// nothing to commit
@@ -197,6 +194,8 @@ public class CommitBuilder {
rootNodeId = mergeTree(baseRoot, ourRoot, theirRoot);
+ //mergeCount.getAndIncrement();
+
baseRevId = currentHead;
}
@@ -213,6 +212,13 @@ public class CommitBuilder {
newRevId = store.putCommit(newCommit);
store.setHeadCommitId(newRevId);
+/*
+ long commits = commitCount.incrementAndGet();
+ if (commits % 100 == 0) {
+ long merges = mergeCount.get();
+ System.out.println("#commits: " + commits + ", #merges: " + merges + " (" + ((int)(100*(1.0*merges/commits))) + "%)");
+ }
+*/
} finally {
store.unlockHead();
}
@@ -240,11 +246,11 @@ public class CommitBuilder {
if (node == null) {
// not yet staged, resolve id using staged parent
// to allow for staged move operations
- String id = parent.getChildNodeEntries().get(names[names.length - i - 1]);
- if (id == null) {
+ ChildNodeEntry cne = parent.getChildNodeEntry(names[names.length - i - 1]);
+ if (cne == null) {
throw new NotFoundException(nodePath);
}
- node = new MutableNode(store.getNode(id));
+ node = new MutableNode(store.getNode(cne.getId()));
staged.put(path, node);
}
parent = node;
@@ -258,7 +264,8 @@ public class CommitBuilder {
if (node != null) {
staged.remove(srcPath);
staged.put(destPath, node);
- for (String childName : node.getChildNodeEntries().keySet()) {
+ for (Iterator<String> it = node.getChildNodeNames(0, -1); it.hasNext(); ) {
+ String childName = it.next();
moveStagedNodes(PathUtils.concat(srcPath, childName), PathUtils.concat(destPath, childName));
}
}
@@ -268,7 +275,8 @@ public class CommitBuilder {
MutableNode node = staged.get(nodePath);
if (node != null) {
staged.remove(nodePath);
- for (String childName : node.getChildNodeEntries().keySet()) {
+ for (Iterator<String> it = node.getChildNodeNames(0, -1); it.hasNext(); ) {
+ String childName = it.next();
removeStagedNodes(PathUtils.concat(nodePath, childName));
}
}
@@ -296,7 +304,7 @@ public class CommitBuilder {
if (PathUtils.denotesRoot(path)) {
rootNodeId = id;
} else {
- staged.get(PathUtils.getParentPath(path)).getChildNodeEntries().put(PathUtils.getName(path), id);
+ staged.get(PathUtils.getParentPath(path)).put(new ChildNodeEntry(PathUtils.getName(path), id));
}
}
if (rootNodeId == null) {
@@ -327,7 +335,6 @@ public class CommitBuilder {
}
void mergeNode(StoredNode baseNode, StoredNode ourNode, StoredNode theirNode, String path) throws Exception {
- // todo review/verify correctness of merge algorithm
NodeDelta theirChanges = new NodeDelta(baseNode, theirNode);
NodeDelta ourChanges = new NodeDelta(baseNode, ourNode);
@@ -341,10 +348,15 @@ public class CommitBuilder {
mergedNode.getProperties().remove(name);
}
- mergedNode.getChildNodeEntries().putAll(ourChanges.getAddedChildNodes());
- mergedNode.getChildNodeEntries().putAll(ourChanges.getChangedChildNodes());
+ // todo fixme
+ for (Map.Entry<String, String> entry : ourChanges.getAddedChildNodes ().entrySet()) {
+ mergedNode.put(new ChildNodeEntry(entry.getKey(), entry.getValue()));
+ }
+ for (Map.Entry<String, String> entry : ourChanges.getChangedChildNodes ().entrySet()) {
+ mergedNode.put(new ChildNodeEntry(entry.getKey(), entry.getValue()));
+ }
for (String name : ourChanges.getRemovedChildNodes().keySet()) {
- mergedNode.getChildNodeEntries().remove(name);
+ mergedNode.remove(name);
}
List<NodeDelta.Conflict> conflicts = theirChanges.listConflicts(ourChanges);
@@ -364,9 +376,9 @@ public class CommitBuilder {
case NODE_CONTENT_CONFLICT: {
if (ourChanges.getChangedChildNodes().containsKey(conflictName)) {
// modified subtrees
- StoredNode baseChild = store.getNode(baseNode.getChildNodeEntries().get(conflictName));
- StoredNode ourChild = store.getNode(ourNode.getChildNodeEntries().get(conflictName));
- StoredNode theirChild = store.getNode(theirNode.getChildNodeEntries().get(conflictName));
+ StoredNode baseChild = store.getNode(baseNode.getChildNodeEntry(conflictName).getId());
+ StoredNode ourChild = store.getNode(ourNode.getChildNodeEntry(conflictName).getId());
+ StoredNode theirChild = store.getNode(theirNode.getChildNodeEntry(conflictName).getId());
// merge the dirty subtrees recursively
mergeNode(baseChild, ourChild, theirChild, PathUtils.concat(path, conflictName));
} else {
@@ -381,7 +393,7 @@ public class CommitBuilder {
break;
case REMOVED_DIRTY_PROPERTY_CONFLICT:
- mergedNode.getChildNodeEntries().remove(conflictName);
+ mergedNode.remove(conflictName);
break;
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/MutableNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/MutableNode.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/MutableNode.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/MutableNode.java Tue Dec 27 11:57:38 2011
@@ -27,4 +27,12 @@ public class MutableNode extends Abstrac
public MutableNode(Node other) {
super(other);
}
+
+ public ChildNodeEntry put(ChildNodeEntry newEntry) {
+ return childEntries.put(newEntry.getName(), newEntry);
+ }
+
+ public ChildNodeEntry remove(String name) {
+ return childEntries.remove(name);
+ }
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/Node.java Tue Dec 27 11:57:38 2011
@@ -19,7 +19,7 @@ package org.apache.jackrabbit.mk.model;
import org.apache.jackrabbit.mk.store.RevisionProvider;
import org.apache.jackrabbit.mk.store.NotFoundException;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
/**
@@ -28,17 +28,21 @@ import java.util.Map;
public interface Node {
Map<String, String> getProperties();
- List<String> getChildNodeNames(int offset, int count);
+
+ ChildNodeEntry getChildNodeEntry(String name);
+
+ Iterator<String> getChildNodeNames(int offset, int count);
int getChildNodeCount();
+
/**
* @deprecated use getChildNodes(int, int, RevisionProvider) instead
*/
- Map<String, String> getChildNodeEntries();
+ Iterator<ChildNodeEntry> getChildNodeEntries();
/**
* @deprecated use getChildNodes(int, int, RevisionProvider) instead
*/
- Map<String, String> getChildNodeEntries(int offset, int count);
+ Iterator<ChildNodeEntry> getChildNodeEntries(int offset, int count);
- Map<String, Node> getChildNodes(int offset, int count, RevisionProvider provider) throws Exception;
+ Iterator<ChildNode> getChildNodes(int offset, int count, RevisionProvider provider) throws Exception;
Node getNode(String relPath, RevisionProvider provider) throws NotFoundException, Exception;
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeUtils.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeUtils.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/NodeUtils.java Tue Dec 27 11:57:38 2011
@@ -20,6 +20,8 @@ import org.apache.jackrabbit.mk.store.Re
import org.apache.jackrabbit.mk.util.PathUtils;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
@@ -77,8 +79,18 @@ public class NodeUtils {
// todo determine copy/move and child-node reorder operations
// compare child node entries
- Map<String, String> oldEntries = node1.getChildNodeEntries(0, -1);
- Map<String, String> newEntries = node2.getChildNodeEntries(0, -1);
+
+ // todo delegate comparing child node entries to (Abstract)Node
+ Map<String, String> oldEntries = new LinkedHashMap<String, String>(node1.getChildNodeCount());
+ for (Iterator<ChildNodeEntry> it = node1.getChildNodeEntries(0, -1); it.hasNext(); ) {
+ ChildNodeEntry cne = it.next();
+ oldEntries.put(cne.getName(), cne.getId());
+ }
+ Map<String, String> newEntries = new LinkedHashMap<String, String>(node2.getChildNodeCount());
+ for (Iterator<ChildNodeEntry> it = node2.getChildNodeEntries(0, -1); it.hasNext(); ) {
+ ChildNodeEntry cne = it.next();
+ newEntries.put(cne.getName(), cne.getId());
+ }
if (!oldEntries.equals(newEntries)) {
Set<String> set = new HashSet<String>();
set.addAll(oldEntries.keySet());
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/StoredNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/StoredNode.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/StoredNode.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/StoredNode.java Tue Dec 27 11:57:38 2011
@@ -20,10 +20,9 @@ import org.apache.jackrabbit.mk.store.Re
import org.apache.jackrabbit.mk.store.NotFoundException;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
+import java.util.NoSuchElementException;
/**
*
@@ -32,9 +31,13 @@ public class StoredNode extends Abstract
private final String id;
- public StoredNode(String id, Map<String, String> properties, Map<String, String> childEntries) {
+ public StoredNode(String id, Map<String, String> properties, Iterator<ChildNodeEntry> cneIt) {
this.id = id;
this.properties.putAll(properties);
+ while (cneIt.hasNext()) {
+ ChildNodeEntry cne = cneIt.next();
+ childEntries.put(cne.getName(), cne);
+ }
this.childEntries.putAll(childEntries);
}
@@ -51,26 +54,21 @@ public class StoredNode extends Abstract
return Collections.unmodifiableMap(properties);
}
- public Map<String, String> getChildNodeEntries() {
- return Collections.unmodifiableMap(super.getChildNodeEntries());
- }
-
- public Map<String, String> getChildNodeEntries(int offset, int count) {
- return Collections.unmodifiableMap(super.getChildNodeEntries(offset, count));
+ public Iterator<ChildNodeEntry> getChildNodeEntries() {
+ return getChildNodeEntries(0, -1);
}
- public List<String> getChildNodeNames(int offset, int count) {
- return Collections.unmodifiableList(super.getChildNodeNames(offset, count));
+ public Iterator<ChildNodeEntry> getChildNodeEntries(int offset, int count) {
+ return new UnmodifiableIterator<ChildNodeEntry>(super.getChildNodeEntries(offset, count));
}
- public int getChildNodeCount() {
- return childEntries.size();
+ public Iterator<String> getChildNodeNames(int offset, int count) {
+ return new UnmodifiableIterator<String>(super.getChildNodeNames(offset, count));
}
- public Map<String, Node> getChildNodes(int offset, int count, RevisionProvider provider)
+ public Iterator<ChildNode> getChildNodes(int offset, int count, RevisionProvider provider)
throws Exception {
- // todo return StoredNode instances instead?
- return Collections.unmodifiableMap(super.getChildNodes(offset, count, provider));
+ return new UnmodifiableIterator<ChildNode>(super.getChildNodes(offset, count, provider));
}
public Node getNode(String relPath, RevisionProvider provider) throws NotFoundException, Exception {
@@ -80,4 +78,27 @@ public class StoredNode extends Abstract
}
return result;
}
+
+ //--------------------------------------------------------< inner classes >
+
+ static class UnmodifiableIterator<T> implements Iterator<T> {
+
+ final Iterator<T> it;
+
+ public UnmodifiableIterator(Iterator<T> it) {
+ this.it = it;
+ }
+
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ public T next() {
+ return it.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java Tue Dec 27 11:57:38 2011
@@ -19,9 +19,11 @@ package org.apache.jackrabbit.mk.store;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
+import org.apache.jackrabbit.mk.model.ChildNodeEntry;
import org.apache.jackrabbit.mk.model.Commit;
import org.apache.jackrabbit.mk.model.Node;
import org.apache.jackrabbit.mk.model.StoredCommit;
@@ -119,15 +121,31 @@ public class MongoPersistenceManager ext
} else {
key.put(ID_FIELD, id);
}
- DBObject nodeObject = nodes.findOne(key);
+ final DBObject nodeObject = nodes.findOne(key);
if (nodeObject != null) {
+ // todo support partitioned child node lists
if (BINARY_FORMAT) {
byte[] bytes = (byte[]) nodeObject.get(DATA_FIELD);
return Serializer.fromBytes(id, bytes, Node.class);
} else {
+ final Iterator<String> it = nodeObject.keySet().iterator();
+ final BasicDBObject children = (BasicDBObject) nodeObject.get(CHILDREN_OBJECT);
+ Iterator<ChildNodeEntry> cneIt = new Iterator<ChildNodeEntry>() {
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ public ChildNodeEntry next() {
+ String name = it.next();
+ return new ChildNodeEntry(decodeName(name), (String) children.get(name));
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
return new StoredNode(id,
- decodeKeys(((BasicDBObject) nodeObject.get(PROPERTIES_OBJECT)).toMap()),
- (LinkedHashMap<String, String>) decodeKeys(((BasicDBObject) nodeObject.get(CHILDREN_OBJECT)).toMap()));
+ decodeKeys(((BasicDBObject) nodeObject.get(PROPERTIES_OBJECT)).toMap()), cneIt);
}
} else {
throw new NotFoundException(id);
@@ -140,13 +158,20 @@ public class MongoPersistenceManager ext
byte[] key = idFactory.createNodeId(node, bytes);
String id = StringUtils.convertBytesToHex(key);
+ // todo support partitioned child node lists
BasicDBObject nodeObject;
if (BINARY_FORMAT) {
nodeObject = new BasicDBObject(ID_FIELD, key).append(DATA_FIELD, bytes);
} else {
+ Iterator<ChildNodeEntry> it = node.getChildNodeEntries(0, -1);
+ BasicDBObject children = new BasicDBObject();
+ while (it.hasNext()) {
+ ChildNodeEntry cne = it.next();
+ children.put(cne.getName(), cne.getId());
+ }
nodeObject = new BasicDBObject(ID_FIELD, id)
.append(PROPERTIES_OBJECT, new BasicDBObject(encodeKeys(node.getProperties())))
- .append(CHILDREN_OBJECT, new BasicDBObject(encodeKeys(node.getChildNodeEntries())));
+ .append(CHILDREN_OBJECT, children);
}
try {
nodes.insert(nodeObject);
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/util/Serializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/util/Serializer.java?rev=1224899&r1=1224898&r2=1224899&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/util/Serializer.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/util/Serializer.java Tue Dec 27 11:57:38 2011
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.mk.store.util;
+import org.apache.jackrabbit.mk.model.ChildNodeEntry;
import org.apache.jackrabbit.mk.model.Commit;
import org.apache.jackrabbit.mk.model.StoredCommit;
import org.apache.jackrabbit.mk.model.StoredNode;
@@ -26,7 +27,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.Iterator;
import java.util.Map;
/**
@@ -49,11 +50,13 @@ public class Serializer {
IOUtils.writeString(out, entry.getKey());
IOUtils.writeString(out, entry.getValue());
}
- Map<String, String> childEntries = node.getChildNodeEntries(0, -1);
- IOUtils.writeVarInt(out, childEntries.size());
- for (Map.Entry<String, String> entry : childEntries.entrySet()) {
- IOUtils.writeString(out, entry.getKey());
- IOUtils.writeString(out, entry.getValue());
+ // todo support partitioned child node lists
+ Iterator<ChildNodeEntry> it = node.getChildNodeEntries(0, -1);
+ IOUtils.writeVarInt(out, node.getChildNodeCount());
+ while (it.hasNext()) {
+ ChildNodeEntry cne = it.next();
+ IOUtils.writeString(out, cne.getName());
+ IOUtils.writeString(out, cne.getId());
}
out.close();
} catch (IOException e) {
@@ -64,7 +67,7 @@ public class Serializer {
}
public static StoredNode fromBytes(String id, byte[] bytes, Class<Node> type) throws Exception {
- ByteArrayInputStream in = new ByteArrayInputStream(bytes);
+ final ByteArrayInputStream in = new ByteArrayInputStream(bytes);
if (in.read() != Constants.NODE) {
throw new Exception("unknown data format");
}
@@ -75,14 +78,33 @@ public class Serializer {
String value = IOUtils.readString(in);
props.put(name, value);
}
- count = IOUtils.readVarInt(in);
- LinkedHashMap<String, String> childEntries = new LinkedHashMap<String, String>(count);
- while (count-- > 0) {
- String name = IOUtils.readString(in);
- String childId = IOUtils.readString(in);
- childEntries.put(name, childId);
- }
- return new StoredNode(id, props, childEntries);
+ // todo support partitioned child node lists
+ final int numChildren = IOUtils.readVarInt(in);
+ Iterator<ChildNodeEntry> cneIt = new Iterator<ChildNodeEntry>() {
+
+ int cnt = numChildren;
+
+ public boolean hasNext() {
+ return cnt > 0;
+ }
+
+ public ChildNodeEntry next() {
+ cnt--;
+ String name = null, childId = null;
+ try {
+ name = IOUtils.readString(in);
+ childId = IOUtils.readString(in);
+ } catch (IOException ignore) {
+ // won't get here...
+ }
+ return new ChildNodeEntry(name, childId);
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ return new StoredNode(id, props, cneIt);
}
//---------------------------------------------------------------< Commit >