[exo-jcr-commits] exo-jcr SVN: r1332 - in jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src: test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Sun Jan 10 14:25:21 EST 2010


Author: nzamosenchuk
Date: 2010-01-10 14:25:20 -0500 (Sun, 10 Jan 2010)
New Revision: 1332

Added:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/CompressedChangesList.java
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestCompressedList.java
Modified:
   jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
Log:
EXOJCR-371: Added CompressedChangesList and test for it and BufferedCache modified: inner classes are now public and CompressedChangesList is used.

Modified: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java	2010-01-10 18:27:37 UTC (rev 1331)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/BufferedJBossCache.java	2010-01-10 19:25:20 UTC (rev 1332)
@@ -14,7 +14,6 @@
 import org.jgroups.Address;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -32,7 +31,7 @@
     */
    private final Cache<Serializable, Object> parentCache;
 
-   private ThreadLocal<List<ChangesContainer>> changesList = new ThreadLocal<List<ChangesContainer>>();
+   private ThreadLocal<CompressedChangesList> changesList = new ThreadLocal<CompressedChangesList>();
 
    public BufferedJBossCache(Cache<Serializable, Object> parentCache)
    {
@@ -45,7 +44,7 @@
     */
    public void beginTransaction()
    {
-      changesList.set(new ArrayList<ChangesContainer>());
+      changesList.set(new CompressedChangesList());
    }
 
    /**
@@ -53,7 +52,7 @@
     */
    public void commitTransaction()
    {
-      List<ChangesContainer> changesContainer = changesList.get();
+      CompressedChangesList changesContainer = changesList.get();
       if (changesContainer == null)
       {
          throw new IllegalStateException("changesContainer should not be empty");
@@ -347,12 +346,12 @@
    public void put(Fqn fqn, Map<? extends Serializable, ? extends Object> data)
    {
       //parentCache.put(fqn, data);
-      List<ChangesContainer> changesContainer = changesList.get();
+      CompressedChangesList changesContainer = changesList.get();
       if (changesContainer == null)
       {
          throw new IllegalStateException("changesContainer should not be empty");
       }
-      changesContainer.add(new PutObjectContainer(fqn, data, parentCache, changesContainer.size()));
+      changesContainer.add(new PutObjectContainer(fqn, data, parentCache, changesContainer.getHistoryIndex()));
    }
 
    /* (non-Javadoc)
@@ -360,12 +359,12 @@
     */
    public Object put(Fqn fqn, Serializable key, Object value)
    {
-      List<ChangesContainer> changesContainer = changesList.get();
+      CompressedChangesList changesContainer = changesList.get();
       if (changesContainer == null)
       {
          throw new IllegalStateException("changesContainer should not be empty");
       }
-      changesContainer.add(new PutKeyValueContainer(fqn, key, value, parentCache, changesContainer.size()));
+      changesContainer.add(new PutKeyValueContainer(fqn, key, value, parentCache, changesContainer.getHistoryIndex()));
 
       return parentCache.get(fqn, key);
    }
@@ -400,12 +399,12 @@
     */
    public Object remove(Fqn fqn, Serializable key)
    {
-      List<ChangesContainer> changesContainer = changesList.get();
+      CompressedChangesList changesContainer = changesList.get();
       if (changesContainer == null)
       {
          throw new IllegalStateException("changesContainer should not be empty");
       }
-      changesContainer.add(new RemoveKeyContainer(fqn, key, parentCache, changesContainer.size()));
+      changesContainer.add(new RemoveKeyContainer(fqn, key, parentCache, changesContainer.getHistoryIndex()));
       return parentCache.get(fqn, key);
    }
 
@@ -446,12 +445,12 @@
     */
    public boolean removeNode(Fqn fqn)
    {
-      List<ChangesContainer> changesContainer = changesList.get();
+      CompressedChangesList changesContainer = changesList.get();
       if (changesContainer == null)
       {
          throw new IllegalStateException("changesContainer should not be empty");
       }
-      changesContainer.add(new RemoveNodeContainer(fqn, parentCache, changesContainer.size()));
+      changesContainer.add(new RemoveNodeContainer(fqn, parentCache, changesContainer.getHistoryIndex()));
       return true;
    }
 
@@ -508,8 +507,8 @@
       return ((CacheSPI<Serializable, Object>)parentCache).getTransactionManager();
    }
 
-   private static enum ChangesType {
-      REMOVED, ADDED;
+   public static enum ChangesType {
+      REMOVE, REMOVE_KEY, PUT, PUT_KEY;
    }
 
    /**
@@ -517,7 +516,7 @@
     * @author sj
     *
     */
-   private static abstract class ChangesContainer implements Comparable<ChangesContainer>
+   public static abstract class ChangesContainer implements Comparable<ChangesContainer>
    {
       protected final Fqn fqn;
 
@@ -583,14 +582,14 @@
     * @author sj
     *
     */
-   private static class PutObjectContainer extends ChangesContainer
+   public static class PutObjectContainer extends ChangesContainer
    {
       private final Map<? extends Serializable, ? extends Object> data;
 
       public PutObjectContainer(Fqn fqn, Map<? extends Serializable, ? extends Object> data,
          Cache<Serializable, Object> cache, int historicalIndex)
       {
-         super(fqn, ChangesType.ADDED, cache, historicalIndex);
+         super(fqn, ChangesType.PUT, cache, historicalIndex);
 
          this.data = data;
       }
@@ -607,7 +606,7 @@
     * @author sj
     *
     */
-   private static class PutKeyValueContainer extends ChangesContainer
+   public static class PutKeyValueContainer extends ChangesContainer
    {
       private final Serializable key;
 
@@ -616,7 +615,7 @@
       public PutKeyValueContainer(Fqn fqn, Serializable key, Object value, Cache<Serializable, Object> cache,
          int historicalIndex)
       {
-         super(fqn, ChangesType.ADDED, cache, historicalIndex);
+         super(fqn, ChangesType.PUT_KEY, cache, historicalIndex);
          this.key = key;
          this.value = value;
       }
@@ -633,13 +632,13 @@
     * @author sj
     *
     */
-   private static class RemoveKeyContainer extends ChangesContainer
+   public static class RemoveKeyContainer extends ChangesContainer
    {
       private final Serializable key;
 
       public RemoveKeyContainer(Fqn fqn, Serializable key, Cache<Serializable, Object> cache, int historicalIndex)
       {
-         super(fqn, ChangesType.REMOVED, cache, historicalIndex);
+         super(fqn, ChangesType.REMOVE_KEY, cache, historicalIndex);
          this.key = key;
       }
 
@@ -657,12 +656,12 @@
     * @author sj
     *
     */
-   private static class RemoveNodeContainer extends ChangesContainer
+   public static class RemoveNodeContainer extends ChangesContainer
    {
 
       public RemoveNodeContainer(Fqn fqn, Cache<Serializable, Object> cache, int historicalIndex)
       {
-         super(fqn, ChangesType.REMOVED, cache, historicalIndex);
+         super(fqn, ChangesType.REMOVE, cache, historicalIndex);
       }
 
       @Override

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/CompressedChangesList.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/CompressedChangesList.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/CompressedChangesList.java	2010-01-10 19:25:20 UTC (rev 1332)
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache;
+
+import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.BufferedJBossCache.ChangesContainer;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.BufferedJBossCache.ChangesType;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * This class implement algorithm of list compressing, omitting unnecessary 
+ * changes and optimizing list. I.e. if added REMOVE /a/b, then list removes
+ * all changes made for /a/b/* 
+ * 
+ * @author <a href="mailto:nikolazius at gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id: CompressedChangesList.java 0 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+public class CompressedChangesList implements List<ChangesContainer>
+{
+   private List<ChangesContainer> changesList = new ArrayList<ChangesContainer>();
+
+   private int historyIndex = 0;
+
+   /**
+    * After each add this field is incremented, so each change can use it as a 
+    * history timestamp to identify original order
+    * @return
+    */
+   public int getHistoryIndex()
+   {
+      return historyIndex;
+   }
+
+   /**
+    * @see java.util.List#add(java.lang.Object)
+    */
+   public boolean add(ChangesContainer e)
+   {
+      historyIndex++;
+      // TODO: most interesting is here
+      optimize(e);
+      changesList.add(e);
+      return false;
+   }
+
+   private int optimize(ChangesContainer newChange)
+   {
+
+      Iterator<ChangesContainer> iter = changesList.iterator();
+      // if /a/b REMOVE performed, then remove all changes from list 
+      // made on any child /a/b/* (remove usecase)
+      if (newChange.getChangesType() == ChangesType.REMOVE)
+      {
+         while (iter.hasNext())
+         {
+            ChangesContainer c = iter.next();
+            if (c.getFqn().isChildOrEquals(newChange.getFqn()))
+            {
+               iter.remove();
+            }
+         }
+      }
+      // if /a/b PUT performed, then remove all previous PUT or PUT_VALUE
+      // performed on exact /a/b path (rewrite usecase)
+      else if (newChange.getChangesType() == ChangesType.PUT)
+      {
+         while (iter.hasNext())
+         {
+            ChangesContainer c = iter.next();
+            if (c.getFqn().equals(newChange.getFqn()))
+            {
+               iter.remove();
+            }
+         }
+      }
+
+      return 0;
+   }
+
+   /**
+    * @see java.util.List#add(int, java.lang.Object)
+    */
+   public void add(int index, ChangesContainer element)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#addAll(java.util.Collection)
+    */
+   public boolean addAll(Collection<? extends ChangesContainer> c)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#addAll(int, java.util.Collection)
+    */
+   public boolean addAll(int index, Collection<? extends ChangesContainer> c)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#clear()
+    */
+   public void clear()
+   {
+      changesList.clear();
+   }
+
+   /**
+    * @see java.util.List#contains(java.lang.Object)
+    */
+   public boolean contains(Object o)
+   {
+      return changesList.contains(o);
+   }
+
+   /**
+    * @see java.util.List#containsAll(java.util.Collection)
+    */
+   public boolean containsAll(Collection<?> c)
+   {
+      return changesList.containsAll(c);
+   }
+
+   /**
+    * @see java.util.List#get(int)
+    */
+   public ChangesContainer get(int index)
+   {
+      return changesList.get(index);
+   }
+
+   /**
+    * @see java.util.List#indexOf(java.lang.Object)
+    */
+   public int indexOf(Object o)
+   {
+      return changesList.indexOf(o);
+   }
+
+   /**
+    * @see java.util.List#isEmpty()
+    */
+   public boolean isEmpty()
+   {
+      return changesList.isEmpty();
+   }
+
+   /**
+    * @see java.util.List#iterator()
+    */
+   public Iterator<ChangesContainer> iterator()
+   {
+      return changesList.iterator();
+   }
+
+   /**
+    * @see java.util.List#lastIndexOf(java.lang.Object)
+    */
+   public int lastIndexOf(Object o)
+   {
+      return changesList.lastIndexOf(o);
+   }
+
+   /**
+    * @see java.util.List#listIterator()
+    */
+   public ListIterator<ChangesContainer> listIterator()
+   {
+      return changesList.listIterator();
+   }
+
+   /**
+    * @see java.util.List#listIterator(int)
+    */
+   public ListIterator<ChangesContainer> listIterator(int index)
+   {
+      return changesList.listIterator(index);
+   }
+
+   /**
+    * @see java.util.List#remove(java.lang.Object)
+    */
+   public boolean remove(Object o)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#remove(int)
+    */
+   public ChangesContainer remove(int index)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#removeAll(java.util.Collection)
+    */
+   public boolean removeAll(Collection<?> c)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#retainAll(java.util.Collection)
+    */
+   public boolean retainAll(Collection<?> c)
+   {
+      throw new UnsupportedOperationException("Unexpected method call ");
+   }
+
+   /**
+    * @see java.util.List#set(int, java.lang.Object)
+    */
+   public ChangesContainer set(int index, ChangesContainer element)
+   {
+      return changesList.set(index, element);
+   }
+
+   /**
+    * @see java.util.List#size()
+    */
+   public int size()
+   {
+      return changesList.size();
+   }
+
+   /**
+    * @see java.util.List#subList(int, int)
+    */
+   public List<ChangesContainer> subList(int fromIndex, int toIndex)
+   {
+      return changesList.subList(fromIndex, toIndex);
+   }
+
+   /**
+    * @see java.util.List#toArray()
+    */
+   public Object[] toArray()
+   {
+      return changesList.toArray();
+   }
+
+   /**
+    * @see java.util.List#toArray(T[])
+    */
+   public <T> T[] toArray(T[] a)
+   {
+      return changesList.toArray(a);
+   }
+
+   /**
+    * @see java.lang.Object#toString()
+    */
+   @Override
+   public String toString()
+   {
+      return changesList.toString();
+   }
+
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/CompressedChangesList.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestCompressedList.java
===================================================================
--- jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestCompressedList.java	                        (rev 0)
+++ jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestCompressedList.java	2010-01-10 19:25:20 UTC (rev 1332)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache;
+
+import junit.framework.TestCase;
+
+import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.BufferedJBossCache.ChangesContainer;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.BufferedJBossCache.PutObjectContainer;
+import org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.BufferedJBossCache.RemoveNodeContainer;
+import org.jboss.cache.Fqn;
+
+import java.util.HashMap;
+
+/**
+ * @author <a href="mailto:foo at bar.org">Foo Bar</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z aheritier $
+ *
+ */
+public class TestCompressedList extends TestCase
+{
+
+   public void testPutOmit()
+   {
+      CompressedChangesList changesList = new CompressedChangesList();
+      ChangesContainer put1 =
+         new PutObjectContainer(Fqn.fromString("/a/b"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+      ChangesContainer put2 =
+         new PutObjectContainer(Fqn.fromString("/a/b/c"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+      ChangesContainer rm1 = new RemoveNodeContainer(Fqn.fromString("/a/b"), null, changesList.getHistoryIndex());
+      changesList.add(put1);
+      changesList.add(put2);
+      assertTrue("List MUST contain put container", changesList.contains(put1));
+      assertTrue("List MUST contain put container", changesList.contains(put2));
+      changesList.add(rm1);
+      assertFalse("List still contains put container", changesList.contains(put1));
+      assertFalse("List still contains put container", changesList.contains(put2));
+      assertTrue("List MUST contain remove container", changesList.contains(rm1));
+   }
+
+   public void testDoublePutOmit()
+   {
+      CompressedChangesList changesList = new CompressedChangesList();
+      ChangesContainer put1 =
+         new PutObjectContainer(Fqn.fromString("/a/b"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+      ChangesContainer put2 =
+         new PutObjectContainer(Fqn.fromString("/a/b"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+
+      changesList.add(put1);
+      assertTrue("List MUST contain put container", changesList.contains(put1));
+      changesList.add(put2);
+      assertFalse("List still contains old put container", changesList.contains(put1));
+      assertTrue("List MUST contain new put container", changesList.contains(put2));
+   }
+   
+   public void testPutKeyOmit()
+   {
+      CompressedChangesList changesList = new CompressedChangesList();
+      ChangesContainer put1 =
+         new PutObjectContainer(Fqn.fromString("/a/b"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+      ChangesContainer put2 =
+         new PutObjectContainer(Fqn.fromString("/a/b"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+
+      changesList.add(put1);
+      assertTrue("List MUST contain put container", changesList.contains(put1));
+      changesList.add(put2);
+      assertFalse("List still contains old put container", changesList.contains(put1));
+      assertTrue("List MUST contain new put container", changesList.contains(put2));
+   }
+   
+   public void testPutChildOmit()
+   {
+      CompressedChangesList changesList = new CompressedChangesList();
+      ChangesContainer put1 =
+         new PutObjectContainer(Fqn.fromString("/a/b"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+      ChangesContainer put2 =
+         new PutObjectContainer(Fqn.fromString("/a/b/c"), new HashMap<String, String>(), null, changesList
+            .getHistoryIndex());
+      ChangesContainer rm1 = new RemoveNodeContainer(Fqn.fromString("/a/b"), null, changesList.getHistoryIndex());
+      changesList.add(put1);
+      changesList.add(put2);
+      assertTrue("List MUST contain put container", changesList.contains(put1));
+      assertTrue("List MUST contain put container", changesList.contains(put2));
+      changesList.add(rm1);
+      assertFalse("List still contains old put container", changesList.contains(put1));
+      assertFalse("List still contains old put container", changesList.contains(put2));
+      assertTrue("List MUST contain remove container", changesList.contains(rm1));
+   }
+   
+}


Property changes on: jcr/branches/1.12.0-JBCCACHE/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/TestCompressedList.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain



More information about the exo-jcr-commits mailing list