[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