You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by ka...@apache.org on 2009/07/09 14:08:04 UTC

svn commit: r792517 - in /labs/bananadb: ./ trunk/ trunk/src/main/java/org/apache/labs/bananadb/entity/ trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/ trunk/src/main/java/org/apache/labs/bananadb/exceptions/ trunk/src/main/java/org/...

Author: kalle
Date: Thu Jul  9 12:08:04 2009
New Revision: 792517

URL: http://svn.apache.org/viewvc?rev=792517&view=rev
Log:
[Banana DB]
0.4
doap status set as completed. 


Added:
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/exceptions/
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/exceptions/DatabaseException.java
Modified:
    labs/bananadb/doap.rdf
    labs/bananadb/trunk/FILES.txt
    labs/bananadb/trunk/README.txt
    labs/bananadb/trunk/pom.xml
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityCursor.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityStore.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryIndex.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Store.java
    labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/data/bananatrie/KeysPartition.java
    labs/bananadb/trunk/src/site/apt/index.apt
    labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/TestEntityStore.java

Modified: labs/bananadb/doap.rdf
URL: http://svn.apache.org/viewvc/labs/bananadb/doap.rdf?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/doap.rdf (original)
+++ labs/bananadb/doap.rdf Thu Jul  9 12:08:04 2009
@@ -5,13 +5,11 @@
     <name>BananaDB</name>
     <shortname>bananadb</shortname>
     <shortdesc xml:lang="en">Filesystem based hashtable</shortdesc>
-    <description xml:lang="en">Map&lt;K, V> living in the filesystem rather than in RAM. Aims at becoming a general
-      embedded key/value pair DB with transactions, secondary indices and annotational API.
-    </description>
+    <description xml:lang="en">A key/value storage for Java similar to working with Map&lt;K, V> but residing on the filesystem rather than in RAM. Annotational and semi-transactional API.</description>
     <homepage rdf:resource="http://labs.apache.org/bananadb/"/>
     <license rdf:resource="http://usefulinc.com/doap/licenses/asl20"/>
     <created>2009-1-3</created>
-    <labs:status>active</labs:status>
+    <labs:status>completed</labs:status>
     <maintainer>
       <foaf:Person rdf:about="http://people.apache.org/~kalle/#me">
         <foaf:name>Karl Wettin</foaf:name>

Modified: labs/bananadb/trunk/FILES.txt
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/FILES.txt?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/FILES.txt (original)
+++ labs/bananadb/trunk/FILES.txt Thu Jul  9 12:08:04 2009
@@ -1,7 +1,5 @@
 = Files =
 
-This scheme supports up to ~180PB value data and ~150PB key data. 
-
 == [0-9]+.v ==
 
 Values postings partition file.

Modified: labs/bananadb/trunk/README.txt
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/README.txt?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/README.txt (original)
+++ labs/bananadb/trunk/README.txt Thu Jul  9 12:08:04 2009
@@ -3,5 +3,24 @@
 For more information see src/main/site/
 
 
+This project is marked as "completed" and is discontinued since July 2009.
+It is however fully functional.
+
+
+I was overwhelmed after a short introduction to CouchDB. But as I couldn't find a Java API
+that met my requirements I took the top level consumer API from BananaDB and applied it to CouchDB.
+It works extremly well according to me.
+
+CouchDB is however quite a different project compared to BananaDB.
+BananaDB is a bunch of files with a locking mechanism, CouchDB is a real DBMS.
+They both have their use cases and I think it's worth saving the BananaDB core and consumer API
+as an own project rather than hiding it as a tag in the SVN.
+
+I'd take this new project to the CouchDB-sandbox if it existed, but it doesn't and even though
+their plan is to add such an area I've been told it will only accept Erlang code.
+
+This new project is known as Tupplur and is available in Apache labs.
+
+
 
 kalle@apache.org 

Modified: labs/bananadb/trunk/pom.xml
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/pom.xml?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/pom.xml (original)
+++ labs/bananadb/trunk/pom.xml Thu Jul  9 12:08:04 2009
@@ -4,18 +4,10 @@
   <groupId>org.apache.labs</groupId>
   <artifactId>bananadb</artifactId>
   <packaging>jar</packaging>
-  <version>0.3.2-SNAPSHOT</version>
+  <version>0.4</version>
   <url>http://labs.apache.org</url>
   <name>Banana DB</name>
-  <description>A self contained key/value pair database.</description>
-
-  <distributionManagement>
-    <repository>
-      <id>kodapan</id>
-      <name>depostify</name>
-      <url>scp://maven.kodapan.se/var/www/mvn</url>
-    </repository>
-  </distributionManagement>
+  <description>A key/value pair database.</description>
 
   <licenses>
     <license>

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java Thu Jul  9 12:08:04 2009
@@ -36,6 +36,9 @@
  * of each {@link org.apache.labs.bananadb.entity.PrimaryIndex}
  * handled by an {@link org.apache.labs.bananadb.entity.EntityStore}.
  *
