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 2012/02/04 23:14:16 UTC

svn commit: r1240626 - in /jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model: AbstractNode.java ChildNodeEntriesBucket.java ChildNodeEntriesTree.java MutableNode.java

Author: stefan
Date: Sat Feb  4 22:14:00 2012
New Revision: 1240626

URL: http://svn.apache.org/viewvc?rev=1240626&view=rev
Log:
flat hierarchy support (WIP)

Modified:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/AbstractNode.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesBucket.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesTree.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/MutableNode.java

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=1240626&r1=1240625&r2=1240626&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 Sat Feb  4 22:14:00 2012
@@ -52,12 +52,14 @@ public abstract class AbstractNode imple
             this.childEntries = (ChildNodeEntries) srcNode.childEntries.clone();
         } else {
             this.properties = new HashMap<String, String>(other.getProperties());
+            this.childEntries = new ChildNodeEntriesInlined();
+/*
             if (other.getChildNodeCount() <= ChildNodeEntries.CAPACITY_THRESHOLD) {
                 this.childEntries = new ChildNodeEntriesInlined();
             } else {
-                this.childEntries = new ChildNodeEntriesTree();
+                this.childEntries = new ChildNodeEntriesTree(provider);
             }
-
+*/
             for (Iterator<ChildNodeEntry> it = other.getChildNodeEntries(0, -1); it.hasNext(); ) {
                 ChildNodeEntry cne = it.next();
                 this.childEntries.add(cne);

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesBucket.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesBucket.java?rev=1240626&r1=1240625&r2=1240626&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesBucket.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesBucket.java Sat Feb  4 22:14:00 2012
@@ -43,6 +43,10 @@ public class ChildNodeEntriesBucket exte
         entries = new HashMap<String, ChildNodeEntry>();
     }
 
+    public ChildNodeEntriesBucket(ChildNodeEntriesBucket other) {
+        entries = (HashMap<String, ChildNodeEntry>) other.entries.clone();
+    }
+
     //------------------------------------------------------------< overrides >
 
     @Override

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesTree.java?rev=1240626&r1=1240625&r2=1240626&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesTree.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/model/ChildNodeEntriesTree.java Sat Feb  4 22:14:00 2012
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.mk.model;
 
+import org.apache.jackrabbit.mk.store.RevisionProvider;
+import org.apache.jackrabbit.mk.store.RevisionStore;
 import org.apache.jackrabbit.mk.util.AbstractFilteringIterator;
 import org.apache.jackrabbit.mk.util.AbstractRangeIterator;
 import org.apache.jackrabbit.mk.util.EmptyIterator;
@@ -33,11 +35,14 @@ public class ChildNodeEntriesTree implem
     protected static final Iterator<ChildNodeEntry> EMPTY_ITER = new EmptyIterator<ChildNodeEntry>();
 
     protected int count;
+    
+    protected RevisionProvider revProvider;
 
     // array of *immutable* IndexEntry objects
     protected IndexEntry[] index = new IndexEntry[1024];  // 2^10
 
-    ChildNodeEntriesTree() {
+    ChildNodeEntriesTree(RevisionProvider revProvider) {
+        this.revProvider = revProvider;
     }
 
     @Override
@@ -87,10 +92,14 @@ public class ChildNodeEntriesTree implem
         }
         if (entry instanceof ChildNodeEntry) {
             return (ChildNodeEntry) entry;
-        } else {
+        } else if (entry instanceof BucketInfo) {
             BucketInfo bi = (BucketInfo) entry;
             ChildNodeEntries entries = retrieveBucket(bi.getId());
             return entries == null ? null : entries.get(name);
+        } else {
+            // dirty bucket
+            Bucket bucket = (Bucket) entry;
+            return bucket.get(name);
         }
     }
 
