*** empty log message ***
authornavid <navid>
Thu, 22 Jan 2009 06:25:24 +0000 (06:25 +0000)
committernavid <navid>
Thu, 22 Jan 2009 06:25:24 +0000 (06:25 +0000)
Robust/Transactions/TransactionalIO/src/TransactionalIO/core/TransactionalFile.java
Robust/Transactions/dstm2/src/dstm2/AtomicByteArray.java
Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/PagedIndex.java
Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/RowTransactional.java [new file with mode: 0644]
Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java
Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/ValueTransactional.java [new file with mode: 0644]

index b7b611a45acd7425fef4cc7c9ab13a5b27c9af59..e54efa930b2483754a64f102133e674a94e8655b 100644 (file)
@@ -211,6 +211,7 @@ public class TransactionalFile implements Comparable {
             if (!(this.inodestate.commitedfilesize.getLengthReaders().contains(me))) {
                 this.inodestate.commitedfilesize.getLengthReaders().add(me);
             }
             if (!(this.inodestate.commitedfilesize.getLengthReaders().contains(me))) {
                 this.inodestate.commitedfilesize.getLengthReaders().add(me);
             }
+        
            tmp.setLocalsize(this.inodestate.commitedfilesize.getLength());
            tmp.lenght_read = true;
         
            tmp.setLocalsize(this.inodestate.commitedfilesize.getLength());
            tmp.lenght_read = true;
         
index d81ec46c5d714d7bdb388f65161065574c65842d..e04f00d182d2495a6d405223d8f8618edcc52961 100644 (file)
@@ -60,6 +60,10 @@ import java.lang.reflect.Array;
     version = 0;
   }
   
     version = 0;
   }
   