+ * By default it contains a {@link org.apache.labs.bananadb.entity.serialization.SerializationRegistry}
+ * using gzipped {@link java.io.Serializable} as fallback serialization.
+ * 
  * @author kalle
  * @since 2009-mar-17 07:40:44
  */
@@ -56,7 +59,7 @@
       log.info("Creating a default serialization registry");
       serializationRegistry = new SerializationRegistry();
       serializationRegistry.getHashCodeCalculators().put(Object.class, new FallBackHashCodeCalculator());
-      serializationRegistry.getMarshallers().put(Serializable.class, new SerializableMarshaller());
+      serializationRegistry.getMarshallers().put(Serializable.class, new SerializableMarshaller(true));
       serializationRegistry.getUnmarshallers().put(Serializable.class, new SerializableUnmarshaller());
     }
     return serializationRegistry;

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityCursor.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityCursor.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityCursor.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityCursor.java Thu Jul  9 12:08:04 2009
@@ -27,14 +27,14 @@
  */
 public abstract class EntityCursor<K, V> {
 
-  public abstract boolean next() throws IOException;
+  public abstract boolean next();
 
-  public abstract K key() throws IOException;
+  public abstract K key();
 
-  public abstract V value() throws IOException;
+  public abstract V value();
 
-  public abstract void remove() throws IOException;
+  public abstract void remove();
 
-  public abstract void close() throws IOException;
+  public abstract void close();
 
 }

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityStore.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityStore.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityStore.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/EntityStore.java Thu Jul  9 12:08:04 2009
@@ -23,6 +23,7 @@
 import org.apache.labs.bananadb.entity.serialization.Unmarshaller;
 import org.apache.labs.bananadb.store.Store;
 import org.apache.labs.bananadb.store.lock.Lock;
+import org.apache.labs.bananadb.store.lock.NativeFSLockFactory;
 import org.apache.labs.bananadb.store.sequence.FilebasedSequenceManager;
 import org.apache.labs.bananadb.store.sequence.SequenceManager;
 
@@ -232,6 +233,8 @@
       storeconf.setUsingDurablePostingLinks(configuration.isUsingDurablePostingLinks());
       storeconf.setValuesPartitionByteSize(configuration.getValuesPartitionByteSize());
 
+      storeconf.setLockFactory(new NativeFSLockFactory(storeconf.getDataPath()));
+
       // todo notice that the lock factory creates entity store wide locks
       // todo even when only attempting to lock a single store as in Accessor
 

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryIndex.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryIndex.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryIndex.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryIndex.java Thu Jul  9 12:08:04 2009
@@ -3,6 +3,7 @@
 import org.apache.labs.bananadb.entity.serialization.HashCodeCalculator;
 import org.apache.labs.bananadb.entity.serialization.Marshaller;
 import org.apache.labs.bananadb.entity.serialization.Unmarshaller;
+import org.apache.labs.bananadb.exceptions.DatabaseException;
 import org.apache.labs.bananadb.store.Accessor;
 import org.apache.labs.bananadb.store.Cursor;
 import org.apache.labs.bananadb.store.Store;
@@ -78,10 +79,9 @@
    * @param keyHashCodeCalculator
    * @param entityMarshaller
    * @param entityUnmarshaller
-   * @throws IOException
    * @see org.apache.labs.bananadb.entity.EntityStore#getPrimaryIndex(Class, Class, String)
    */