@@ -139,7 +148,7 @@ public class ChildNodeEntriesTree implem
                 } else {
                     if (e instanceof NodeInfo) {
                         list.add((NodeInfo) e);
-                    } else {
+                    } else if (e instanceof BucketInfo) {
                         BucketInfo bi = (BucketInfo) e;
                         ChildNodeEntriesBucket bucket = retrieveBucket(bi.getId());
                         for (Iterator<ChildNodeEntry> it =
@@ -148,6 +157,15 @@ public class ChildNodeEntriesTree implem
                             list.add(it.next());
                         }
                         skipped = offset;
+                    } else {
+                        // dirty bucket
+                        Bucket bucket = (Bucket) e;
+                        for (Iterator<ChildNodeEntry> it =
+                                     bucket.getEntries(offset - skipped, cnt - list.size());
+                             it.hasNext(); ) {
+                            list.add(it.next());
+                        }
+                        skipped = offset;
                     }
                     if (list.size() == cnt) {
                         break;
@@ -176,34 +194,35 @@ public class ChildNodeEntriesTree implem
                 index[idx] = new NodeInfo(entry.getName(), entry.getId());
                 return existing;
             } else {
-                ChildNodeEntriesBucket bucket = new ChildNodeEntriesBucket();
+                Bucket bucket = new Bucket();
                 bucket.add(existing);
                 bucket.add(entry);
-                // todo store bucket and update index entry with new bucket id (content hash)
-                //bucketId = <content hash of bucket>;
-                String bucketId = "";
-                index[idx] = new BucketInfo(bucketId, 2);
+                index[idx] = bucket;
                 count++;
                 return null;
             }
-        } else {
+        } 
+        
+        Bucket bucket;
+        if (ie instanceof BucketInfo) {
             BucketInfo bi = (BucketInfo) ie;
-            ChildNodeEntries entries = retrieveBucket(bi.getId());
-            ChildNodeEntry existing = entries.add(entry);
-            if (entry.equals(existing)) {
-                // no-op
-                return existing;
-            }
-            // todo store bucket and update index entry with new bucket id (content hash)
-            //bucketId = <content hash of bucket>;
-            String bucketId = "";
-            if (existing == null) {
-                // new entry
-                count++;
-                index[idx] = new BucketInfo(bucketId, entries.getCount());;
-            }
+            bucket = new Bucket(retrieveBucket(bi.getId()));
+        } else {
+            // dirty bucket
+            bucket = (Bucket) ie;
+        }
+
+        ChildNodeEntry existing = bucket.add(entry);
+        if (entry.equals(existing)) {
+            // no-op
             return existing;
         }
+        index[idx] = bucket;
+        if (existing == null) {
+            // new entry
+            count++;
+        }
+        return existing;
     }
 
     @Override
@@ -222,28 +241,32 @@ public class ChildNodeEntriesTree implem
             } else {
                 return null;
             }
-        } else {
+        }
+        
+        Bucket bucket;
+        if (ie instanceof BucketInfo) {
             BucketInfo bi = (BucketInfo) ie;
-            ChildNodeEntries entries = retrieveBucket(bi.getId());
-            ChildNodeEntry existing = entries.remove(name);
-            if (existing == null) {
-                return null;
-            }
-            if (entries.getCount() == 0) {
-                index[idx] = null;
-            } else if (entries.getCount() == 1) {
-                // inline single remaining entry
-                ChildNodeEntry remaining = entries.getEntries(0, 1).next();
-                index[idx] = new NodeInfo(remaining.getName(), remaining.getId());
-            } else {
-                // todo store bucket and update index entry with new bucket id (content hash)
-                //bucketId = <content hash of bucket>;
-                String bucketId = "";
-                index[idx] = new BucketInfo(bucketId, entries.getCount());
-            }
-            count--;
-            return existing;
+            bucket = new Bucket(retrieveBucket(bi.getId()));
+        } else {
+            // dirty bucket
+            bucket = (Bucket) ie;
+        }
+
+        ChildNodeEntry existing = bucket.remove(name);
+        if (existing == null) {
+            return null;
         }
+        if (bucket.getCount() == 0) {
+            index[idx] = null;
+        } else if (bucket.getCount() == 1) {
+            // inline single remaining entry
+            ChildNodeEntry remaining = bucket.getEntries(0, 1).next();
+            index[idx] = new NodeInfo(remaining.getName(), remaining.getId());
+        } else {
+            index[idx] = bucket;
+        }
+        count--;
+        return existing;
     }
 
     @Override
