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<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<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<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