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/03/17 11:14:04 UTC
svn commit: r755179 [1/3] - in /labs/bananadb/trunk: ./
src/main/java/org/apache/labs/bananadb/entity/
src/main/java/org/apache/labs/bananadb/entity/isolation/
src/main/java/org/apache/labs/bananadb/entity/serialization/
src/main/java/org/apache/labs/b...
Author: kalle
Date: Tue Mar 17 10:14:03 2009
New Revision: 755179
URL: http://svn.apache.org/viewvc?rev=755179&view=rev
Log:
BananaDB
v0.3, complete rewrite from scratch. still a few features missing, but works just fine as it is.
Added:
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/
- copied from r754666, labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/index/
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Sequence.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/isolation/
- copied from r754666, labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/hashtable/txn/
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/FallBackHashCodeCalculator.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/HashCodeCalculator.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Marshaller.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/entity/serialization/SerializationRegistry.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Unmarshaller.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Accessor.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Configuration.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Cursor.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/FileHandler.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/HashCodesPartition.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Hashtable.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/KeysPartition.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Log.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/Metadata.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/ValuesPartition.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/
- copied from r754666, labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/lock/
labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/
labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/entity/TestEntityStore.java
labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/store/
labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/store/StoreTest.java
labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/store/TestStore.java
Removed:
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/README.txt
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/Transaction.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/hashtable/
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/index/
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/lock/
labs/bananadb/trunk/src/test/java/log4j.properties
labs/bananadb/trunk/src/test/java/org/apache/labs/bananadb/hashtable/
Modified:
labs/bananadb/trunk/FILES.txt
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/AbstractIndex.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Entity.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/PrimaryKey.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryIndex.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryKey.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/AbstractIsolation.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/DeadlockException.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/Isolation.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationDeadlocking.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationLastCommitWins.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationUpdated.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/Lock.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/LockFactory.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/LockObtainFailedException.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/LockReleaseFailedException.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/LockStressTest.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/LockVerifyServer.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/NativeFSLockFactory.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/NoLockFactory.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/NoSuchDirectoryException.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/SimpleFSLockFactory.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/SingleInstanceLockFactory.java
labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/store/lock/VerifyingLockFactory.java
labs/bananadb/trunk/src/site/apt/index.apt
Modified: labs/bananadb/trunk/FILES.txt
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/FILES.txt?rev=755179&r1=755178&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/FILES.txt (original)
+++ labs/bananadb/trunk/FILES.txt Tue Mar 17 10:14:03 2009
@@ -1,71 +1,125 @@
= Files =
-== values.[0-9]+ ==
+This scheme supports up to ~180PB value data and ~150PB key data.
-Hashtable entity values, the serialized V part of the Hashtable<K, V>.
-There can be any number of these files, refered to as partitions in the code.
+== [0-9]+.v ==
+
+Values postings partition file.
+
+This file is NOT affected by rehashing.
Header: 1024 bytes
{{{
-int next value postings start offset
-int capacity
+int Offset in this partition for next new posting.
+int Bytes left for use in this partition.
}}}
+
Posting data:
{{{
-int value length in bytes. 0 = null
-byte[] serialized value
+byte Flag
+ 0 = never used
+ 1 = in use
+ 2 = deleted
+
+int Length in bytes of serializaed value.
+ 0 == null
+byte[] Serialized value.
}}}
-== keys ==
+== [0-9]+.k ==
+
+Key postings partition file.
-Hashtable key postings list, the serialized K part of the Hashtable<K, V>.
-If keys share the same hash code,
-or if the capacity is not great enough for keys to get a unique posting the the hashtable
-entities will be added to a list that must be iterated in order to find the correct posting.
+Chained postings. Each posting contains a unique key value and points at how to
+find the value associated with this key.
+
+This file is NOT affected by rehashing.
Header: 1024 bytes
{{{
-int next available key posting offset
-int entity count
-int postings start offset -- will change after rehash
-int postings end offset -- will change after rehash
-int capacity
-long version -- increased by 1 after each change to the database
+int Offset in this partition for next new posting.
+int Bytes left for use in this partition.
}}}
Posting data:
{{{
-deleted key posting values are all set to -2.
+byte Flag
+ 0 = never used
+ 1 = in use
+ 2 = deleted
+
+int Partition id of next key posting with the same hash code.
+ -1 == end of keys chain
+int Offset in above key postings partition.
-int offset position in this file to the next entry with the same hash, -1 = null
-int key hash
-int value partition number, -1 = null value
-int offset position in value partition, -1 = null
-int key length in bytes, 0 = null // todo remove
-byte[] serialized key (if not null)
+long Key hash code
+int Paritition id of value posting.
+ -1 == null
+int Offset in above value postings partition.
+
+int Length in bytes of serialized key.
+byte[] Serialized key
}}}
-== hashtable ==
+== [0-9]+.hc ==
+
+Hash code postings partition file.
-The actual key entity hashtable, points at the first position in entities-file for the given hash.
-The position for any given key is calculated with: hash & (capacity - 1);
+Chained postings. Each postings has a unique hash code value and points at how to find
+the key posting for this hash code.
+This file is affected by rehashing.
Header: 1024 bytes
{{{
-int hash posting start offset -- will change after rehash
-int capacity
+int Offset in this partition for next new posting.
+int Bytes left for use in this partition.
+
+}}}
+
+Posting data:
+{{{
+
+byte Flag
+ 0 = never used
+ 1 = in use
+ 2 = deleted
+
+long Key hash code.
+
+int Partition id of next hash code posting with the same hashtable posting position.
+ -1 == null
+int Offset in above hash code postings partition.
+
+int Partition id of first key posting with this hash code.
+int Offset in above key postings partition.
+
+}}}
+
+== [0-9]+.ht ==
+
+Hashtable file. There is never more than one of these that are valid at any given time.
+
+The position in the hashtable for a given hash code is calculated as (hash & (capacity - 1)).
+At this position there is a posting that points at the first known hash code posting.
+
+This file is affected by rehashing.
+
+Header: 1024 bytes
+{{{
+
+int This hashtable postings file capacity.
}}}
@@ -73,9 +127,24 @@
Posting data:
{{{
-byte 0 = no posting. Any other value means there is a posting.
-int offset position in key postings to first entity with this hash
-int offset position in key postings to last entity with this hash (used at rehash time)
+int Partition id of first hash code posting with this hashtable position.
+ -1 == null
+int Offset in above hash code postings partition.
}}}
+== metadata ==
+
+Contains information about the database.
+
+{{{
+
+int File format version.
+long Commit version, will increase by one after each modification to the database.
+int Current hashtable file id. -- will change after rehash.
+int Current hash code partition
+int Current keys partition
+int Current values partition
+long Total number of value postings.
+
+}}}
\ No newline at end of file
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/AbstractIndex.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/AbstractIndex.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/AbstractIndex.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/AbstractIndex.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,4 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,12 +23,12 @@
* Date: 2008-jul-23
* Time: 02:34:19
*/
-public abstract class AbstractIndex<K, T> {
+public abstract class AbstractIndex<K, V> {
- public abstract EntityCursor<T> cursor();
+ public abstract EntityCursor<V> cursor();
- public abstract EntityCursor<T> cursor(K start);
+ public abstract EntityCursor<V> cursor(K start);
- public abstract EntityCursor<T> cursor(K start, K end);
+ public abstract EntityCursor<V> cursor(K start, K end);
}
Added: 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=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Configuration.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,71 @@
+package org.apache.labs.bananadb.entity;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import org.apache.labs.bananadb.entity.isolation.Isolation;
+import org.apache.labs.bananadb.entity.isolation.IsolationUpdated;
+import org.apache.labs.bananadb.entity.serialization.SerializationRegistry;
+import org.apache.labs.bananadb.entity.serialization.FallBackHashCodeCalculator;
+import org.apache.labs.bananadb.entity.serialization.SerializableMarshaller;
+import org.apache.labs.bananadb.entity.serialization.SerializableUnmarshaller;
+import org.apache.labs.bananadb.store.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 07:40:44
+ */
+public class Configuration extends org.apache.labs.bananadb.store.Configuration {
+
+ private static final Log log = new Log(Configuration.class);
+
+ public Configuration(File dataPath) throws IOException {
+ super(dataPath);
+ }
+
+ private Isolation defaultIsolation = new IsolationUpdated();
+
+ private SerializationRegistry serializationRegistry;
+
+ public SerializationRegistry getSerializationRegistry() {
+ if (serializationRegistry == null) {
+ 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.getUnmarshallers().put(Serializable.class, new SerializableUnmarshaller());
+ }
+ return serializationRegistry;
+ }
+
+ public void setSerializationRegistry(SerializationRegistry serializationRegistry) {
+ this.serializationRegistry = serializationRegistry;
+ }
+
+ public Isolation getDefaultIsolation() {
+ return defaultIsolation;
+ }
+
+ public void setDefaultIsolation(Isolation defaultIsolation) {
+ this.defaultIsolation = defaultIsolation;
+ }
+}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Entity.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Entity.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Entity.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Entity.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,4 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -18,10 +18,19 @@
*/
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Retention;
+
+
+
/**
* User: kalle
* Date: 2008-jul-24
* Time: 19:12:08
*/
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
public @interface Entity {
}
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=755179&r1=754666&r2=755179&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 Tue Mar 17 10:14:03 2009
@@ -1,4 +1,4 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
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=755179&r1=754666&r2=755179&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 Tue Mar 17 10:14:03 2009
@@ -1,4 +1,4 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -18,19 +18,139 @@
*/
+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.entity.Transaction;
+import org.apache.labs.bananadb.store.*;
+import org.apache.labs.bananadb.store.Configuration;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.File;
+import java.io.IOException;
+
+
/**
* User: kalle
* Date: 2008-jul-23
* Time: 02:54:45
*/
-public class EntityStore {
+public class EntityStore extends Store {
+
+ private org.apache.labs.bananadb.entity.Configuration configuration;
+
+ public EntityStore(File dataPath) throws IOException {
+ this(new org.apache.labs.bananadb.entity.Configuration(dataPath));
+ }
+
+ public EntityStore(org.apache.labs.bananadb.entity.Configuration configuration) {
+ super(configuration);
+ this.configuration = configuration;
+ }
+
+ public org.apache.labs.bananadb.entity.Configuration getConfiguration() {
+ return configuration;
+ }
+
+ private Map<Class, PrimaryIndex> primaryIndexByEntityClass = new HashMap<Class, PrimaryIndex>();
+
+
+ @SuppressWarnings("unchecked")
+ public <PK, V> PrimaryIndex<PK, V> getPrimaryIndex(Class<PK> keyClass, Class<V> entityClass) {
+ PrimaryIndex<PK, V> primaryIndex = primaryIndexByEntityClass.get(entityClass);
+ if (primaryIndex == null) {
+
+ if (!entityClass.isAnnotationPresent(Entity.class)) {
+ throw new RuntimeException("Entity class " + entityClass.getName() + " is not annotated with @Entity");
+ }
+
+ Method primaryKeyGetter;
+ Method primaryKeySetter;
+ Sequence primaryKeySequence;
+ {
+ List<Field> pkFields = new ArrayList<Field>();
+ for (Field field : entityClass.getDeclaredFields()) {
+ if (field.isAnnotationPresent(PrimaryKey.class)) {
+ pkFields.add(field);
+ }
+ }
+ if (pkFields.size() == 0) {
+ throw new RuntimeException("No field in class " + entityClass.getName() + " annotated with @PrimaryKey");
+ } else if (pkFields.size() > 1) {
+ StringBuilder sb = new StringBuilder(1000);
+ for (Field pkField : pkFields) {
+ if (sb.length() > 0) {
+ sb.append(", ");
+ }
+ sb.append(pkField.getName());
+ }
+ throw new RuntimeException("Multiple fields in class " + entityClass.getName() + " annotated with @PrimaryKey: " + sb.toString());
+ }
+ Field primaryKeyField = pkFields.get(0);
+ StringBuffer name = new StringBuffer(primaryKeyField.getName());
+ name.setCharAt(0, Character.toUpperCase(name.charAt(0)));
+ String getterName = "get" + name.toString();
+ try {
+ primaryKeyGetter = entityClass.getMethod(getterName);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("@PrimaryKey field " + primaryKeyField.getName() + " of @Entity class " + entityClass.getName() + " does not have a getter method named " + getterName);
+ }
+ String setterName = "set" + name.toString();
+ try {
+ primaryKeySetter = entityClass.getMethod(setterName, primaryKeyField.getType());
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("@PrimaryKey field " + primaryKeyField.getName() + " of @Entity class " + entityClass.getName() + " does not have a setter method named " + setterName);
+ }
+ PrimaryKey primaryKey = primaryKeyField.getAnnotation(PrimaryKey.class);
+ if ("[unassigned]".equals(primaryKey.sequence())) {
+ primaryKeySequence = new Sequence(this, entityClass.getName());
+ } else {
+ primaryKeySequence = new Sequence(this, primaryKey.sequence());
+ }
+ }
+
+ Marshaller keyMarshaller = getConfiguration().getSerializationRegistry().getMarshaller(keyClass);
+ Unmarshaller keyUnmarshaller = getConfiguration().getSerializationRegistry().getUnmarshaller(keyClass);
+ HashCodeCalculator keyHashCodeCalculator = getConfiguration().getSerializationRegistry().getHashCodeCalcualtor(keyClass);
+ Marshaller entityMarshaller = getConfiguration().getSerializationRegistry().getMarshaller(entityClass);
+ Unmarshaller entityUnmarshaller = getConfiguration().getSerializationRegistry().getUnmarshaller(entityClass);
+
+ primaryIndex = new PrimaryIndex<PK, V>(
+ this,
+ primaryKeySequence,
+ primaryKeyGetter, primaryKeySetter,
+ keyClass, entityClass,
+ keyMarshaller, keyUnmarshaller, keyHashCodeCalculator,
+ entityMarshaller, entityUnmarshaller
+ );
+
+ primaryIndexByEntityClass.put(entityClass, primaryIndex);
+ }
+
+ return primaryIndex;
+ }
- public <PK, T> PrimaryIndex<PK, T> getPrimaryIndex(Class primaryKeyClass, Class entityClass) {
- return null;
+ public <PK, SK, V> SecondaryIndex<PK, SK, V> getSecondaryIndex(PrimaryIndex<PK, V> primaryIndex, Class<SK> secondaryKeyClass, String secondaryKeyAttributeName) {
+ throw new UnsupportedOperationException();
}
- public <PK, SK, T> SecondaryIndex<PK, SK, T> getSecondaryIndex(PrimaryIndex<PK, T> primaryIndex, Class secondaryKeyClass, String secondaryKeyAttributeName) {
- return null;
+ private ThreadLocal<Transaction> transactions = new ThreadLocal<Transaction>() {
+ @Override
+ protected Transaction initialValue() {
+ return new Transaction(EntityStore.this);
+ }
+ };
+
+ /**
+ * @return A thread local transaction.
+ */
+ public Transaction getTxn() {
+ return transactions.get();
}
}
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=755179&r1=754666&r2=755179&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 Tue Mar 17 10:14:03 2009
@@ -1,4 +1,17 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
+
+import org.apache.labs.bananadb.entity.serialization.Marshaller;
+import org.apache.labs.bananadb.entity.serialization.Unmarshaller;
+import org.apache.labs.bananadb.entity.serialization.HashCodeCalculator;
+import org.apache.labs.bananadb.store.Accessor;
+import org.apache.labs.bananadb.store.lock.Lock;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.nio.charset.Charset;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,29 +36,400 @@
* Date: 2008-jul-23
* Time: 02:33:45
*/
-public class PrimaryIndex<PK, T> extends AbstractIndex<PK, T> {
+public class PrimaryIndex<K, E> extends AbstractIndex<K, E> {
+
+ private EntityStore entityStore;
+
+ private Marshaller keyMarshaller;
+ private Unmarshaller keyUnmarshaller;
+ private HashCodeCalculator keyHashCodeCalculator;
+ private Marshaller entityMarshaller;
+ private Unmarshaller entityUnmarshaller;
+
+ private Class<K> keyClass;
+ private Class<E> entityClass;
+
+ private Method primaryKeyGetter;
+ private Method primaryKeySetter;
+
+ private Sequence<K> primaryKeySequence;
+
+ public PrimaryIndex(EntityStore entityStore, Sequence<K> primaryKeySequence, Method primaryKeyGetter, Method primaryKeySetter, Class<K> keyClass, Class<E> entityClass, Marshaller keyMarshaller, Unmarshaller keyUnmarshaller, HashCodeCalculator keyHashCodeCalculator, Marshaller entityMarshaller, Unmarshaller entityUnmarshaller) {
+ this.entityStore = entityStore;
+
+ this.primaryKeySequence = primaryKeySequence;
+
+ this.primaryKeyGetter = primaryKeyGetter;
+ this.primaryKeySetter = primaryKeySetter;
+
+ this.keyClass = keyClass;
+ this.entityClass = entityClass;
+
+ this.keyMarshaller = keyMarshaller;
+ this.keyUnmarshaller = keyUnmarshaller;
+ this.keyHashCodeCalculator = keyHashCodeCalculator;
+ this.entityMarshaller = entityMarshaller;
+ this.entityUnmarshaller = entityUnmarshaller;
+
+ try {
+ entityClassName = entityClass.getName().getBytes("UTF8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ entityClassNameHashCode = entityClass.getName().hashCode();
+ }
+
+ @SuppressWarnings("unchecked")
+ public E get(Accessor accessor, K key) throws IOException {
+// long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
+// byte[] keyBytes = keyMarshaller.marshall(key);
- public T get(PK key) {
- return null;
+ long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+ byte[] keyBytes = marshalPrimayIndexKey(key);
+
+ byte[] entityBytes = entityStore.get(accessor, keyBytes, keyHashCode);
+ return (E) entityUnmarshaller.unmarshall(entityBytes);
}
- public T put(T entity) {
- return null;
+ public boolean containsKey(Accessor accessor, K key) throws IOException {
+ long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
+ byte[] keyBytes = keyMarshaller.marshall(key);
+ return entityStore.containsKey(accessor, keyBytes, keyHashCode);
+ }
+
+ @SuppressWarnings("unchecked")
+ public E put(Accessor accessor, E entity) 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() + "?");
+ }
+ key = primaryKeySequence.next();
+ setPrimaryKey(entity, key);
+ }
+// long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
+// byte[] keyBytes = keyMarshaller.marshall(key);
+ long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+ byte[] keyBytes = marshalPrimayIndexKey(key);
+
+ byte[] entityBytes = entityMarshaller.marshall(entity);
+ byte[] oldEntityBytes = entityStore.put(accessor, keyBytes, keyHashCode, entityBytes);
+ if (oldEntityBytes == null) {
+ return null;
+ } else {
+ return (E) entityUnmarshaller.unmarshall(oldEntityBytes);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public E remove(Accessor accessor, K key) throws IOException {
+// long keyHashCode = keyHashCodeCalculator.calcualteLongHashCode(key);
+// byte[] keyBytes = keyMarshaller.marshall(key);
+
+ long keyHashCode = calculatePrimaryIndexKeyHashCode(key);
+ byte[] keyBytes = marshalPrimayIndexKey(key);
+
+ byte[] oldEntityBytes = entityStore.remove(accessor, keyBytes, keyHashCode);
+ if (oldEntityBytes == null) {
+ return null;
+ } else {
+ return (E) entityUnmarshaller.unmarshall(oldEntityBytes);
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public K getPrimaryKey(E entity) {
+ try {
+ return (K) primaryKeyGetter.invoke(entity);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
}
- public T remove(PK key) {
- return null;
+ public void setPrimaryKey(E entity, K key) {
+ try {
+ primaryKeySetter.invoke(entity, key);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
}
- public EntityCursor<T> cursor() {
- return null;
+ public EntityCursor<E> cursor() {
+ throw new UnsupportedOperationException();
}
- public EntityCursor<T> cursor(PK start) {
- return null;
+ public EntityCursor<E> cursor(K start) {
+ throw new UnsupportedOperationException();
}
- public EntityCursor<T> cursor(PK start, PK end) {
- return null;
+ public EntityCursor<E> cursor(K start, K end) {
+ throw new UnsupportedOperationException();
}
+
+ public Class<K> getKeyClass() {
+ return keyClass;
+ }
+
+ public Class<E> getEntityClass() {
+ return entityClass;
+ }
+
+ public EntityStore getEntityStore() {
+ return entityStore;
+ }
+
+ public Sequence<K> getPrimaryKeySequence() {
+ return primaryKeySequence;
+ }
+
+
+ // transactional
+
+ public class CachedKey {
+ private byte[] bytes;
+ private int hashCode;
+
+ private CachedKey(K key) throws IOException {
+ bytes = keyMarshaller.marshall(key);
+ hashCode = keyHashCodeCalculator.calcualteIntegerHashCode(key);
+ }
+
+ public K getObject() throws IOException {
+ return (K) keyUnmarshaller.unmarshall(bytes);
+ }
+
+ public int getHashCode() {
+ return hashCode;
+ }
+
+ public PrimaryIndex<K, E> getPrimaryIndex() {
+ return PrimaryIndex.this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CachedKey cachedKey = (CachedKey) o;
+
+ if (hashCode != cachedKey.hashCode) return false;
+ if (!Arrays.equals(bytes, cachedKey.bytes)) return false;
+ if (getPrimaryIndex() != cachedKey.getPrimaryIndex()) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+ }
+
+ public class CachedEntity {
+
+ private byte[] bytes;
+
+ private CachedEntity(E entity) throws IOException {
+ if (entity != null) {
+ bytes = entityMarshaller.marshall(entity);
+ } else {
+ bytes = null;
+ }
+ }
+
+ public E getObject() throws IOException {
+ if (bytes == null) {
+ return null;
+ }
+ return (E) entityUnmarshaller.unmarshall(bytes);
+ }
+
+ public PrimaryIndex<K, E> getPrimaryIndex() {
+ return PrimaryIndex.this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CachedEntity that = (CachedEntity) o;
+
+ if (!Arrays.equals(bytes, that.bytes)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return bytes != null ? Arrays.hashCode(bytes) : 0;
+ }
+ }
+
+
+ public E get(final K key) throws IOException {
+
+ final Transaction txn = getEntityStore().getTxn();
+
+ Lock.With<E> with = new Lock.With<E>(txn.getLock(), txn.getLockWaitTimeoutMilliseconds()) {
+ protected E doBody() throws IOException {
+
+ 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().get(cachedKey).getObject();
+ } else if (txn.getReplaced().containsKey(cachedKey)) {
+ v = (E) txn.getReplaced().get(cachedKey).getObject();
+ } else {
+ v = get(txn.getAccessor(), key);
+ }
+ return v;
+ }
+ };
+ return with.run();
+ }
+
+ public E put(final E entity) throws IOException {
+
+ final Transaction txn = getEntityStore().getTxn();
+
+ Lock.With<E> with = new Lock.With<E>(txn.getLock(), txn.getLockWaitTimeoutMilliseconds()) {
+ protected E doBody() throws IOException {
+
+ K key = getPrimaryKey(entity);
+
+ CachedKey cachedKey = new CachedKey(key);
+ CachedEntity cachedEntity = new CachedEntity(entity);
+
+ 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(txn.getAccessor(), key)) {
+ txn.getReplaced().put(cachedKey, cachedEntity);
+ if (txn.getRemoved().containsKey(cachedKey)) {
+ txn.getRemoved().remove(cachedKey);
+ v = null;
+ } else {
+ v = get(txn.getAccessor(), key);
+ }
+ } else {
+ txn.getCreated().put(cachedKey, cachedEntity);
+ v = null;
+ txn.getRemoved().remove(cachedKey); // todo not needed?
+ }
+ }
+ return v;
+ }
+ };
+ return with.run();
+ }
+
+ public E remove(final K key) throws IOException {
+
+ final Transaction txn = getEntityStore().getTxn();
+
+ Lock.With<E> with = new Lock.With<E>(txn.getLock(), txn.getLockWaitTimeoutMilliseconds()) {
+ protected E doBody() throws IOException {
+
+ 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();
+ } else {
+ v = get(txn.getAccessor(), key);
+ txn.getRemoved().put(cachedKey, new CachedEntity(v));
+ }
+ return v;
+ }
+ };
+ return with.run();
+ }
+
+ public boolean containsKey(final K key) throws IOException {
+
+ final Transaction txn = getEntityStore().getTxn();
+
+ Lock.With<Boolean> with = new Lock.With<Boolean>(txn.getLock(), txn.getLockWaitTimeoutMilliseconds()) {
+ protected Boolean doBody() throws IOException {
+
+ txn.getIsolation().checkVersion(txn);
+
+ CachedKey cachedKey = new CachedKey(key);
+
+ return !txn.getRemoved().containsKey(cachedKey)
+ && (txn.getReplaced().containsKey(cachedKey) || txn.getCreated().containsKey(cachedKey) || containsKey(txn.getAccessor(), key));
+ }
+ };
+ return with.run();
+ }
+
+// public int size() throws IOException {
+//
+// isolation.checkVersion(Transaction.this);
+//
+// Lock.With<Integer> with = new Lock.With<Integer>(lock, lockWaitTimeoutMilliseconds) {
+// protected Integer doBody() throws IOException {
+// int size = entityStore.size(accessor);
+// size += created.size();
+// size += replaced.size();
+// size -= removed.size();
+// size += isolation.getSizeModifier();
+// return size;
+// }
+// };
+// return with.run();
+// }
+
+
+ //
+
+ private final byte[] entityClassName;
+ private final long entityClassNameHashCode;
+
+ private byte[] marshalPrimayIndexKey(K key) throws IOException {
+ byte[] keyBytes = keyMarshaller.marshall(key);
+ byte[] out = new byte[keyBytes.length + entityClassName.length];
+ System.arraycopy(keyBytes, 0, out, 0, keyBytes.length);
+ System.arraycopy(entityClassName, 0, out, keyBytes.length, entityClassName.length);
+ return out;
+ }
+
+ private K unmarshalPrimaryIndexKey(byte[] bytes) throws IOException {
+ return (K)keyUnmarshaller.unmarshall(bytes, 0, bytes.length - entityClassName.length);
+ }
+
+ private long calculatePrimaryIndexKeyHashCode(K key) {
+ long result;
+ result = entityClassNameHashCode << 32;
+ result += keyHashCodeCalculator.calcualteIntegerHashCode(key);
+ return result;
+ }
+
+
+
}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryKey.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryKey.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryKey.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/PrimaryKey.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,9 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,8 +28,9 @@
* Date: 2008-jul-23
* Time: 02:47:59
*/
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
public @interface PrimaryKey {
-
public String sequence() default "[unassigned]";
}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryIndex.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryIndex.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryIndex.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryIndex.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,4 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryKey.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryKey.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryKey.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/SecondaryKey.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,9 @@
-package org.apache.labs.bananadb.index;
+package org.apache.labs.bananadb.entity;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,6 +28,8 @@
* Date: 2008-jul-23
* Time: 02:49:08
*/
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
public @interface SecondaryKey {
public Class otherEndClass();
Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Sequence.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Sequence.java?rev=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Sequence.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Sequence.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,46 @@
+package org.apache.labs.bananadb.entity;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 05:51:45
+ */
+public class Sequence<K> {
+
+ private EntityStore entityStore;
+ private String name;
+
+ public Sequence(EntityStore entityStore, String name) {
+ this.entityStore = entityStore;
+ this.name = name;
+ }
+
+ public K next() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public EntityStore getEntityStore() {
+ return entityStore;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
Added: 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=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/Transaction.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,168 @@
+package org.apache.labs.bananadb.entity;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import org.apache.labs.bananadb.store.lock.Lock;
+import org.apache.labs.bananadb.store.lock.SingleInstanceLockFactory;
+import org.apache.labs.bananadb.store.Accessor;
+import org.apache.labs.bananadb.store.Metadata;
+import org.apache.labs.bananadb.entity.EntityStore;
+import org.apache.labs.bananadb.entity.PrimaryIndex;
+import org.apache.labs.bananadb.entity.isolation.Isolation;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author kalle
+ * @since 2009-mar-14 13:29:29
+ */
+public class Transaction {
+
+ private Lock lock = new SingleInstanceLockFactory().makeLock("transaction");
+ private long lockWaitTimeoutMilliseconds = 60000;
+
+ private Isolation isolation;
+
+ private long commitVersion = 0l;
+
+ private Accessor accessor;
+
+ private Map<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> created;
+ private Map<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> replaced;
+
+ /** contains the value in the hashtable when it was removed */
+ private Map<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> removed;
+
+ private EntityStore entityStore;
+
+ public Transaction(EntityStore entityStore) {
+ this.entityStore = entityStore;
+ isolation = entityStore.getConfiguration().getDefaultIsolation();
+ }
+
+ public void begin() throws IOException {
+ if (accessor != null) {
+ throw new IOException("Transaction has already begun");
+ }
+ accessor = entityStore.createAccessor(false);
+ created = new HashMap<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>();
+ replaced = new HashMap<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>();
+ removed = new HashMap<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>();
+
+ Metadata.Header mdh = new Metadata.Header();
+ accessor.getMetadata().readHeader(mdh);
+ commitVersion = mdh.getCommitVersion();
+ }
+
+ public void commit() throws IOException {
+ Lock.With with = new Lock.With(lock, lockWaitTimeoutMilliseconds) {
+ protected Object doBody() throws IOException {
+ if (accessor == null) {
+ throw new IOException("Transaction is not started");
+ }
+
+ isolation.checkVersion(Transaction.this);
+
+ for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : removed.entrySet()) {
+ e.getKey().getPrimaryIndex().remove(accessor, e.getKey().getObject());
+ }
+ for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : created.entrySet()) {
+ e.getKey().getPrimaryIndex().put(accessor, e.getValue().getObject());
+ }
+ for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : replaced.entrySet()) {
+ e.getKey().getPrimaryIndex().put(accessor, e.getValue().getObject());
+ }
+ accessor.close();
+ accessor = null;
+ created = null;
+ replaced = null;
+ removed = null;
+
+ return null;
+ }
+ };
+ with.run();
+ }
+
+ public void abort() throws IOException {
+ Lock.With with = new Lock.With(lock, lockWaitTimeoutMilliseconds) {
+ protected Object doBody() throws IOException {
+ if (accessor == null) {
+ throw new IOException("Transaction is not started");
+ }
+ accessor = null;
+ created = null;
+ replaced = null;
+ removed = null;
+ return null;
+ }
+ };
+ with.run();
+ }
+
+
+ public long getCommitVersion() {
+ return commitVersion;
+ }
+
+ public Accessor getAccessor() {
+ return accessor;
+ }
+
+ public Map<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> getCreated() {
+ return created;
+ }
+
+ public Map<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> getReplaced() {
+ return replaced;
+ }
+
+ public Map<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> getRemoved() {
+ return removed;
+ }
+
+ public EntityStore getEntityStore() {
+ return entityStore;
+ }
+
+ public void setCommitVersion(long commitVersion) {
+ this.commitVersion = commitVersion;
+ }
+
+ public Isolation getIsolation() {
+ return isolation;
+ }
+
+ public void setIsolation(Isolation isolation) {
+ this.isolation = isolation;
+ }
+
+ Lock getLock() {
+ return lock;
+ }
+
+ public long getLockWaitTimeoutMilliseconds() {
+ return lockWaitTimeoutMilliseconds;
+ }
+
+ public void setLockWaitTimeoutMilliseconds(long lockWaitTimeoutMilliseconds) {
+ this.lockWaitTimeoutMilliseconds = lockWaitTimeoutMilliseconds;
+ }
+}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/AbstractIsolation.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/AbstractIsolation.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/AbstractIsolation.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/AbstractIsolation.java Tue Mar 17 10:14:03 2009
@@ -1,10 +1,10 @@
-package org.apache.labs.bananadb.hashtable.txn;
+package org.apache.labs.bananadb.entity.isolation;
/**
* @author kalle
* @since 2009-mar-14 16:24:29
*/
-public abstract class AbstractIsolation<K, V> implements Isolation<K, V> {
+public abstract class AbstractIsolation implements Isolation {
public int getSizeModifier() {
return 0;
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/DeadlockException.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/DeadlockException.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/DeadlockException.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/DeadlockException.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,4 @@
-package org.apache.labs.bananadb.hashtable.txn;
+package org.apache.labs.bananadb.entity.isolation;
import java.io.IOException;
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/Isolation.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/Isolation.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/Isolation.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/Isolation.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,6 @@
-package org.apache.labs.bananadb.hashtable.txn;
+package org.apache.labs.bananadb.entity.isolation;
+
+import org.apache.labs.bananadb.entity.Transaction;
import java.io.IOException;
@@ -25,9 +27,9 @@
* @author kalle
* @since 2009-mar-14 15:39:32
*/
-public interface Isolation<K, V> {
+public interface Isolation {
- public abstract void checkVersion(Transaction<K, V> txn) throws IOException;
+ public abstract void checkVersion(Transaction txn) throws IOException;
public abstract int getSizeModifier();
}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationDeadlocking.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationDeadlocking.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationDeadlocking.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationDeadlocking.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,8 @@
-package org.apache.labs.bananadb.hashtable.txn;
+package org.apache.labs.bananadb.entity.isolation;
+
+import org.apache.labs.bananadb.store.Metadata;
+import org.apache.labs.bananadb.entity.PrimaryIndex;
+import org.apache.labs.bananadb.entity.Transaction;
import java.io.IOException;
import java.util.Iterator;
@@ -10,27 +14,35 @@
* @author kalle
* @since 2009-mar-14 15:40:40
*/
-public class IsolationDeadlocking<K, V> extends AbstractIsolation<K, V> {
+public class IsolationDeadlocking extends AbstractIsolation {
+
+ public void checkVersion(Transaction txn) throws IOException {
+
+ Metadata.Header mdh = new Metadata.Header();
+ txn.getAccessor().getMetadata().readHeader(mdh);
+
+ if (txn.getCommitVersion() != mdh.getCommitVersion()) {
- public void checkVersion(Transaction<K, V> txn) throws IOException {
- org.apache.labs.bananadb.hashtable.Hashtable.KeyPostingsFileHeader keyPostingsFileHeader = txn.getHashtable().new KeyPostingsFileHeader(txn.getAccessor());
- if (txn.getHashtableVersion() != keyPostingsFileHeader.getVersion()) {
+ txn.setCommitVersion(mdh.getCommitVersion());
- txn.setHashtableVersion(keyPostingsFileHeader.getVersion());
+ Set<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> deadlocks = new HashSet<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>>();
- Set<Map.Entry<K, V>> deadlocks = new HashSet<Map.Entry<K, V>>();
+ for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : txn.getRemoved().entrySet()) {
- for (Map.Entry<K, V> e : txn.getRemoved().entrySet()) {
- boolean contains = txn.getHashtable().containsKey(txn.getAccessor(), e.getKey());
+ Object key = e.getKey().getObject();
+ Object entity = e.getValue().getObject();
+
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ boolean contains = primaryIndex.containsKey(txn.getAccessor(), key);
if (!contains) {
deadlocks.add(e);
} else {
- V v = txn.getHashtable().get(txn.getAccessor(), e.getKey());
- if (v == null && e.getValue() != null) {
+ Object v = primaryIndex.get(txn.getAccessor(), entity);
+ if (v == null && e.getValue().getObject() != null) {
deadlocks.add(e);
- } else if (v != null && e.getValue() == null) {
+ } else if (v != null && entity == null) {
deadlocks.add(e);
- } else if (v != null && e.getValue() != null && !v.equals(e.getValue())) {
+ } else if (v != null && entity != null && !v.equals(entity)) {
deadlocks.add(e);
}
}
@@ -38,30 +50,36 @@
if (deadlocks.size() > 0) {
StringBuilder sb = new StringBuilder();
- for (Map.Entry<K, V> e : deadlocks) {
+ for (Map.Entry e : deadlocks) {
if (sb.length() > 0) {
sb.append("; ");
}
- sb.append(e.getKey().toString());
+ sb.append(e.getKey().toString());
}
throw new DeadlockException("Some of the keys removed in this transaction was removed from the hashtable while the transaction was running: " + sb.toString());
}
- Set<K> moved = new HashSet<K>();
- for (Iterator<Map.Entry<K, V>> it = txn.getCreated().entrySet().iterator(); it.hasNext();) {
- Map.Entry<K, V> e = it.next();
- if (txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
+ Set<PrimaryIndex.CachedKey> moved = new HashSet<PrimaryIndex.CachedKey>();
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getCreated().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ Object key = e.getKey().getObject();
+
+ if (primaryIndex.containsKey(txn.getAccessor(), key)) {
txn.getReplaced().put(e.getKey(), e.getValue());
moved.add(e.getKey());
it.remove();
}
}
- for (Iterator<Map.Entry<K, V>> it = txn.getReplaced().entrySet().iterator(); it.hasNext();) {
- Map.Entry<K, V> e = it.next();
- if (!moved.contains(e.getKey()) && !txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
- txn.getCreated().put(e.getKey(), e.getValue());
- it.remove();
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getReplaced().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (!moved.contains(e.getKey())) {
+ if (!primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
+ txn.getCreated().put(e.getKey(), e.getValue());
+ it.remove();
+ }
}
}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationLastCommitWins.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationLastCommitWins.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationLastCommitWins.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationLastCommitWins.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,8 @@
-package org.apache.labs.bananadb.hashtable.txn;
+package org.apache.labs.bananadb.entity.isolation;
+
+import org.apache.labs.bananadb.store.Metadata;
+import org.apache.labs.bananadb.entity.PrimaryIndex;
+import org.apache.labs.bananadb.entity.Transaction;
import java.io.IOException;
import java.util.Iterator;
@@ -10,42 +14,50 @@
* @author kalle
* @since 2009-mar-14 15:40:40
*/
-public class IsolationLastCommitWins<K, V> extends AbstractIsolation<K, V> {
+public class IsolationLastCommitWins extends AbstractIsolation {
private int sizeModifier = 0;
- public void checkVersion(Transaction<K, V> txn) throws IOException {
- org.apache.labs.bananadb.hashtable.Hashtable.KeyPostingsFileHeader keyPostingsFileHeader = txn.getHashtable().new KeyPostingsFileHeader(txn.getAccessor());
- if (txn.getHashtableVersion() != keyPostingsFileHeader.getVersion()) {
+ public void checkVersion(Transaction txn) throws IOException {
+
+ Metadata.Header mdh = new Metadata.Header();
+ txn.getAccessor().getMetadata().readHeader(mdh);
- txn.setHashtableVersion(keyPostingsFileHeader.getVersion());
+ if (txn.getCommitVersion() != mdh.getCommitVersion()) {
+
+ txn.setCommitVersion(mdh.getCommitVersion());
// todo if this contains a deleted entity and the entity already is deleted in the hashtable
// todo then the size is -1 off per such occurance.
int removedConflicts = 0;
- for (Map.Entry<K, V> e : txn.getRemoved().entrySet()) {
- if (!txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
+ for (Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e : txn.getRemoved().entrySet()) {
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (!primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
removedConflicts++;
}
}
this.sizeModifier = removedConflicts;
- Set<K> moved = new HashSet<K>();
- for (Iterator<Map.Entry<K, V>> it = txn.getCreated().entrySet().iterator(); it.hasNext();) {
- Map.Entry<K, V> e = it.next();
- if (txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
+ Set<PrimaryIndex.CachedKey> moved = new HashSet<PrimaryIndex.CachedKey>();
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getCreated().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
txn.getReplaced().put(e.getKey(), e.getValue());
moved.add(e.getKey());
it.remove();
}
}
- for (Iterator<Map.Entry<K, V>> it = txn.getReplaced().entrySet().iterator(); it.hasNext();) {
- Map.Entry<K, V> e = it.next();
- if (!moved.contains(e.getKey()) && !txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
- txn.getCreated().put(e.getKey(), e.getValue());
- it.remove();
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getReplaced().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ if (!moved.contains(e.getKey())) {
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (!primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
+ txn.getCreated().put(e.getKey(), e.getValue());
+ it.remove();
+ }
}
}
Modified: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationUpdated.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationUpdated.java?rev=755179&r1=754666&r2=755179&view=diff
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationUpdated.java (original)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/isolation/IsolationUpdated.java Tue Mar 17 10:14:03 2009
@@ -1,4 +1,8 @@
-package org.apache.labs.bananadb.hashtable.txn;
+package org.apache.labs.bananadb.entity.isolation;
+
+import org.apache.labs.bananadb.store.Metadata;
+import org.apache.labs.bananadb.entity.PrimaryIndex;
+import org.apache.labs.bananadb.entity.Transaction;
import java.io.IOException;
import java.util.Iterator;
@@ -10,39 +14,47 @@
* @author kalle
* @since 2009-mar-14 15:40:40
*/
-public class IsolationUpdated<K, V> extends AbstractIsolation<K, V> {
+public class IsolationUpdated extends AbstractIsolation {
+
+ public void checkVersion(Transaction txn) throws IOException {
+
+ Metadata.Header mdh = new Metadata.Header();
+ txn.getAccessor().getMetadata().readHeader(mdh);
- public void checkVersion(Transaction<K, V> txn) throws IOException {
- org.apache.labs.bananadb.hashtable.Hashtable.KeyPostingsFileHeader keyPostingsFileHeader = txn.getHashtable().new KeyPostingsFileHeader(txn.getAccessor());
- if (txn.getHashtableVersion() != keyPostingsFileHeader.getVersion()) {
+ if (txn.getCommitVersion() != mdh.getCommitVersion()) {
- txn.setHashtableVersion(keyPostingsFileHeader.getVersion());
+ txn.setCommitVersion(mdh.getCommitVersion());
- for (Iterator<K> it = txn.getRemoved().keySet().iterator(); it.hasNext();) {
- K key = it.next();
- if (!txn.getHashtable().containsKey(txn.getAccessor(), key)) {
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getRemoved().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (!primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
it.remove();
}
}
- Set<K> moved = new HashSet<K>();
- for (Iterator<Map.Entry<K, V>> it = txn.getCreated().entrySet().iterator(); it.hasNext();) {
- Map.Entry<K, V> e = it.next();
- if (txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
+ Set<PrimaryIndex.CachedKey> moved = new HashSet<PrimaryIndex.CachedKey>();
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getCreated().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
txn.getReplaced().put(e.getKey(), e.getValue());
moved.add(e.getKey());
it.remove();
}
}
- for (Iterator<Map.Entry<K, V>> it = txn.getReplaced().entrySet().iterator(); it.hasNext();) {
- Map.Entry<K, V> e = it.next();
- if (!moved.contains(e.getKey()) && !txn.getHashtable().containsKey(txn.getAccessor(), e.getKey())) {
- txn.getCreated().put(e.getKey(), e.getValue());
- it.remove();
+ for (Iterator<Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity>> it = txn.getReplaced().entrySet().iterator(); it.hasNext();) {
+ Map.Entry<PrimaryIndex.CachedKey, PrimaryIndex.CachedEntity> e = it.next();
+ if (!moved.contains(e.getKey())) {
+ PrimaryIndex primaryIndex = e.getKey().getPrimaryIndex();
+ if (!primaryIndex.containsKey(txn.getAccessor(), e.getKey().getObject())) {
+ txn.getCreated().put(e.getKey(), e.getValue());
+ it.remove();
+ }
}
}
-
+
}
}
Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/FallBackHashCodeCalculator.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/FallBackHashCodeCalculator.java?rev=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/FallBackHashCodeCalculator.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/FallBackHashCodeCalculator.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,36 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * Uses {@link Object#hashCode()}.
+ *
+ * @author kalle
+ * @since 2009-mar-17 06:32:30
+ */
+public class FallBackHashCodeCalculator extends HashCodeCalculator {
+
+ public long calcualteLongHashCode(Object object) {
+ return calcualteIntegerHashCode(object);
+ }
+
+ public int calcualteIntegerHashCode(Object object) {
+ return object.hashCode();
+ }
+}
Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/HashCodeCalculator.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/HashCodeCalculator.java?rev=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/HashCodeCalculator.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/HashCodeCalculator.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,30 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 03:59:08
+ */
+public abstract class HashCodeCalculator {
+
+ public abstract long calcualteLongHashCode(Object object);
+ public abstract int calcualteIntegerHashCode(Object object);
+
+}
Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Marshaller.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Marshaller.java?rev=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Marshaller.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Marshaller.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,32 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import java.io.IOException;
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 03:44:55
+ */
+public abstract class Marshaller {
+
+ public abstract byte[] marshall(Object object) throws IOException;
+
+
+}
Added: 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=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableMarshaller.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,37 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import java.io.*;
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 06:34:08
+ */
+public class SerializableMarshaller extends Marshaller {
+
+ public byte[] marshall(Object object) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(object);
+ oos.close();
+ return baos.toByteArray();
+ }
+
+}
\ No newline at end of file
Added: 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=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializableUnmarshaller.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,40 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import java.io.*;
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 06:34:08
+ */
+public class SerializableUnmarshaller extends Unmarshaller {
+
+ public Serializable unmarshall(byte[] bytes, int startOffset, int length) throws IOException {
+ ObjectInputStream oos = new ObjectInputStream(new ByteArrayInputStream(bytes, startOffset, length));
+ Serializable object;
+ try {
+ object = (Serializable) oos.readObject();
+ } catch (ClassNotFoundException e) {
+ throw new IOException(e);
+ }
+ oos.close();
+ return object;
+ }
+}
Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializationRegistry.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializationRegistry.java?rev=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializationRegistry.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/SerializationRegistry.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,106 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 04:16:12
+ */
+public class SerializationRegistry {
+
+ private Map<Class, Marshaller> marshallers = new HashMap<Class, Marshaller>();
+ private Map<Class, Unmarshaller> unmarshallers = new HashMap<Class, Unmarshaller>();
+ private Map<Class, HashCodeCalculator> hashCodeCalculators = new HashMap<Class, HashCodeCalculator>();
+
+ public SerializationRegistry() {
+ }
+
+ public Marshaller getMarshaller(Class type) {
+ Marshaller marshaller;
+ for (Class _class : getAllClasses(type)) {
+ if ((marshaller = marshallers.get(_class)) != null) {
+ return marshaller;
+ }
+ }
+ throw new IllegalArgumentException("No applicable marshaller found for class " + type.getName());
+ }
+
+
+ public Unmarshaller getUnmarshaller(Class type) {
+ Unmarshaller unmarshaller;
+ for (Class _class : getAllClasses(type)) {
+ if ((unmarshaller = unmarshallers.get(_class)) != null) {
+ return unmarshaller;
+ }
+ }
+ throw new IllegalArgumentException("No applicable unmarshaller found for class " + type.getName());
+ }
+
+ public HashCodeCalculator getHashCodeCalcualtor(Class type) {
+ HashCodeCalculator calculator;
+ for (Class _class : getAllClasses(type)) {
+ if ((calculator = hashCodeCalculators.get(_class)) != null) {
+ return calculator;
+ }
+ }
+ throw new IllegalArgumentException("No applicable hash code calculator found for class " + type.getName());
+ }
+
+ private List<Class> getAllClasses(Class type) {
+ List<Class> all = new ArrayList<Class>();
+ all.add(type);
+ Class tmp = type;
+ while ((tmp = tmp.getSuperclass()) != Object.class) {
+ all.add(tmp);
+ }
+ all.add(Object.class);
+
+ List<Class> allInterfaces = new ArrayList<Class>();
+ for (Class tmp2 : all) {
+ addInterfaces(tmp2, allInterfaces);
+ }
+
+ all.addAll(allInterfaces);
+ return all;
+ }
+
+ private void addInterfaces(Class _class, List<Class> all) {
+ for (Class _interface : _class.getInterfaces()) {
+ all.add(_interface);
+ addInterfaces(_interface, all);
+ }
+ }
+
+ public Map<Class, Marshaller> getMarshallers() {
+ return marshallers;
+ }
+
+ public Map<Class, Unmarshaller> getUnmarshallers() {
+ return unmarshallers;
+ }
+
+ public Map<Class, HashCodeCalculator> getHashCodeCalculators() {
+ return hashCodeCalculators;
+ }
+}
Added: labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Unmarshaller.java
URL: http://svn.apache.org/viewvc/labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Unmarshaller.java?rev=755179&view=auto
==============================================================================
--- labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Unmarshaller.java (added)
+++ labs/bananadb/trunk/src/main/java/org/apache/labs/bananadb/entity/serialization/Unmarshaller.java Tue Mar 17 10:14:03 2009
@@ -0,0 +1,33 @@
+package org.apache.labs.bananadb.entity.serialization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @author kalle
+ * @since 2009-mar-17 03:58:21
+ */
+public abstract class Unmarshaller {
+
+ public Object unmarshall(byte[] bytes) throws java.io.IOException {
+ return unmarshall(bytes, 0, bytes.length);
+ }
+
+ public abstract Object unmarshall(byte[] bytes, int startOffset, int length) throws java.io.IOException;
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org