@@ -291,13 +314,20 @@ public class ChildNodeEntriesTree implem
                         // this index entry in null => other must be non-null
                         if (ie2 instanceof NodeInfo) {
                             added.add((ChildNodeEntry) ie2);    
-                        } else {
+                        } else if (ie2 instanceof BucketInfo) {
                             BucketInfo bi = (BucketInfo) ie2;
                             ChildNodeEntriesBucket bucket = retrieveBucket(bi.getId());
                             for (Iterator<ChildNodeEntry> it = bucket.getEntries(0, -1);
                                  it.hasNext(); ) {
                                 added.add(it.next());
                             }
+                        } else {
+                            // dirty bucket
+                            Bucket bucket = (Bucket) ie2;
+                            for (Iterator<ChildNodeEntry> it = bucket.getEntries(0, -1);
+                                 it.hasNext(); ) {
+                                added.add(it.next());
+                            }
                         }
                     } else if (ie2 != null) {
                         // both this and other index entry are non-null
@@ -305,17 +335,23 @@ public class ChildNodeEntriesTree implem
                         if (ie1 instanceof NodeInfo) {
                             bucket1 = new ChildNodeEntriesBucket();
                             bucket1.add((ChildNodeEntry) ie1);
-                        } else {
+                        } else if (ie1 instanceof BucketInfo) {
                             BucketInfo bi = (BucketInfo) ie1;
                             bucket1 = retrieveBucket(bi.getId());
+                        } else {
+                            // dirty bucket
+                            bucket1 = (Bucket) ie1;
                         }
                         ChildNodeEntriesBucket bucket2;
                         if (ie2 instanceof NodeInfo) {
                             bucket2 = new ChildNodeEntriesBucket();
                             bucket2.add((ChildNodeEntry) ie2);
-                        } else {
+                        } else if (ie2 instanceof BucketInfo) {
                             BucketInfo bi = (BucketInfo) ie2;
                             bucket2 = retrieveBucket(bi.getId());
+                        } else {
+                            // dirty bucket
+                            bucket2 = (Bucket) ie2;
                         }
 
                         for (Iterator<ChildNodeEntry> it = bucket1.getAdded(bucket2);
@@ -355,13 +391,20 @@ public class ChildNodeEntriesTree implem
                         // other index entry in null => this must be non-null
                         if (ie1 instanceof NodeInfo) {
                             removed.add((ChildNodeEntry) ie1);
-                        } else {
+                        } else if (ie2 instanceof BucketInfo) {
                             BucketInfo bi = (BucketInfo) ie1;
                             ChildNodeEntriesBucket bucket = retrieveBucket(bi.getId());
                             for (Iterator<ChildNodeEntry> it = bucket.getEntries(0, -1);
                                  it.hasNext(); ) {
                                 removed.add(it.next());
                             }
+                        } else {
+                            // dirty bucket
+                            Bucket bucket = (Bucket) ie1;
+                            for (Iterator<ChildNodeEntry> it = bucket.getEntries(0, -1);
+                                 it.hasNext(); ) {
+                                removed.add(it.next());
+                            }
                         }
                     } else if (ie1 != null) {
                         // both this and other index entry are non-null
@@ -369,17 +412,23 @@ public class ChildNodeEntriesTree implem
                         if (ie1 instanceof NodeInfo) {
                             bucket1 = new ChildNodeEntriesBucket();
                             bucket1.add((ChildNodeEntry) ie1);
-                        } else {
+                        } else if (ie1 instanceof BucketInfo) {
                             BucketInfo bi = (BucketInfo) ie1;
                             bucket1 = retrieveBucket(bi.getId());
+                        } else {
+                            // dirty bucket
+                            bucket1 = (Bucket) ie1;
                         }
                         ChildNodeEntriesBucket bucket2;
                         if (ie2 instanceof NodeInfo) {
                             bucket2 = new ChildNodeEntriesBucket();
                             bucket2.add((ChildNodeEntry) ie2);
-                        } else {
+                        } else if (ie2 instanceof BucketInfo) {
                             BucketInfo bi = (BucketInfo) ie2;
                             bucket2 = retrieveBucket(bi.getId());
+                        } else {
+                            // dirty bucket
+                            bucket2 = (Bucket) ie2;
                         }
 
                         for (Iterator<ChildNodeEntry> it = bucket1.getRemoved(bucket2);
@@ -430,17 +479,23 @@ public class ChildNodeEntriesTree implem
                     if (ie1 instanceof NodeInfo) {
                         bucket1 = new ChildNodeEntriesBucket();
                         bucket1.add((ChildNodeEntry) ie1);
-                    } else {
+                    } else if (ie1 instanceof BucketInfo) {
                         BucketInfo bi = (BucketInfo) ie1;
                         bucket1 = retrieveBucket(bi.getId());
+                    } else {
+                        // dirty bucket
+                        bucket1 = (Bucket) ie1;
                     }
                     ChildNodeEntriesBucket bucket2;
                     if (ie2 instanceof NodeInfo) {
                         bucket2 = new ChildNodeEntriesBucket();
                         bucket2.add((ChildNodeEntry) ie2);
-                    } else {
+                    } else if (ie2 instanceof BucketInfo) {
                         BucketInfo bi = (BucketInfo) ie2;
                         bucket2 = retrieveBucket(bi.getId());
+                    } else {
+                        // dirty bucket
+                        bucket2 = (Bucket) ie2;
                     }
 
                     for (Iterator<ChildNodeEntry> it = bucket1.getModified(bucket2);
@@ -464,6 +519,17 @@ public class ChildNodeEntriesTree implem
 
     //-------------------------------------------------------< implementation >
     
+    protected void persistDirtyBuckets(RevisionStore store) throws Exception {
+        for (int i = 0; i < index.length; i++) {
+            if (index[i] instanceof Bucket) {
+                // dirty bucket
+                Bucket bucket = (Bucket) index[i];
+                String id = store.putCNEBucket(bucket);
+                index[i] = new BucketInfo(id, bucket.getSize());
+            }
+        }
+    }
+
     protected int keyToIndex(String key) {
         int hash = key.hashCode();
         // todo rehash? ensure optimal distribution of hash WRT to index.length
@@ -471,8 +537,12 @@ public class ChildNodeEntriesTree implem
     }
 
     protected ChildNodeEntriesBucket retrieveBucket(String id) {
-        // todo implement
-        return null;
+        try {
+            return revProvider.getCNEBucket(id);
+        } catch (Exception e) {
+            // todo log error and gracefully handle exception
+            return new ChildNodeEntriesBucket();
+        }
     }
 
     //--------------------------------------------------------< inner classes >
@@ -516,6 +586,32 @@ public class ChildNodeEntriesTree implem
         }
     }
 
+    protected static class Bucket extends ChildNodeEntriesBucket implements IndexEntry {
+
+        protected Bucket() {
+        }
+
+        protected Bucket(ChildNodeEntriesBucket other) {
+            super(other);
+        }
+
+        @Override
+        public int getSize() {
+            return getCount();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof Bucket) {
+                return super.equals(obj);
+            }
+            return false;
+        }
+    }
+
     protected static class NodeInfo extends ChildNodeEntry implements IndexEntry {
 
         public NodeInfo(String name, String id) {
@@ -528,7 +624,13 @@ public class ChildNodeEntriesTree implem
 
         @Override
         public boolean equals(Object obj) {
-            return super.equals(obj);
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof NodeInfo) {
+                return super.equals(obj);
+            }
+            return false;
         }
     }
 }

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=1240626&r1=1240625&r2=1240626&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 Sat Feb  4 22:14:00 2012
@@ -46,6 +46,7 @@ public class MutableNode extends Abstrac
 
     @Override
     public void serialize(Binding binding) throws Exception {
+        // todo serialize inlined child entries
         super.serialize(binding);
     }
 
@@ -54,7 +55,8 @@ public class MutableNode extends Abstrac
     @Override
     public void prePersist(RevisionStore store) throws Exception {
         if (!childEntries.inlined()) {
-            // todo persist dirty buckets (delegate to ChildNodeEntries instance?)
+            // persist dirty buckets
+            ((ChildNodeEntriesTree) childEntries).persistDirtyBuckets(store);
         }
     }