-  PrimaryIndex(Store store, EntityStore entityStore, String indexName, SequenceManager.Sequence<K> primaryKeySequence, Method primaryKeyGetter, Method primaryKeySetter, Class<K> keyClass, Class<E> entityClass, Marshaller keyMarshaller, Unmarshaller keyUnmarshaller, HashCodeCalculator keyHashCodeCalculator, Marshaller entityMarshaller, Unmarshaller entityUnmarshaller) throws IOException {
+  PrimaryIndex(Store store, EntityStore entityStore, String indexName, SequenceManager.Sequence<K> primaryKeySequence, Method primaryKeyGetter, Method primaryKeySetter, Class<K> keyClass, Class<E> entityClass, Marshaller keyMarshaller, Unmarshaller keyUnmarshaller, HashCodeCalculator keyHashCodeCalculator, Marshaller entityMarshaller, Unmarshaller entityUnmarshaller) {
     this.store = store;
     this.entityStore = entityStore;
     this.indexName = indexName;
@@ -110,100 +110,125 @@
 
 
   @SuppressWarnings("unchecked")
-  public E get(K key, long revision) throws IOException {
+  public E get(K key, long revision) {
 //    long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
 //    byte[] keyBytes = keyMarshaller.marshall(key);
 
-    long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
-    byte[] keyBytes = marshalPrimayIndexKey(key);
+    try {
+      long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+      byte[] keyBytes = marshalPrimayIndexKey(key);
 
-    Accessor accessor = store.borrowAccessor();
-    byte[] entityBytes = store.get(accessor, keyBytes, keyHashCode, revision);
-    store.returnAccessor(accessor);
-    if (entityBytes == null) {
-      return null;
+      Accessor accessor = store.borrowAccessor();
+      byte[] entityBytes = store.get(accessor, keyBytes, keyHashCode, revision);
+      store.returnAccessor(accessor);
+      if (entityBytes == null) {
+        return null;
+      }
+      return (E) entityUnmarshaller.unmarshall(entityBytes);
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
-    return (E) entityUnmarshaller.unmarshall(entityBytes);
+
   }
 
 
-  public boolean containsKey(final K key) throws IOException {
+  public boolean containsKey(final K key) {
 
-    Transaction txn = getEntityStore().getTxn();
-    if (txn.isActive()) {
+    try {
+      Transaction txn = getEntityStore().getTxn();
+      if (txn.isActive()) {
 
-      txn.getIsolation().checkVersion(txn);
+        txn.getIsolation().checkVersion(txn);
 
-      CachedKey cachedKey = new CachedKey(key);
+        CachedKey cachedKey = new CachedKey(key);
 
-      return !txn.getRemoved().containsKey(cachedKey)
-          && (
-          txn.getReplaced().containsKey(cachedKey)
-              || txn.getCreated().containsKey(cachedKey)
-              || containsKey(key, entityStore.getTxn().getDefaultReadRevision()));
+        return !txn.getRemoved().containsKey(cachedKey)
+            && (
+            txn.getReplaced().containsKey(cachedKey)
+                || txn.getCreated().containsKey(cachedKey)
+                || containsKey(key, entityStore.getTxn().getDefaultReadRevision()));
 
-    } else {
-      return containsKey(key, entityStore.getTxn().getDefaultReadRevision());
+      } else {
+        return containsKey(key, entityStore.getTxn().getDefaultReadRevision());
+      }
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
+
   }
 
 
-  public boolean containsKey(K key, long revision) throws IOException {
-    long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
-    byte[] keyBytes = marshalPrimayIndexKey(key);
+  public boolean containsKey(K key, long revision) {
+    try {
+      long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+      byte[] keyBytes = marshalPrimayIndexKey(key);
+
+      Accessor accessor = store.borrowAccessor();
+      boolean result = store.containsKey(accessor, keyBytes, keyHashCode, revision);
+      store.returnAccessor(accessor);
+      return result;
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
+    }
 
-    Accessor accessor = store.borrowAccessor();
-    boolean result = store.containsKey(accessor, keyBytes, keyHashCode, revision);
-    store.returnAccessor(accessor);
-    return result;
   }
 
   @SuppressWarnings("unchecked")
-  public E put(E entity, long revision) throws IOException {
-    K key = getPrimaryKey(entity);
-    if (key == null) {
-      if (primaryKeySequence == null) {
-        throw new UnsupportedOperationException("Null keys are not allowed. Did you perhaps forget to set sequence() to something in the @PrimaryKey annotation of entity class " + entityClass.getName() + "?");
+  public E put(E entity, long revision) {
+    try {
+      K key = getPrimaryKey(entity);
+      if (key == null) {
+        if (primaryKeySequence == null) {
+          throw new UnsupportedOperationException("Null keys are not allowed. Did you perhaps forget to set sequence() to something in the @PrimaryKey annotation of entity class " + entityClass.getName() + "?");
+        }
+        key = primaryKeySequence.next();
+        setPrimaryKey(entity, key);
       }
-      key = primaryKeySequence.next();
-      setPrimaryKey(entity, key);
-    }
 //    long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
 //    byte[] keyBytes = keyMarshaller.marshall(key);
-    long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
-    byte[] keyBytes = marshalPrimayIndexKey(key);
+      long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+      byte[] keyBytes = marshalPrimayIndexKey(key);
 
-    byte[] entityBytes = entityMarshaller.marshall(entity);
+      byte[] entityBytes = entityMarshaller.marshall(entity);
 
-    Accessor accessor = store.borrowAccessor();
-    byte[] oldEntityBytes = store.put(accessor, keyBytes, keyHashCode, entityBytes, revision);
-    store.returnAccessor(accessor);
-
-    if (oldEntityBytes == null) {
-      return null;
-    } else {
-      return (E) entityUnmarshaller.unmarshall(oldEntityBytes);
+      Accessor accessor = store.borrowAccessor();
+      byte[] oldEntityBytes = store.put(accessor, keyBytes, keyHashCode, entityBytes, revision);
+      store.returnAccessor(accessor);
+
+      if (oldEntityBytes == null) {
+        return null;
+      } else {
+        return (E) entityUnmarshaller.unmarshall(oldEntityBytes);
+      }
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
+
   }
 
   @SuppressWarnings("unchecked")
-  public E remove(K key, long revision) throws IOException {
+  public E remove(K key, long revision) {
+    try {
 //    long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
 //    byte[] keyBytes = keyMarshaller.marshall(key);
 
-    long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
-    byte[] keyBytes = marshalPrimayIndexKey(key);
+      long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+      byte[] keyBytes = marshalPrimayIndexKey(key);
+
 
+      Accessor accessor = store.borrowAccessor();
+      byte[] oldEntityBytes = store.remove(accessor, keyBytes, keyHashCode, revision);
+      store.returnAccessor(accessor);
 
-    Accessor accessor = store.borrowAccessor();
-    byte[] oldEntityBytes = store.remove(accessor, keyBytes, keyHashCode, revision);
-    store.returnAccessor(accessor);
-
-    if (oldEntityBytes == null) {
-      return null;
-    } else {
-      return (E) entityUnmarshaller.unmarshall(oldEntityBytes);
+      if (oldEntityBytes == null) {
+        return null;
+      } else {
+        return (E) entityUnmarshaller.unmarshall(oldEntityBytes);
+      }
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
+
   }
 
 
@@ -228,48 +253,63 @@
     }
   }
 
-  public EntityCursor<K, E> cursor() throws IOException {
+  public EntityCursor<K, E> cursor() {
     return cursor(getEntityStore().getTxn().getDefaultReadRevision());
   }
 
-  public EntityCursor<K, E> cursor(final long revision) throws IOException {
+  public EntityCursor<K, E> cursor(final long revision) {
     final Accessor accessor = store.borrowAccessor();
     final Cursor<KeysPartition.Posting> keysCursor = store.keys();
     return new EntityCursor<K, E>() {
       private KeysPartition.Posting keyPosting = new KeysPartition.Posting();
       private ValuesPartition.Posting valuePosting = new ValuesPartition.Posting();
 
-      public boolean next() throws IOException {
-        boolean result = (keyPosting = keysCursor.next(accessor, keyPosting, revision)) != null;
-        key = null;
-        value = null;
-        return result;
+      public boolean next() {
+        try {
+          boolean result = (keyPosting = keysCursor.next(accessor, keyPosting, revision)) != null;
+          key = null;
+          value = null;
+          return result;
+        } catch (IOException ioe) {
+          throw new DatabaseException(ioe);
+        }
+
       }
 
       private K key;
 
-      public K key() throws IOException {
-        if (key == null) {
-          key = unmarshalPrimaryIndexKey(keyPosting.getBytes());
+      public K key() {
+        try {
+          if (key == null) {
+            key = unmarshalPrimaryIndexKey(keyPosting.getBytes());
+          }
+          return key;
+        } catch (IOException ioe) {
+          throw new DatabaseException(ioe);
         }
-        return key;
+
       }
 
       private E value;
 
-      public E value() throws IOException {
-        if (value == null) {
-          accessor.getValuesPartition(keyPosting.getValuePostingPartition()).readPosting(valuePosting, keyPosting.getValuePostingPartitionOffset());
-          value = (E) entityUnmarshaller.unmarshall(valuePosting.getBytes());
+      public E value() {
+        try {
+          if (value == null) {
+            accessor.getValuesPartition(keyPosting.getValuePostingPartition()).readPosting(valuePosting, keyPosting.getValuePostingPartitionOffset());
+            value = (E) entityUnmarshaller.unmarshall(valuePosting.getBytes());
+          }
+          return value;
+        } catch (IOException ioe) {
+          throw new DatabaseException(ioe);
         }
-        return value;
+
       }
 
-      public void remove() throws IOException {
+      public void remove() {
         PrimaryIndex.this.remove(key());
       }
 
-      public void close() throws IOException {
+      public void close() {
         store.returnAccessor(accessor);
       }
     };
@@ -380,113 +420,134 @@
   }
 
   @SuppressWarnings("unchecked")
-  public E get(K key) throws IOException {
+  public E get(K key) {
 
-    Transaction txn = getEntityStore().getTxn();
-    if (txn.isActive()) {
+    try {
+      Transaction txn = getEntityStore().getTxn();
+      if (txn.isActive()) {
 
-      txn.getIsolation().checkVersion(txn);
+        txn.getIsolation().checkVersion(txn);
 
-      CachedKey cachedKey = new CachedKey(key);
+        CachedKey cachedKey = new CachedKey(key);
 
-      if (txn.getRemoved().containsKey(cachedKey)) {
-        return null;
-      }
-      E v;
-      if (txn.getCreated().containsKey(cachedKey)) {
-        v = (E) txn.getCreated().get(cachedKey).getObject();
-      } else if (txn.getReplaced().containsKey(cachedKey)) {
-        v = (E) txn.getReplaced().get(cachedKey).getObject();
+        if (txn.getRemoved().containsKey(cachedKey)) {
+          return null;
+        }
+        E v;
+        if (txn.getCreated().containsKey(cachedKey)) {
+          v = (E) txn.getCreated().get(cachedKey).getObject();
+        } else if (txn.getReplaced().containsKey(cachedKey)) {
+          v = (E) txn.getReplaced().get(cachedKey).getObject();
+        } else {
+          v = get(key, entityStore.getTxn().getDefaultReadRevision());
+        }
+        return v;
       } else {
-        v = get(key, entityStore.getTxn().getDefaultReadRevision());
+        return get(key, entityStore.getTxn().getDefaultReadRevision());
       }
-      return v;
-    } else {
-      return get(key, entityStore.getTxn().getDefaultReadRevision());
-    }
 
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
+    }
 
   }
 
 
   @SuppressWarnings("unchecked")
-  public E put(E entity) throws IOException {
+  public E put(E entity) {
 
-    Transaction txn = getEntityStore().getTxn();
-    if (txn.isActive()) {
+    try {
+      Transaction txn = getEntityStore().getTxn();
+      if (txn.isActive()) {
 
-      K key = getPrimaryKey(entity);
-      if (key == null) {
-        setPrimaryKey(entity, key = primaryKeySequence.next());
-      }
+        K key = getPrimaryKey(entity);
+        if (key == null) {
+          setPrimaryKey(entity, key = primaryKeySequence.next());
+        }
 
 
-      CachedKey cachedKey = new CachedKey(key);
-      CachedEntity cachedEntity = new CachedEntity(entity);
+        CachedKey cachedKey = new CachedKey(key);
+        CachedEntity cachedEntity = new CachedEntity(entity);
 
-      txn.getIsolation().checkVersion(txn);
+        txn.getIsolation().checkVersion(txn);
 
-      E v;
-      if (txn.getCreated().containsKey(cachedKey)) {
-        v = (E) txn.getCreated().put(cachedKey, cachedEntity).getObject();
-      } else if (txn.getReplaced().containsKey(cachedKey)) {
-        v = (E) txn.getReplaced().put(cachedKey, cachedEntity).getObject();
-      } else {
-        if (containsKey(key)) {
-          txn.getReplaced().put(cachedKey, cachedEntity);
-          if (txn.getRemoved().containsKey(cachedKey)) {
-            txn.getRemoved().remove(cachedKey);
-            v = null;
+        E v;
+        if (txn.getCreated().containsKey(cachedKey)) {
+          v = (E) txn.getCreated().put(cachedKey, cachedEntity).getObject();
+        } else if (txn.getReplaced().containsKey(cachedKey)) {
+          v = (E) txn.getReplaced().put(cachedKey, cachedEntity).getObject();
+        } else {
+          if (containsKey(key)) {
+            txn.getReplaced().put(cachedKey, cachedEntity);
+            if (txn.getRemoved().containsKey(cachedKey)) {
+              txn.getRemoved().remove(cachedKey);
+              v = null;
+            } else {
+              v = get(key);
+            }
           } else {
-            v = get(key);
+            txn.getCreated().put(cachedKey, cachedEntity);
+            v = null;
+            txn.getRemoved().remove(cachedKey); // todo not needed?
           }
-        } else {
-          txn.getCreated().put(cachedKey, cachedEntity);
-          v = null;
-          txn.getRemoved().remove(cachedKey); // todo not needed?
         }
+        return v;
+      } else {
+        // transactionless
+        return put(entity, entityStore.increaseStoreRevision());
       }
-      return v;
-    } else {
-      // transactionless
-      return put(entity, entityStore.increaseStoreRevision());
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
 
   }
 
 
   @SuppressWarnings("unchecked")
-  public E remove(final K key) throws IOException {
+  public E remove(final K key) {
 
-    Transaction txn = getEntityStore().getTxn();
-    if (txn.isActive()) {
+    try {
 
-      txn.getIsolation().checkVersion(txn);
+      Transaction txn = getEntityStore().getTxn();
+      if (txn.isActive()) {
 
-      CachedKey cachedKey = new CachedKey(key);
+        txn.getIsolation().checkVersion(txn);
 
+        CachedKey cachedKey = new CachedKey(key);
 
-      if (txn.getRemoved().containsKey(cachedKey)) {
-        return null;
-      }
-      E v;
-      if (txn.getCreated().containsKey(cachedKey)) {
-        v = (E) txn.getCreated().remove(cachedKey).getObject();
-      } else if (txn.getReplaced().containsKey(cachedKey)) {
-        v = (E) txn.getReplaced().remove(cachedKey).getObject();
+
+        if (txn.getRemoved().containsKey(cachedKey)) {
+          return null;
+        }
+        E v;
+        if (txn.getCreated().containsKey(cachedKey)) {
+          v = (E) txn.getCreated().remove(cachedKey).getObject();
+        } else if (txn.getReplaced().containsKey(cachedKey)) {
+          v = (E) txn.getReplaced().remove(cachedKey).getObject();
+        } else {
+          v = get(key);
+          txn.getRemoved().put(cachedKey, new CachedEntity(v));
+        }
+        return v;
       } else {
-        v = get(key);
-        txn.getRemoved().put(cachedKey, new CachedEntity(v));
+        // transactionless
+        return remove(key, entityStore.increaseStoreRevision());
       }
-      return v;
-    } else {
-      // transactionless
-      return remove(key, entityStore.increaseStoreRevision());
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
 
   }
 
   /**
+   * @return
+   * @see #count(long)
+   */
+  public long count() {
+    return count(getEntityStore().getTxn().getDefaultReadRevision());
+  }
+
+  /**
    * Counts number of entities in the store.
    * <p/>
    * A primary index and its store is unaware of how many entities it keeps for a given revision.
@@ -499,25 +560,31 @@
    * @return
    * @throws IOException
    */
-  public long count(long revision) throws IOException {
-    Accessor accessor = store.borrowAccessor();
-    Cursor<KeysPartition.Posting> cursor = store.keys();
-    KeysPartition.Posting posting = new KeysPartition.Posting();
-    long count = 0;
-    // todo implement ad hoc cursor on keys that only reads the data needed to skip by all items.
-    while ((cursor.next(accessor, posting, revision)) != null) {
-      count++;
-    }
-    store.returnAccessor(accessor);
-
-    Transaction txn = getEntityStore().getTxn();
-    if (txn.isActive()) {
-      count += txn.getCreated().size();
-      count += txn.getReplaced().size();
-      count -= txn.getRemoved().size();
-      count += txn.getIsolation().getCountModifier();
+  public long count(long revision) {
+
+    try {
+      Accessor accessor = store.borrowAccessor();
+      Cursor<KeysPartition.Posting> cursor = store.keys();
+      KeysPartition.Posting posting = new KeysPartition.Posting();
+      long count = 0;
+      // todo implement ad hoc cursor on keys that only reads the data needed to skip by all items.
+      while ((cursor.next(accessor, posting, revision)) != null) {
+        count++;
+      }
+      store.returnAccessor(accessor);
+
+      Transaction txn = getEntityStore().getTxn();
+      if (txn.isActive()) {
+        count += txn.getCreated().size();
+        count += txn.getReplaced().size();
+        count -= txn.getRemoved().size();
+        count += txn.getIsolation().getCountModifier();
+      }
+      return count;
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
     }
-    return count;
+
   }
 
 //  public long size() throws IOException {
@@ -581,9 +648,13 @@
     return indexName;
   }
 
-  public void close() throws IOException {
+  public void close() {
     if (getPrimaryKeySequence() != null) {
-      getPrimaryKeySequence().close();
+      try {
+        getPrimaryKeySequence().close();
+      } catch (IOException e) {
+        throw new DatabaseException(e);
+      }
     }
   }
 

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java Thu Jul  9 12:08:04 2009
@@ -19,6 +19,7 @@
 
 
 import org.apache.labs.bananadb.entity.isolation.IsolationStrategy;
+import org.apache.labs.bananadb.exceptions.DatabaseException;
 import org.apache.labs.bananadb.store.lock.Lock;
 
 import java.io.IOException;
@@ -61,13 +62,13 @@
 
   private long defaultReadRevision = Long.MAX_VALUE; // latest revision for non transactional
 
-  public void begin() throws IOException {
+  public void begin() {
     begin(Long.MAX_VALUE);
   }
 
-  public synchronized void begin(long readRevision) throws IOException {
+  public synchronized void begin(long readRevision) {
     if (active) {
-      throw new IOException("Transaction has already begun");
+      throw new DatabaseException("Transaction has already begun");
     }
     active = true;
     this.defaultReadRevision = readRevision;
@@ -75,7 +76,11 @@
     replaced = new HashMap<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>();
     removed = new HashMap<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>();
 
-    storeRevisionTransactionIsSynchronizedWith = entityStore.getStoreRevision();
+    try {
+      storeRevisionTransactionIsSynchronizedWith = entityStore.getStoreRevision();
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
+    }
   }
 
   /**
@@ -83,42 +88,48 @@
    * @throws IOException
    */
   @SuppressWarnings("unchecked")
-  public synchronized long commit() throws IOException {
+  public synchronized long commit() {
     if (!active) {
-      throw new IOException("Transaction is not started");
+      throw new DatabaseException("Transaction is not started");
     }
 
-    return new Lock.With<Long>(entityStore.getStoreWriteLock(), entityStore.getConfiguration().getLockWaitTimeoutMilliseconds()) {
-      public Long doBody() throws IOException {
-        isolation.checkVersion(Transaction.this);
+    try {
+      return new Lock.With<Long>(entityStore.getStoreWriteLock(), entityStore.getConfiguration().getLockWaitTimeoutMilliseconds()) {
+        public Long doBody() throws IOException {
+          isolation.checkVersion(Transaction.this);
+
+          long revision = entityStore.increaseStoreRevision();
+
+          for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : removed.entrySet()) {
+            e.getKey().getPrimaryIndex().remove(e.getKey().getObject(), revision);
+          }
+          for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : created.entrySet()) {
+            e.getKey().getPrimaryIndex().put(e.getValue().getObject(), revision);
+          }
+          for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : replaced.entrySet()) {
+            e.getKey().getPrimaryIndex().put(e.getValue().getObject(), revision);
+          }
+
+          created = null;
+          replaced = null;
+          removed = null;
 
-        long revision = entityStore.increaseStoreRevision();
+          active = false;
 
-        for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : removed.entrySet()) {
-          e.getKey().getPrimaryIndex().remove(e.getKey().getObject(), revision);
-        }
-        for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : created.entrySet()) {
-          e.getKey().getPrimaryIndex().put(e.getValue().getObject(), revision);
-        }
-        for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : replaced.entrySet()) {
-          e.getKey().getPrimaryIndex().put(e.getValue().getObject(), revision);
+          return revision;
         }
+      }.run();
+    } catch (IOException ioe) {
+      throw new DatabaseException(ioe);
+    }
 
-        created = null;
-        replaced = null;
-        removed = null;
-        
-        active = false;
-
-        return revision;
-      }
-    }.run();
   }
 
-  public synchronized void abort() throws IOException {
+
+  public synchronized void abort() {
 
     if (!active) {
-      throw new IOException("Transaction is not started");
+      throw new DatabaseException("Transaction is not started");
     }
 
     created = null;

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java Thu Jul  9 12:08:04 2009
@@ -19,8 +19,11 @@
 
 
 import java.io.*;
+import java.util.zip.GZIPOutputStream;
 
 /**
+ * Handles serializable object, optionally gzipped.
+ *
  * @see java.io.Serializable
  * @see org.apache.labs.bananadb.entity.serialization.SerializableUnmarshaller
  * @author kalle
@@ -28,12 +31,38 @@
  */
 public class SerializableMarshaller extends Marshaller  {
 
+  /** if true, output will be gzipped */
+  private boolean usingCompression = false;
+
+  public SerializableMarshaller() {
+  }
+
+  public SerializableMarshaller(boolean usingCompression) {
+    this.usingCompression = usingCompression;
+  }
+
+  public boolean isUsingCompression() {
+    return usingCompression;
+  }
+
+  public void setUsingCompression(boolean usingCompression) {
+    this.usingCompression = usingCompression;
+  }
+
   public byte[] marshall(Object object) throws IOException {
     ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
-    ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+    OutputStream out;
+    if (usingCompression) {
+      out = new GZIPOutputStream(baos);
+    } else {
+      out = baos;
+    }
+
+    ObjectOutputStream oos = new ObjectOutputStream(out);
     oos.writeObject(object);
     oos.close();
     return baos.toByteArray();
   }
-  
+
 }
\ No newline at end of file

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java Thu Jul  9 12:08:04 2009
@@ -19,8 +19,11 @@
 
 
 import java.io.*;
+import java.util.zip.GZIPInputStream;
 
 /**
+ * Handles gzipped or non gzipped serializable object
+ *
  * @see java.io.Serializable
  * @see org.apache.labs.bananadb.entity.serialization.SerializableMarshaller
  * @author kalle
@@ -28,8 +31,16 @@
  */
 public class SerializableUnmarshaller extends Unmarshaller {
 
+  public SerializableUnmarshaller() {
+  }
+
   public Serializable unmarshall(byte[] bytes, int startOffset, int length) throws IOException {
-    ObjectInputStream oos = new ObjectInputStream(new ByteArrayInputStream(bytes, startOffset, length));
+    InputStream in = new ByteArrayInputStream(bytes, startOffset, length);
+    if (length > 2 && bytes[startOffset] == 31 && bytes[startOffset+1] == -117) {
+      // gzip magic numbers todo create our own two byte header insead! 
+      in = new GZIPInputStream(in);
+    }
+    ObjectInputStream oos = new ObjectInputStream(in);
     Serializable object;
     try {
       object = (Serializable) oos.readObject();

Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/exceptions/DatabaseException.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/exceptions/DatabaseException.java?rev=792517&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/exceptions/DatabaseException.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/exceptions/DatabaseException.java Thu Jul  9 12:08:04 2009
@@ -0,0 +1,23 @@
+package org.apache.labs.bananadb.exceptions;
+
+/**
+ * @author kalle
+ * @since 2009-jun-29 06:08:08
+ */
+public class DatabaseException extends RuntimeException {
+
+  public DatabaseException() {
+  }
+
+  public DatabaseException(String s) {
+    super(s);
+  }
+
+  public DatabaseException(String s, Throwable throwable) {
+    super(s, throwable);
+  }
+
+  public DatabaseException(Throwable throwable) {
+    super(throwable);
+  }
+}

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Store.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Store.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Store.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Store.java Thu Jul  9 12:08:04 2009
@@ -28,6 +28,7 @@
 import org.apache.labs.bananadb.store.data.bananatrie.KeysPartition;
 import org.apache.labs.bananadb.store.data.bananatrie.ValuesPartition;
 import org.apache.labs.bananadb.store.lock.Lock;
+import org.apache.labs.bananadb.exceptions.DatabaseException;
 
 import java.io.File;
 import java.io.IOException;
@@ -107,23 +108,19 @@
 
   }
 
-  public Accessor borrowAccessor() throws IOException {
+  public Accessor borrowAccessor() {
     try {
       return (Accessor) accessorPool.borrowObject();
-    } catch (IOException e) {
-      throw e;
     } catch (Exception e) {
-      throw new RuntimeException(e);
+      throw new DatabaseException(e);
     }
   }
 
-  public void returnAccessor(Accessor accessor) throws IOException {
+  public void returnAccessor(Accessor accessor)  {
     try {
       accessorPool.returnObject(accessor);
-    } catch (IOException e) {
-      throw e;
     } catch (Exception e) {
-      throw new RuntimeException(e);
+      throw new DatabaseException(e);
     }
   }
 

Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/data/bananatrie/KeysPartition.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/data/bananatrie/KeysPartition.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/data/bananatrie/KeysPartition.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/data/bananatrie/KeysPartition.java Thu Jul  9 12:08:04 2009
@@ -250,6 +250,9 @@
 
   public void readPosting(Posting posting, RandomAccessFile RAF) throws IOException {
     posting.flag = RAF.readByte();
+    if (posting.flag == 0) {
+      return;
+    }
     posting.createdRevision = RAF.readLong();
     posting.nextKeyPostingPartition = RAF.readInt();
     posting.nextKeyPostingPartitionOffset = RAF.readInt();

Modified: labs/bananadb/trunk/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/site/apt/index.apt?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/site/apt/index.apt (original)
+++ labs/bananadb/trunk/src/site/apt/index.apt Thu Jul  9 12:08:04 2009
@@ -3,14 +3,13 @@
 
 Banana DB
 
-    Banana DB is a key/value pair database implemented in Java.
+    Banana DB is a key/value pair database implemented in Java
+    with a consumer API similar to working with a java.util.Map&lt;K, V>.
 
 
 * Features
 
-    * Less than 200KB .jar-files with all dependencies included. 100% Apache.
-
-    * A core byte array key/value file system storage with cursors.
+    * Low memory usage. All persistent data always resides on file system.
 
     * Thread safe and write locking over multiple JVMs (using Lucene locks made reentrant).
 
@@ -20,20 +19,15 @@
 
     * Pluggable serialization strategies (java.io.Serializable as default).
 
-
-* Possible upcoming features
-
-    * Secondary indices
-
-    * Optimized generic serialization.
+    * A core byte array key/value file system storage with cursors.
 
 
 * About the ACID support
 
         * Atomicity, write all postings or no postings at all during commit.
-        In cases of fatal shutdowns such as loss of power, this is not supported, but is ment to solve it by using the durabillity revision log.
+        In cases of fatal shutdowns such as loss of power, this is not supported, but is could be solved using the durabillity revision log.
 
-        * Consistency, writes only valid data to the store.
+        * Consistency, writes only valid data to the store. This will however depend on the serialization strategy you use. 
 
         * Isolation, rules for accessing uncommited and locked data.
 
@@ -46,7 +40,7 @@
             * Updated. (Read committed)
             Keeps your transaction synchronized with the store by accepting any changes to the store over your uncommitted updates.
 
-        * Durability, abillity to access the data from older revisions.
+        * Durability, abillity to instantly access the database the way it look in a previous revision.
 
             
 Releases
@@ -88,13 +82,8 @@
 
 Compared to other databases
 
- The Banana DB API is very similar to other key/value database implementations.
+ The Banana DB consumer API is quite similar to many other key/value database implementations.
 
- The main reason for the existence of Banana DB
- is the lack of a key value database implemented in Java
- with a very simple consumer API
- distributed under the Apache Software License.
- 
  I am not a lawyer. Please double-check any information regarding licensing models mentioned below.
 
 
@@ -177,7 +166,7 @@
         private String password;
 
         public Long getIdentity() {
-          return PK;
+          return identity;
         ...
 
 

Modified: labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/TestEntityStore.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/TestEntityStore.java?rev=792517&r1=792516&r2=792517&view=diff
==============================================================================
--- labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/TestEntityStore.java (original)
+++ labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/TestEntityStore.java Thu Jul  9 12:08:04 2009
@@ -35,28 +35,17 @@
 
     PrimaryIndex<Long, Message> messages = store.getPrimaryIndex(Long.class, Message.class);
 
-    messages.put(new Message(1l, "one"));
-    messages.put(new Message(2l, "two"));
-    messages.put(new Message(3l, "three"));
-    messages.put(new Message(4l, "four"));
+    for (long l = 0; l < 1000; l++) {
+      messages.put(new Message(l, String.valueOf(l)));
+    }
 
     EntityCursor<Long, Message> cursor = messages.cursor();
 
-    assertTrue(cursor.next());
-    assertEquals(1l, (long)cursor.key());
-    assertEquals("one", cursor.value().getSubject());
-
-    assertTrue(cursor.next());
-    assertEquals(2l, (long)cursor.key());
-    assertEquals("two", cursor.value().getSubject());
-
-    assertTrue(cursor.next());
-    assertEquals(3l, (long)cursor.key());
-    assertEquals("three", cursor.value().getSubject());
-
-    assertTrue(cursor.next());
-    assertEquals(4l, (long)cursor.key());
-    assertEquals("four", cursor.value().getSubject());
+    for (long l = 0; l < 1000; l++) {
+      assertTrue(cursor.next());
+      assertEquals(l, (long) cursor.key());
+      assertEquals(String.valueOf(l), cursor.value().getSubject());
+    }
 
     assertFalse(cursor.next());
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org