+  public int length(){
+      return array.length;
+  }
+  
   public Byte get(int i) {
     Transaction me  = Thread.getTransaction();
     Transaction other = null;
   public Byte get(int i) {
     Transaction me  = Thread.getTransaction();
     Transaction other = null;
index f200fa9b42bb2c06996423588a7ead80f141442f..914f41ff3a99cdb35a7dff650f31dae65d019b16 100644 (file)
  
 package com.solidosystems.tuplesoup.core;
 
  
 package com.solidosystems.tuplesoup.core;
 
+import dstm2.AtomicArray;
+import dstm2.atomic;
 import java.io.*;
 import java.util.*;
 import java.nio.channels.*;
 
 public class PagedIndex implements TableIndex{
 import java.io.*;
 import java.util.*;
 import java.nio.channels.*;
 
 public class PagedIndex implements TableIndex{
+    
+    public @atomic interface PageIndexTSInf{
+       Long getStat_read();
+       Long getStat_write();
+       Long getStat_create_page();
+       Long getStat_page_next();
+       Long getStat_page_branch();
+       AtomicArray<TableIndexPageTransactional> getRoots();
+       
+       void setRoots(AtomicArray<TableIndexPageTransactional> roots);
+       void setStat_read(Long val);
+       void setStat_write(Long val);
+       void setStat_create_page(Long val);
+       void setStat_page_next(Long val);
+       void setStat_page_branch(Long val);
+    }
+    
     protected static final int INITIALPAGEHASH=1024;
     protected static final int PAGESIZE=2048;
     
     private RandomAccessFile out=null;
     private String filename;
     private TableIndexPage[] root=null;
     protected static final int INITIALPAGEHASH=1024;
     protected static final int PAGESIZE=2048;
     
     private RandomAccessFile out=null;
     private String filename;
     private TableIndexPage[] root=null;
+   // private TableIndexPageTransactional[] root=null;
     
     private long stat_read=0;
     private long stat_write=0;
     
     private long stat_read=0;
     private long stat_write=0;
diff --git a/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/RowTransactional.java b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/RowTransactional.java
new file mode 100644 (file)
index 0000000..7668508
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.solidosystems.tuplesoup.core;
+
+import dstm2.atomic;
+import dstm2.util.HashMap;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Set;
+/**
+ *
+ * @author navid
+ */
+public class RowTransactional {
+     private String id;
+     private int size;
+     private HashMap<ValueTransactional> values;
+     
+     public @atomic interface RowTSInf{
+        
+     }
+     
+     public RowTransactional(String id){
+         this.id=id;
+         size=-1;
+         values=new HashMap<ValueTransactional>();
+     }
+     
+     /**
+      * Returns the number of keys in this row.
+      */
+     public int getKeyCount(){
+         return values.size();
+     }
+     
+     public Set keySet(){
+         return values.entrySet();
+     }
+     
+     /**
+      * Returns the actual size in bytes this row will take when written to a stream.
+      */
+     public int getSize(){
+         if(size==-1)recalcSize();
+         return size;
+     }
+
+     /**
+      * Returns a hashcode for this row. This hashcode will be based purely on the id of the row.
+      */
+     public int hashCode(){
+         return id.hashCode();
+     }
+     public boolean equals(Object obj){
+         try{
+             RowTransactional r=(RowTransactional)obj;
+             return r.id.equals(id);
+         }catch(Exception e){}
+         return false;
+     }
+     /**
+      * Returns the id of this row.
+      */
+     public String getId(){
+         return id;
+     }
+     /**
+      * Stores the given value for the given key.
+      */
+     public void put(String key,ValueTransactional value){
+         size=-1;
+         values.put(key.hashCode(),value);
+     }
+     
+     /**
+      * Stores the given string wrapped in a value object for the given key.
+      */
+     public void put(String key,String value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Stores the given int wrapped in a value object for the given key.
+      */
+     public void put(String key,int value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Stores the given long wrapped in a value object for the given key.
+      */
+     public void put(String key,long value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Stores the given float wrapped in a value object for the given key.
+      */
+     public void put(String key,float value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Stores the given double wrapped in a value object for the given key.
+      */
+     public void put(String key,double value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Stores the given boolean wrapped in a value object for the given key.
+      */
+     public void put(String key,boolean value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Stores the given Date wrapped in a value object for the given key.
+      */
+     public void put(String key,Date value){
+         size=-1;
+         values.put(key.hashCode(),new ValueTransactional(value));
+     }
+     
+     /**
+      * Returns the value stored for the current key, or a null value (not null) if the key does not exist.
+      */
+     public ValueTransactional get(String key){
+         if(!values.containsKey(key.hashCode()))return new ValueTransactional();
+         return values.get(key.hashCode());
+     }
+     
+     /**
+      * Returns a string representation of the value stored for the current key.
+      * If the key does not exist, an empty string will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public String getString(String key){
+         if(!values.containsKey(key.hashCode()))return "";
+         return values.get(key.hashCode()).getString();
+     }
+     
+     /**
+      * Returns an int representation of the value stored for the current key.
+      * If the key does not exist, 0 will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public int getInt(String key){
+         if(!values.containsKey(key.hashCode()))return 0;
+          return values.get(key.hashCode()).getInt();
+     }
+     
+     /**
+      * Returns a long representation of the value stored for the current key.
+      * If the key does not exist, 0 will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public long getLong(String key){
+         if(!values.containsKey(key.hashCode()))return 0;
+          return values.get(key.hashCode()).getLong();
+     }
+     
+     /**
+      * Returns a float representation of the value stored for the current key.
+      * If the key does not exist, 0 will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public float getFloat(String key){
+         if(!values.containsKey(key.hashCode()))return 0f;
+          return values.get(key.hashCode()).getFloat();
+     }
+     
+     /**
+      * Returns a double representation of the value stored for the current key.
+      * If the key does not exist, 0 will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public double getDouble(String key){
+         if(!values.containsKey(key.hashCode()))return 0d;
+          return values.get(key.hashCode()).getDouble();
+     }
+     
+     /**
+      * Returns a boolean representation of the value stored for the current key.
+      * If the key does not exist, false will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public boolean getBoolean(String key){
+         if(!values.containsKey(key.hashCode()))return false;
+          return values.get(key.hashCode()).getBoolean();
+     }
+     
+     /**
+      * Returns a Date representation of the value stored for the current key.
+      * If the key does not exist, the date initialized with 0 will be returned.
+      * See the documentation for Value to learn how the string value is generated.
+      */
+     public Date getTimestamp(String key){
+         if(!values.containsKey(key.hashCode()))return new Date(0);
+          return values.get(key.hashCode()).getTimestamp();
+      }
+     /**
+      * Utility function to calculate the distance between ints, allowing for a single wraparound.
+      */
+     protected static int calcSize(int pre,int post){
+         if(post>pre)return post-pre;
+         return (Integer.MAX_VALUE-pre)+post;
+     }
+    
+     /**
+      * Recalculate the size of the row. Be aware that this method will actually write the full row to a buffer to calculate the size.
+      * Its a slow and memory consuming method to call!
+      */
+     private void recalcSize(){
+         try{
+             ByteArrayOutputStream bout=new ByteArrayOutputStream();
+             DataOutputStream dout=new DataOutputStream(bout);
+             writeToStream(dout);
+             size=bout.size();
+             dout.close();
+             bout.close();
+         }catch(Exception e){}
+     }
+    
+     /**
+      * Writes the contents of this row to the given RandomAccessFile
+      */
+     public void writeToFile(RandomAccessFile out) throws IOException{
+          long pre=out.getFilePointer();
+          
+          out.writeUTF(id);
+          
+          Set keys=values.keySet();
+          out.writeInt(keys.size());
+          Iterator<String> it=keys.iterator();
+          while(it.hasNext()){
+             Integer key= (Integer)it.next();
+             ValueTransactional value=values.get(key.hashCode());
+             out.writeUTF(key);
+             value.writeToFile(out);
+          }
+          long post=out.getFilePointer();
+          int size=(int)(post-pre);
+          this.size=size+4;
+          out.writeInt(this.size);
+      }
+      /**
+       * Writes the contents of this row to the given DataOutputStream.
+       */
+      public void writeToStream(DataOutputStream out) throws IOException{
+         int pre=out.size();
+         out.writeUTF(id);
+         Set<String> keys=values.keySet();
+         out.writeInt(keys.size());
+         Iterator<String> it=keys.iterator();
+         while(it.hasNext()){
+             String key=it.next();
+             ValueTransactional value=values.get(key.hashCode());
+             out.writeUTF(key);
+             value.writeToStream(out);
+         }
+         int post=out.size();
+         int size=calcSize(pre,post);
+         this.size=size+4;
+         out.writeInt(this.size);
+     }
+     /**
+      * Reads a full row from the given DataInputStream and returns it.
+      */
+     public static Row readFromStream(DataInputStream in) throws IOException{
+         String id=in.readUTF();
+         Row row=new Row(id);
+         int size=in.readInt();
+         for(int i=0;i<size;i++){
+             String key=in.readUTF();
+             Value value=Value.readFromStream(in);
+             row.put(key,value);
+         }
+         size=in.readInt();
+         row.size=size;
+         return row;
+     }
+     /**
+      * Returns a string representing this row formatted as the following example:
+      * (1732)=>{"name":string:"Kasper J. Jeppesen","age":int:31}
+      *
+      * @return a string representation of this row
+      */
+     public String toString(){
+         StringBuffer buf=new StringBuffer();
+         buf.append("("+id+")=>{");
+         Iterator<String> it=values.keySet().iterator();
+         boolean first=true;
+         while(it.hasNext()){
+             if(!first){
+                 buf.append(",");
+             }else{
+                 first=false;
+             }
+              key=it.next();
+             buf.append("\"");
+             buf.append(key);
+             buf.append("\":");
+             Value value=values.get(key);
+             buf.append(value.getTypeName());
+             buf.append(":");
+             if(value.getType()==Value.STRING){
+                buf.append("\"");
+                // TODO: This string should be escaped properly
+                buf.append(value.getString());
+                buf.append("\"");
+             }else{
+                 buf.append(value.getString());
+             }
+         }
+         buf.append("}");
+         return buf.toString();
+     }
+     
+     /**
+      * Shorthand for calling toBasicXMLString("")
+      */
+     public String toBasicXMLString(){
+         return toBasicXMLString("");
+     }
+     
+     /**
+      * Creates an indentation of the given size and calls toBasicXMLString(String) with the indentation string as parameter.
+      */
+     public String toBasicXMLString(int indentation){
+         StringBuffer buf=new StringBuffer();
+         for(int i=0;i<indentation;i++){
+             buf.append(" ");
+         }
+         return toBasicXMLString(buf.toString());
+     }
+     
+     /**
+      * Creates a basic xml representation of the row as shown in the following sample:
+      * &lt;row id="1"&gt;
+      *   &lt;value name="foo" type="string"&gt;Bar&lt;/value&gt;
+      * &lt;/row&gt;
+      */
+     public String toBasicXMLString(String indentation){
+         StringBuffer buf=new StringBuffer();
+         buf.append(indentation);
+         buf.append("<row id=\""+id+"\">\n");
+         Iterator it=values.entrySet().iterator();
+         while(it.hasNext()){
+             String key=(String)it.next();
+             ValueTransactional value=values.get(key.hashCode());
+             buf.append(indentation);
+             buf.append("   ");
+             buf.append(value.toBasicXMLString(key));
+             buf.append("\n");
+         }
+         buf.append(indentation);
+         buf.append("</row>\n");
+         return buf.toString();
+     }
+
+}
index 9385902d4c160d0a583d00c4eb851d121b32fc45..23a251055a65f6195d236c26da25add0b5eec644 100644 (file)
  * POSSIBILITY OF SUCH DAMAGE.
  */
  
  * POSSIBILITY OF SUCH DAMAGE.
  */
  
-package com.solidosystems.tuplesoup.core;
+/*package com.solidosystems.tuplesoup.core;
 
 
+import TransactionalIO.core.TransactionalFile;
+import dstm2.AtomicSuperClass;
+import dstm2.atomic;
 import java.io.*;
 import java.util.*;
 
 import java.io.*;
 import java.util.*;
 
-public class TableIndexPageTransactional{
+public class TableIndexPageTransactional implements AtomicSuperClass{
+    TableIndexPageTSInf atomicfields;
+    private final static int BASEOFFSET=4+8+8+4+4;
+    //private RandomAccessFile file=null;
+    private TransactionalFile file = null;
+    
     public @atomic interface TableIndexPageTSInf{
         Long getLocation();
         Integer getSize();
     public @atomic interface TableIndexPageTSInf{
         Long getLocation();
         Integer getSize();
@@ -59,8 +67,7 @@ public class TableIndexPageTransactional{
         void setLocation(Long location);
         void setLower(Long val);
     }
         void setLocation(Long location);
         void setLower(Long val);
     }
-    private final static int BASEOFFSET=4+8+8+4+4;
-    private RandomAccessFile file=null;
+  
     
     private long location=-1;
     private int size=-1;
     
     private long location=-1;
     private int size=-1;
@@ -77,7 +84,7 @@ public class TableIndexPageTransactional{
     
     private PagedIndex index=null;
     
     
     private PagedIndex index=null;
     
-    public TableIndexPageTransactional(PagedIndex index,RandomAccessFile file) throws IOException{
+    public TableIndexPageTransactional(PagedIndex index,TransactionalFile file) throws IOException{
         this.file=file;
         this.index=index;
         first=false;
         this.file=file;
         this.index=index;
         first=false;
@@ -281,4 +288,4 @@ public class TableIndexPageTransactional{
         if(id.hashCode()>endhash)endhash=id.hashCode();
         updateMeta();
     }
         if(id.hashCode()>endhash)endhash=id.hashCode();
         updateMeta();
     }
-}
\ No newline at end of file
+}*/
\ No newline at end of file
diff --git a/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/ValueTransactional.java b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/ValueTransactional.java
new file mode 100644 (file)
index 0000000..f3be982
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.solidosystems.tuplesoup.core;
+
+import dstm2.AtomicByteArray;
+import dstm2.AtomicSuperClass;
+import dstm2.atomic;
+import java.util.*;
+ import java.io.*;
+
+/**
+ *
+ * @author navid
+ */
+public class ValueTransactional implements AtomicSuperClass{
+
+     ValueTSInf atomicfields;
+     
+     public @atomic interface ValueTSInf{
+         byte getType();
+         String getStr_value();
+         long getInt_value();
+         double getFloat_value();
+         AtomicByteArray getBinary();
+         
+         void setType(byte val);
+         void setStr_value(String val);
+         void setInt_value(long val);
+         void setFloat_value(double val);
+         void setBinary(AtomicByteArray bytes);
+     }   
+     
+     
+     public final static int NULL=0;
+     public final static int STRING=1;
+     public final static int INT=2;
+     public final static int LONG=3;
+     public final static int FLOAT=4;
+     public final static int DOUBLE=5;
+     public final static int BOOLEAN=6;
+     public final static int TIMESTAMP=7;
+     public final static int BINARY=8;
+
+  /*   private byte type=NULL; // The type of the value being held
+     private String str_value=null;
+     private long int_value=0;
+     private double float_value=0.0;
+     private byte[] binary=null;*/
+
+     /**
+      * Returns the numerical type id for this value.
+      */
+     public int getType(){
+         return atomicfields.getType();
+     }
+     
+     /**
+      * Returns the name this value's type.
+      */
+     public String getTypeName(){
+         switch(atomicfields.getType()){
+              case STRING     : return "string";
+              case INT        : return "int";
+              case LONG       : return "long";
+              case FLOAT      : return "float";
+              case DOUBLE     : return "double";
+              case BOOLEAN    : return "boolean";
+              case TIMESTAMP  : return "timestamp";
+              case BINARY     : return "binary";
+          }
+          return "null";
+     }
+
+     /**
+      * An implementation of the hashCode method as defined in java.lang.Object
+      * 
+      * @return a hash code value for this object
+      */
+     public int hashCode(){
+         int hash=0;
+         switch(atomicfields.getType()){
+             case STRING     : hash+=atomicfields.getStr_value().hashCode();
+             case INT        : hash+=(int)atomicfields.getInt_value();
+             case LONG       : hash+=(int)atomicfields.getInt_value();
+             case FLOAT      : hash+=(int)atomicfields.getFloat_value();
+             case DOUBLE     : hash+=(int)atomicfields.getFloat_value();
+             case BOOLEAN    : hash+=(int)atomicfields.getInt_value();
+             case TIMESTAMP  : hash+=(int)atomicfields.getInt_value();
+             case BINARY     : hash+=atomicfields.getBinary().hashCode();
+         }
+         return hash;
+     }
+
+     /**
+      * Returns true only if this Value has specifically been set to null.
+      *
+      * @return true if the data being held is null, false otherwise
+      */
+     public boolean isNull(){
+         return atomicfields.getType()==NULL;
+     }
+
+     /**
+      * Returns -1, 0 or 1 if this value is smaller, equal or larger than the value given as a parameter.
+      */
+     public int compareTo(ValueTransactional value){
+         if(atomicfields.getType()==STRING){
+             return atomicfields.getStr_value().compareTo(value.getString());
+         }
+         if(lessThan(value))return -1;
+         if(greaterThan(value))return 1;
+         return 0;
+     }
+
+     /**
+      * Attempts to compare this Value to the value given as parameter and returns true if this value is less than the value given as a parameter.
+      * The types used for the comparison will always be based on the type of this Value based on the following rules.
+      * <ul>
+      *   <li>If this Value is a numeric type, then the other Value will be asked to deliver the same numeric type for the comparison.
+      *   <li>If this Value is a string, then both values will be asked to deliver a double value for the comparison.
+      *   <li>If this Value is a timestamp, then both values will be asked to deliver a long value for the comparison.
+      *   <li>If this Value is a boolean, false will be returned.
+      * </ul>
+      *
+      * @param value the value this value should be compared to
+      * @return true if this value is less than the value given as a parameter, false otherwise
+      */
+     public boolean lessThan(ValueTransactional value){
+         switch(atomicfields.getType()){
+             case STRING     : return getDouble()<value.getDouble();
+             case INT        : return getInt()<value.getInt();
+             case LONG       : return getLong()<value.getLong();
+             case FLOAT      : return getFloat()<value.getFloat();
+             case DOUBLE     : return getDouble()<value.getDouble();
+             case TIMESTAMP  : return getLong()<value.getLong();
+         }
+         return false;
+     }
+
+     /**
+      * Attempts to compare this Value to the value given as parameter and returns true if this value is greater than the value given as a parameter.
+      * The types used for the comparison will always be based on the type of this Value based on the following rules.
+      * <ul>
+      *   <li>If this Value is a numeric type, then the other Value will be asked to deliver the same numeric type for the comparison.
+      *   <li>If this Value is a string, then both values will be asked to deliver a double value for the comparison.
+      *   <li>If this Value is a timestamp, then both values will be asked to deliver a long value for the comparison.
+      *   <li>If this Value is a boolean, false will be returned.
+      * </ul>
+      *
+      * @param value the value this value should be compared to
+      * @return true if this value is greater than the value given as a parameter, false otherwise
+      */
+     public boolean greaterThan(ValueTransactional value){
+         switch(atomicfields.getType()){
+             case STRING     : return getDouble()>value.getDouble();
+             case INT        : return getInt()>value.getInt();
+             case LONG       : return getLong()>value.getLong();
+             case FLOAT      : return getFloat()>value.getFloat();
+             case DOUBLE     : return getDouble()>value.getDouble();
+             case TIMESTAMP  : return getLong()>value.getLong();
+         }
+         return false;
+     }
+
+     /**
+      * Returns true if the string representation of this value starts with the string representation of the value given as parameter.
+      */
+     public boolean startsWith(ValueTransactional value){
+         return getString().startsWith(value.getString());
+     }
+
+     /**
+      * Returns true if the string representation of this value ends with the string representation of the value given as parameter.
+      */
+     public boolean endsWith(ValueTransactional value){
+         return getString().endsWith(value.getString());
+     }
+
+     /**
+      * Returns true if the string representation of this value contains the string representation of the value given as parameter.
+      */
+     public boolean contains(ValueTransactional value){
+         return getString().indexOf(value.getString())>-1;
+     }
+
+     /**
+      * Returns true if the contents of this value equals the contents of the value given as parameter.
+      */
+     public boolean equals(Object obj){
+         try{
+             ValueTransactional val=(ValueTransactional)obj;
+             if(val.atomicfields.getType()==atomicfields.getType()){
+                 switch(atomicfields.getType()){
+                     case NULL       : return true;
+                     case STRING     : return atomicfields.getStr_value().equals(val.atomicfields.getStr_value());
+                     case INT        : return atomicfields.getInt_value()==atomicfields.getInt_value();
+                     case LONG       : return atomicfields.getInt_value()==atomicfields.getInt_value();
+                     case FLOAT      : return atomicfields.getFloat_value()==atomicfields.getFloat_value();
+                     case DOUBLE     : return atomicfields.getFloat_value()==atomicfields.getFloat_value();
+                     case BOOLEAN    : return atomicfields.getInt_value()==atomicfields.getInt_value();
+                     case TIMESTAMP  : return atomicfields.getInt_value()==atomicfields.getInt_value();
+                     case BINARY     : if(atomicfields.getBinary().length()==val.atomicfields.getBinary().length()){
+                                          for(int i=0;i<atomicfields.getBinary().length();i++){
+                                              if(atomicfields.getBinary().get(i)!=val.atomicfields.getBinary().get(i))return false;
+                                          }
+                                       }
+                                       return true;
+                 }
+             }
+         }catch(Exception e){}
+         return false;
+     }
+
+     /**
+      * Returns a string representation of this object.
+      */
+     public String toString(){
+         return getString();
+     }
+
+     /**
+      * Returns a string representation of this object (identical to toString)
+      */
+     public String get(){
+         return getString();
+     }
+
+     /**
+      * Returns this value as an xml tag with the given key set as an attribute called name.
+      * The following string is an example of the int value 1234 created with the key foo &lt;value name="foo" type="int"&gt;1234&lt;/value&gt;
+      */
+     public String toBasicXMLString(String key){
+         switch(atomicfields.getType()){
+             case STRING     : return "<value name=\""+key+"\" type=\"string\">"+atomicfields.getStr_value()+"</value>";
+             case INT        : return "<value name=\""+key+"\"  type=\"int\">"+atomicfields.getInt_value()+"</value>";
+             case LONG       : return "<value name=\""+key+"\"  type=\"long\">"+atomicfields.getInt_value()+"</value>";
+             case FLOAT      : return "<value name=\""+key+"\"  type=\"float\">"+atomicfields.getFloat_value()+"</value>";
+             case DOUBLE     : return "<value name=\""+key+"\"  type=\"double\">"+atomicfields.getFloat_value()+"</value>";
+             case BOOLEAN    : if(atomicfields.getInt_value()==1){
+                                     return "<value name=\""+key+"\"  type=\"boolean\">TRUE</value>";
+                               }else{
+                                     return "<value name=\""+key+"\"  type=\"boolean\">FALSE</value>";
+                               }
+             case TIMESTAMP  : return "<value name=\""+key+"\"  type=\"timestamp\">"+new Date(atomicfields.getInt_value()).toString()+"</value>";
+             case BINARY     : return "<value name=\""+key+"\" type=\"binary\">"+getString()+"</value>";
+         }
+         return "<value name=\""+key+"\"  type=\"null\"></value>";
+     }
+     
+     /**
+       * Returns this value as an xml tag.
+       * The following string is an example of the int value 1234 &lt;value type="int"&gt;1234&lt;/value&gt;
+       */
+     public String toBasicXMLString(){
+          switch(atomicfields.getType()){
+              case STRING     : return "<value type=\"string\">"+atomicfields.getStr_value()+"</value>";
+              case INT        : return "<value type=\"int\">"+atomicfields.getInt_value()+"</value>";
+              case LONG       : return "<value type=\"long\">"+atomicfields.getInt_value()+"</value>";
+              case FLOAT      : return "<value type=\"float\">"+atomicfields.getFloat_value()+"</value>";
+              case DOUBLE     : return "<value type=\"double\">"+atomicfields.getFloat_value()+"</value>";
+              case BOOLEAN    : if(atomicfields.getInt_value()==1){
+                                      return "<value type=\"boolean\">TRUE</value>";
+                                }else{
+                                      return "<value type=\"boolean\">FALSE</value>";
+                                }
+              case TIMESTAMP  : return "<value type=\"timestamp\">"+new Date(atomicfields.getInt_value()).toString()+"</value>";
+              case BINARY     : return "<value type=\"binary\">"+getString()+"</value>";
+          }
+          return "<value type=\"null\"></value>";
+      }
+
+     /**
+      * Returns a string representation of this value
+      */
+     public String getString(){
+         switch(atomicfields.getType()){
+             case STRING     : return atomicfields.getStr_value();
+             case INT        : return ""+atomicfields.getInt_value();
+             case LONG       : return ""+atomicfields.getInt_value();
+             case FLOAT      : return ""+atomicfields.getFloat_value();
+             case DOUBLE     : return ""+atomicfields.getFloat_value();
+             case BOOLEAN    : if(atomicfields.getInt_value()==1){
+                                     return "TRUE";
+                               }else{
+                                     return "FALSE";
+                               }
+             case TIMESTAMP  : return new Date(atomicfields.getInt_value()).toString();
+             case BINARY     : StringBuffer buf=new StringBuffer();
+                               for(int i=0;i<atomicfields.getBinary().length();i++){
+                                  byte b=atomicfields.getBinary().get(i);
+                                  buf.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1,3));
+                               }
+                               return buf.toString();
+         }
+         return "";
+     }
+
+     /**
+      * Attempts to return an integer representation of this value.
+      * Numerical values will be returned directly (demoted if necessary).
+      * Boolean values will be returned as 1 or 0.
+      * Timestamp values will be returned as a unix timestamp representation divided by 1000.
+      * String values will be atempted to be converted into an int, if that fails, 0 will be returned.
+      * Everything else will return 0.
+      */
+     public int getInt(){
+         try{
+             switch(atomicfields.getType()){
+                 case STRING     : return Integer.parseInt(atomicfields.getStr_value());
+                 case INT        : return (int)atomicfields.getInt_value();
+                 case LONG       : return (int)atomicfields.getInt_value();
+                 case FLOAT      : return (int)atomicfields.getFloat_value();
+                 case DOUBLE     : return (int)atomicfields.getFloat_value();
+                 case BOOLEAN    : return (int)atomicfields.getInt_value();
+                 case TIMESTAMP  : return (int)(atomicfields.getInt_value()/1000);
+             }
+         }catch(Exception e){}
+         return 0;
+     }
+
+     /**
+       * Attempts to return a long representation of this value.
+       * Numerical values will be returned directly.
+       * Boolean values will be returned as 1 or 0.
+       * Timestamp values will be returned as a unix timestamp representation.
+       * String values will be atempted to be converted into an int, if that fails, 0 will be returned.
+       * Everything else will return 0.
+       */
+     public long getLong(){
+         try{
+             switch(atomicfields.getType()){
+                 case STRING     : return Long.parseLong(atomicfields.getStr_value());
+                 case INT        : return atomicfields.getInt_value();
+                 case LONG       : return atomicfields.getInt_value();
+                 case FLOAT      : return (long)atomicfields.getFloat_value();
+                 case DOUBLE     : return (long)atomicfields.getFloat_value();
+                 case BOOLEAN    : return atomicfields.getInt_value();
+                 case TIMESTAMP  : return atomicfields.getInt_value();
+             }
+         }catch(Exception e){}
+         return 0;
+     }
+
+     /**
+      * Attempts to return a float representation of this value.
+      * Numerical values will be returned directly (demoted if necessary).
+      * Boolean values will be returned as 1 or 0.
+      * Timestamp values will be returned as a unix timestamp representation divided by 1000.
+      * String values will be atempted to be converted into a float, if that fails, 0 will be returned.
+      * Everything else will return 0.
+      */
+     public float getFloat(){
+         try{
+             switch(atomicfields.getType()){
+                 case STRING     : return Float.parseFloat(atomicfields.getStr_value());
+                 case INT        : return (float)atomicfields.getInt_value();
+                 case LONG       : return (float)atomicfields.getInt_value();
+                 case FLOAT      : return (float)atomicfields.getFloat_value();
+                 case DOUBLE     : return (float)atomicfields.getFloat_value();
+                 case BOOLEAN    : return (float)atomicfields.getInt_value();
+                 case TIMESTAMP  : return (float)(atomicfields.getInt_value()/1000);
+             }
+         }catch(Exception e){}
+         return 0.0f;
+     }
+
+     /**
+      * Attempts to return a double representation of this value.
+      * Numerical values will be returned directly.
+      * Boolean values will be returned as 1 or 0.
+      * Timestamp values will be returned as a unix timestamp representation divided by 1000.
+      * String values will be atempted to be converted into a float, if that fails, 0 will be returned.
+      * Everything else will return 0.
+      */
+     public double getDouble(){
+         try{
+             switch(atomicfields.getType()){
+                 case STRING     : return Double.parseDouble(atomicfields.getStr_value());
+                 case INT        : return (double)atomicfields.getInt_value();
+                 case LONG       : return (double)atomicfields.getInt_value();
+                 case FLOAT      : return (double)atomicfields.getFloat_value();
+                 case DOUBLE     : return (double)atomicfields.getFloat_value();
+                 case BOOLEAN    : return (double)atomicfields.getInt_value();
+                 case TIMESTAMP  : return (double)(atomicfields.getInt_value());
+             }
+         }catch(Exception e){}
+         return 0.0;
+     }
+
+     /**
+      * Returns a boolean representation of this value.
+      * Boolean values will be returned directly.
+      * Integer values equalling 1 will be returned as true.
+      * String values equalling true,1,t,yes,on will be returned as true (case insensitive).
+      * Everything else will be returned as false.
+      *
+      * @return a boolean representation of this value.
+      */
+     public boolean getBoolean(){
+         try{
+             switch(atomicfields.getType()){
+                 case STRING     : if(atomicfields.getStr_value().toLowerCase().trim().equals("true"))return true;
+                                   if(atomicfields.getStr_value().trim().equals("1"))return true;
+                                   if(atomicfields.getStr_value().toLowerCase().trim().equals("t"))return true;
+                                   if(atomicfields.getStr_value().toLowerCase().trim().equals("yes"))return true;
+                                   if(atomicfields.getStr_value().toLowerCase().trim().equals("on"))return true;
+                 case INT        : if(atomicfields.getInt_value()==1)return true;
+                 case LONG       : if(atomicfields.getInt_value()==1)return true;
+                 case FLOAT      : if(atomicfields.getFloat_value()==1.0f)return true;
+                 case DOUBLE     : if(atomicfields.getFloat_value()==1.0)return true;
+                 case BOOLEAN    : if(atomicfields.getInt_value()==1)return true;
+             }
+         }catch(Exception e){}
+         return false;
+     }
+
+     /**
+      * Attempts to return this value as a Date object.
+      * For non date numerical values, the following rules will be used for conversion:
+      * int and float will be multiplied by 1000 and used as a unix timestamp.
+      * long and double will be used directly as a unix timestamp.
+      * Any other type will result in a Date object initialized with 0.
+      *
+      * @return a Date object representation of this value
+      */
+     public Date getTimestamp(){
+         try{
+             switch(atomicfields.getType()){
+                 case INT        : return new Date(atomicfields.getInt_value()*1000l);
+                 case LONG       : return new Date(atomicfields.getInt_value());
+                 case FLOAT      : return new Date((long)(atomicfields.getFloat_value()*1000l));
+                 case DOUBLE     : return new Date((long)atomicfields.getFloat_value());
+                 case TIMESTAMP  : return new Date(atomicfields.getInt_value());
+             }
+         }catch(Exception e){}
+         return new Date(0);
+     }
+
+     public AtomicByteArray getBinary(){
+         switch(atomicfields.getType()){
+             case BINARY        : return atomicfields.getBinary();
+         }
+         return null;
+     }
+
+     /**
+      * Attempts to write this Value to the given DataOutputStream.
+      * The Value will be written as a byte signifying the type of the Value, followed by the actual Value in the native format used by DataOutput.
+      * The exception to this is the string which is written as an integer followed by each character as a single char.
+      * 
+      * @param out the DataOutputStream the Value should be written to
+      */
+     public void writeToStream(DataOutputStream out) throws IOException{
+         out.writeByte(atomicfields.getType());
+         switch(atomicfields.getType()){
+             case STRING :   out.writeInt(atomicfields.getStr_value().length());
+                             for(int i=0;i<atomicfields.getStr_value().length();i++){
+                                 out.writeChar(atomicfields.getStr_value().charAt(i));
+                             }
+                         break;
+             case INT    :   out.writeInt((int)atomicfields.getInt_value());
+                         break;
+             case LONG   :   out.writeLong(atomicfields.getInt_value());
+                         break;
+             case FLOAT  :   out.writeFloat((float)atomicfields.getFloat_value());
+                         break;
+             case DOUBLE :   out.writeDouble(atomicfields.getFloat_value());
+                         break;
+             case BOOLEAN:   out.writeBoolean(atomicfields.getInt_value()==1);
+                         break;
+             case TIMESTAMP: out.writeLong(atomicfields.getInt_value());
+                         break;
+             case BINARY : out.writeInt(atomicfields.getBinary().length());
+                         for (int i=0; i<atomicfields.getBinary().length(); i++) 
+                             out.write(atomicfields.getBinary().get(i));
+                         break;
+         }
+     }
+     
+     /**
+       * Attempts to write this Value to the given DataOutputStream.
+       * The Value will be written as a byte signifying the type of the Value, followed by the actual Value in the native format used by DataOutput.
+       * The exception to this is the string which is written as an integer followed by each character as a single char.
+       * 
+       * @param out the DataOutputStream the Value should be written to
+       */
+      public void writeToFile(DataOutput out) throws IOException{
+          out.writeByte(atomicfields.getType());
+          switch(atomicfields.getType()){
+              case STRING :   out.writeInt(atomicfields.getStr_value().length());
+                              for(int i=0;i<atomicfields.getStr_value().length();i++){
+                                  out.writeChar(atomicfields.getStr_value().charAt(i));
+                              }
+                          break;
+              case INT    :   out.writeInt((int)atomicfields.getInt_value());
+                          break;
+              case LONG   :   out.writeLong(atomicfields.getInt_value());
+                          break;
+              case FLOAT  :   out.writeFloat((float)atomicfields.getFloat_value());
+                          break;
+              case DOUBLE :   out.writeDouble(atomicfields.getFloat_value());
+                          break;
+              case BOOLEAN:   out.writeBoolean(atomicfields.getInt_value()==1);
+                          break;
+              case TIMESTAMP: out.writeLong(atomicfields.getInt_value());
+                          break;
+              case BINARY : out.writeInt(atomicfields.getBinary().length());
+                            for (int i=0; i<atomicfields.getBinary().length(); i++) 
+                                out.write(atomicfields.getBinary().get(i));
+                            
+          }
+      }
+
+     /**
+      * Attempts to read a new Value from the given DataInputStream.
+      * The Value should be in the format delivered by writeToStream.
+      *
+      * @param in the DataInputStream the Value should be read from
+      * @return the Value read from the stream
+      */
+     public static ValueTransactional readFromStream(DataInputStream in) throws IOException{
+         byte type=in.readByte();
+         switch(type){
+             case STRING :   int size=in.readInt();
+                             StringBuffer buf=new StringBuffer();
+                             for(int i=0;i<size;i++){
+                                 buf.append(in.readChar());
+                             }
+                             return new ValueTransactional(buf.toString());
+             case INT    :   return new ValueTransactional(in.readInt());
+             case LONG   :   return new ValueTransactional(in.readLong());
+             case FLOAT  :   return new ValueTransactional(in.readFloat());
+             case DOUBLE :   return new ValueTransactional(in.readDouble());
+             case BOOLEAN:   return new ValueTransactional(in.readBoolean());
+             case TIMESTAMP: return new ValueTransactional(new Date(in.readLong()));
+             case BINARY : int length=in.readInt();
+                           byte[] abuf=new byte[length];
+                           int read=0;
+                           while(read<length){
+                               read+=in.read(abuf,read,length-read);
+                           }
+                           return new ValueTransactional(abuf);
+
+         }
+         return new ValueTransactional();
+     }
+
+    /**
+     * Initializes this Value with the given String.
+     * 
+     * @param val the value this Value object should represent
+     */
+     public ValueTransactional(String val){
+         this();
+         atomicfields.setStr_value(val);
+         atomicfields.setType((byte)STRING);
+     }
+     
+     public ValueTransactional(byte[] val){
+         this();
+         for (int i=0; i<val.length; i++) 
+                 atomicfields.getBinary().set(i, val[i]);
+         
+         atomicfields.setType((byte)BINARY);
+      }
+
+     /**
+      * Initializes this Value with the given Date.
+      * The Dates internal long value delivered by the getTime() method will be used.
+      * 
+      * @param val the value this Value object should represent
+      */
+     public ValueTransactional(Date val){
+         atomicfields.setInt_value(val.getTime());
+         atomicfields.setType((byte)TIMESTAMP);
+     }
+
+     /**
+      * Initializes this Value as null.
+      */
+     public ValueTransactional(){
+         atomicfields.setStr_value(null);
+         atomicfields.setInt_value(0);
+         atomicfields.setFloat_value(0.0);
+         atomicfields.setBinary(new AtomicByteArray(Byte.class, NULL));
+         atomicfields.setType((byte)NULL);
+     }
+
+     /**
+      * Initializes this Value with the given int.
+      * 
+      * @param val the value this Value object should represent
+      */
+     public ValueTransactional(int val){
+         this();
+         atomicfields.setInt_value(val);
+         atomicfields.setType((byte)INT);
+     }
+
+     /**
+      * Initializes this Value with the given long.
+      * 
+      * @param val the value this Value object should represent
+      */
+     public ValueTransactional(long val){
+         this();
+         atomicfields.setInt_value(val);
+         atomicfields.setType((byte)LONG);
+     }
+
+     /**
+      * Initializes this Value with the given float.
+      * 
+      * @param val the value this Value object should represent
+      */
+     public ValueTransactional(float val){
+         this();
+         atomicfields.setFloat_value(val);
+         atomicfields.setType((byte)FLOAT);
+     }
+
+     /**
+      * Initializes this Value with the given double.
+      * 
+      * @param val the value this Value object should represent
+      */
+     public ValueTransactional(double val){
+         this();
+         atomicfields.setFloat_value(val);
+         atomicfields.setType((byte)DOUBLE);
+     }
+
+     /**
+      * Initializes this Value with the given boolean.
+      * 
+      * @param val the value this Value object should represent
+      */
+     public ValueTransactional(boolean val){
+         this();
+         if(val){
+             atomicfields.setInt_value(1);
+         }else{
+             atomicfields.setInt_value(0);
+         }
+         atomicfields.setType((byte)BOOLEAN);
+     }  
+     
+     
+
+}