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 2004/11/08 18:42:34 UTC
svn commit: rev 56953 - in incubator/jackrabbit/trunk: . src/java/org/apache/jackrabbit/core src/java/org/apache/jackrabbit/core/state xdocs
Author: stefan
Date: Mon Nov 8 09:42:33 2004
New Revision: 56953
Added:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LazyItemIterator.java (contents, props changed)
Modified:
incubator/jackrabbit/trunk/ToDo.txt
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeReferences.java
incubator/jackrabbit/trunk/xdocs/tasks.xml
Log:
- added lazy-loading item iterator
- optimized Node.has/getNodes(), Node.has/getProperties()
Modified: incubator/jackrabbit/trunk/ToDo.txt
==============================================================================
--- incubator/jackrabbit/trunk/ToDo.txt (original)
+++ incubator/jackrabbit/trunk/ToDo.txt Mon Nov 8 09:42:33 2004
@@ -6,9 +6,6 @@
- locking
- access control (jaas)
-- current persistence model (nodes and properties are stored in separate
- files) leads to *very* slow performance in a normal filesystem;
- see next issues for solutions
- use jdbc as an alternative to virtual filesystem persistence layer
- use an alternative journaling store as (transactional) persistence layer
- provide clean abstraction for persistence grouping (nodes & properties
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/ItemManager.java Mon Nov 8 09:42:33 2004
@@ -18,17 +18,13 @@
import org.apache.commons.collections.ReferenceMap;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.jackrabbit.core.state.*;
-import org.apache.jackrabbit.core.util.IteratorHelper;
import org.apache.log4j.Logger;
import javax.jcr.*;
import javax.jcr.nodetype.NodeDef;
import javax.jcr.nodetype.PropertyDef;
import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.*;
/**
* There's one <code>ItemManager</code> instance per <code>Session</code>
@@ -237,6 +233,57 @@
* @throws AccessDeniedException
* @throws RepositoryException
*/
+ synchronized boolean hasChildNodes(NodeId parentId)
+ throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+ // check privileges
+ if (!session.getAccessManager().isGranted(parentId, AccessManager.READ)) {
+ // clear cache
+ ItemImpl item = retrieveItem(parentId);
+ if (item != null) {
+ evictItem(parentId);
+ }
+ throw new AccessDeniedException("cannot read item " + parentId);
+ }
+
+ ItemState state = null;
+ try {
+ state = itemStateProvider.getItemState(parentId);
+ } catch (NoSuchItemStateException nsise) {
+ String msg = "no such item: " + parentId;
+ log.error(msg);
+ throw new ItemNotFoundException(msg);
+ } catch (ItemStateException ise) {
+ String msg = "failed to retrieve item state of node " + parentId;
+ log.error(msg);
+ throw new RepositoryException(msg);
+ }
+
+ if (!state.isNode()) {
+ String msg = "can't list child nodes of property " + parentId;
+ log.error(msg);
+ throw new RepositoryException(msg);
+ }
+ NodeState nodeState = (NodeState) state;
+ Iterator iter = nodeState.getChildNodeEntries().iterator();
+
+ while (iter.hasNext()) {
+ NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
+ NodeId id = new NodeId(entry.getUUID());
+ // check read access
+ if (session.getAccessManager().isGranted(id, AccessManager.READ)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param parentId
+ * @return
+ * @throws ItemNotFoundException
+ * @throws AccessDeniedException
+ * @throws RepositoryException
+ */
synchronized NodeIterator getChildNodes(NodeId parentId)
throws ItemNotFoundException, AccessDeniedException, RepositoryException {
// check privileges
@@ -249,7 +296,7 @@
throw new AccessDeniedException("cannot read item " + parentId);
}
- ArrayList children = new ArrayList();
+ ArrayList childIds = new ArrayList();
ItemState state = null;
try {
@@ -274,16 +321,66 @@
while (iter.hasNext()) {
NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
- try {
- Item item = getItem(new NodeId(entry.getUUID()));
- children.add(item);
- } catch (AccessDeniedException ade) {
- // ignore
- continue;
+ NodeId id = new NodeId(entry.getUUID());
+ // check read access
+ if (session.getAccessManager().isGranted(id, AccessManager.READ)) {
+ childIds.add(id);
+ }
+ }
+
+ return new LazyItemIterator(this, childIds);
+ }
+
+ /**
+ * @param parentId
+ * @return
+ * @throws ItemNotFoundException
+ * @throws AccessDeniedException
+ * @throws RepositoryException
+ */
+ synchronized boolean hasChildProperties(NodeId parentId)
+ throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+ // check privileges
+ if (!session.getAccessManager().isGranted(parentId, AccessManager.READ)) {
+ ItemImpl item = retrieveItem(parentId);
+ if (item != null) {
+ evictItem(parentId);
}
+ throw new AccessDeniedException("cannot read item " + parentId);
}
- return new IteratorHelper(Collections.unmodifiableList(children));
+ ItemState state = null;
+ try {
+ state = itemStateProvider.getItemState(parentId);
+ } catch (NoSuchItemStateException nsise) {
+ String msg = "no such item: " + parentId;
+ log.error(msg);
+ throw new ItemNotFoundException(msg);
+ } catch (ItemStateException ise) {
+ String msg = "failed to retrieve item state of node " + parentId;
+ log.error(msg);
+ throw new RepositoryException(msg);
+ }
+
+ if (!state.isNode()) {
+ String msg = "can't list child properties of property " + parentId;
+ log.error(msg);
+ throw new RepositoryException(msg);
+ }
+ NodeState nodeState = (NodeState) state;
+ Iterator iter = nodeState.getPropertyEntries().iterator();
+
+ while (iter.hasNext()) {
+ NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
+
+ PropertyId id = new PropertyId(parentId.getUUID(), entry.getName());
+ // check read access
+ if (session.getAccessManager().isGranted(id, AccessManager.READ)) {
+ return true;
+ }
+ }
+
+ return false;
}
/**
@@ -304,7 +401,7 @@
throw new AccessDeniedException("cannot read item " + parentId);
}
- ArrayList children = new ArrayList();
+ ArrayList childIds = new ArrayList();
ItemState state = null;
try {
@@ -329,18 +426,14 @@
while (iter.hasNext()) {
NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
- try {
- Item item = getItem(new PropertyId(parentId.getUUID(), entry.getName()));
- children.add(item);
- } catch (AccessDeniedException ade) {
- // ignore
- continue;
+ PropertyId id = new PropertyId(parentId.getUUID(), entry.getName());
+ // check read access
+ if (session.getAccessManager().isGranted(id, AccessManager.READ)) {
+ childIds.add(id);
}
}
- // not need to add virtual properties
-
- return new IteratorHelper(Collections.unmodifiableList(children));
+ return new LazyItemIterator(this, childIds);
}
//-------------------------------------------------< item factory methods >
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LazyItemIterator.java
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LazyItemIterator.java Mon Nov 8 09:42:33 2004
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.core;
+
+import javax.jcr.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * <code>LazyItemIterator</code> is an id-based iterator that instantiates
+ * the <code>Item</code>s only when they are requested.
+ */
+public class LazyItemIterator implements NodeIterator, PropertyIterator {
+
+ private final ItemManager itemMgr;
+ private final List idList;
+ private int pos;
+
+ /**
+ * Creates a new <code>LazyItemIterator</code> instance.
+ *
+ * @param itemMgr item manager
+ * @param idList list of item id's
+ */
+ LazyItemIterator(ItemManager itemMgr, List idList) {
+ this.itemMgr = itemMgr;
+ this.idList = new ArrayList(idList);
+ pos = -1;
+ }
+
+ //---------------------------------------------------------< NodeIterator >
+ public Node nextNode() {
+ return (Node) next();
+ }
+
+ //-----------------------------------------------------< PropertyIterator >
+ public Property nextProperty() {
+ return (Property) next();
+ }
+
+ //--------------------------------------------------------< RangeIterator >
+ public long getPos() {
+ return pos + 1;
+ }
+
+ public long getSize() {
+ return idList.size();
+ }
+
+ public void skip(long skipNum) {
+ if (skipNum < 0) {
+ throw new IllegalArgumentException("skipNum must be a positive number");
+ }
+ if (pos + skipNum >= idList.size()) {
+ pos = idList.size() - 1;
+ throw new NoSuchElementException();
+ }
+ pos += skipNum;
+ }
+
+ //-------------------------------------------------------------< Iterator >
+ public boolean hasNext() {
+ return pos < idList.size() - 1;
+ }
+
+ public Object next() {
+ if (pos >= idList.size() - 1) {
+ throw new NoSuchElementException();
+ }
+ while (true) {
+ pos++;
+ try {
+ return itemMgr.getItem((ItemId) idList.get(pos));
+ } catch (AccessDeniedException ade) {
+ // silently ignore and try next
+ continue;
+ } catch (RepositoryException re) {
+ // FIXME: not quite correct
+ throw new NoSuchElementException(re.getMessage());
+ }
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("remove");
+ }
+}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java Mon Nov 8 09:42:33 2004
@@ -17,7 +17,6 @@
import org.apache.jackrabbit.core.nodetype.*;
import org.apache.jackrabbit.core.state.*;
-import org.apache.jackrabbit.core.util.ChildrenCollector;
import org.apache.jackrabbit.core.util.ChildrenCollectorFilter;
import org.apache.jackrabbit.core.util.IteratorHelper;
import org.apache.jackrabbit.core.util.uuid.UUID;
@@ -1463,10 +1462,7 @@
* return false if child nodes exist
* but the session is not granted read-access
*/
- ArrayList nodes = new ArrayList();
- // traverse children using a 'collector'
- accept(new ChildrenCollector(nodes, true, false, 1));
- return (nodes.size() > 0);
+ return itemMgr.hasChildNodes((NodeId) id);
}
/**
@@ -1482,10 +1478,7 @@
* return false if properties exist
* but the session is not granted read-access
*/
- ArrayList props = new ArrayList();
- // traverse children using a 'collector'
- accept(new ChildrenCollector(props, false, true, 1));
- return (props.size() > 0);
+ return itemMgr.hasChildProperties((NodeId) id);
}
/**
@@ -1877,13 +1870,9 @@
ReferenceManager refMgr = wsp.getReferenceManager();
synchronized (refMgr) {
NodeReferences refs = refMgr.get((NodeId) id);
- Iterator iter = refs.getReferences().iterator();
- ArrayList list = new ArrayList();
- while (iter.hasNext()) {
- PropertyId propId = (PropertyId) iter.next();
- list.add(itemMgr.getItem(propId));
- }
- return new IteratorHelper(list);
+ // refs.getReferences returns a list of PropertyId's
+ List idList = refs.getReferences();
+ return new LazyItemIterator(itemMgr, idList);
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeReferences.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeReferences.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeReferences.java Mon Nov 8 09:42:33 2004
@@ -71,8 +71,8 @@
/**
* @return
*/
- public Collection getReferences() {
- return Collections.unmodifiableCollection(references);
+ public List getReferences() {
+ return Collections.unmodifiableList(references);
}
/**
Modified: incubator/jackrabbit/trunk/xdocs/tasks.xml
==============================================================================
--- incubator/jackrabbit/trunk/xdocs/tasks.xml (original)
+++ incubator/jackrabbit/trunk/xdocs/tasks.xml Mon Nov 8 09:42:33 2004
@@ -13,10 +13,6 @@
access control (jaas)
</task>
<task creator="stefan" assignedto="" startdate="" enddate="" effort="" status="">
- current persistence model (nodes and properties are stored in separate
- files) leads to *very* slow performance in a normal filesystem;
- </task>
- <task creator="stefan" assignedto="" startdate="" enddate="" effort="" status="">
use jdbc as an alternative to virtual filesystem persistence layer
</task>
<task creator="stefan" assignedto="" startdate="" enddate="" effort="" status="">