From 1800a26f4a4e2c56e30b6b5670f8dee1f05d840b Mon Sep 17 00:00:00 2001 From: navid Date: Thu, 22 Jan 2009 06:25:24 +0000 Subject: [PATCH] *** empty log message *** --- .../core/TransactionalFile.java | 1 + .../dstm2/src/dstm2/AtomicByteArray.java | 4 + .../tuplesoup/core/PagedIndex.java | 20 + .../tuplesoup/core/RowTransactional.java | 382 ++++++++++ .../core/TableIndexPageTransactional.java | 19 +- .../tuplesoup/core/ValueTransactional.java | 653 ++++++++++++++++++ 6 files changed, 1073 insertions(+), 6 deletions(-) create mode 100644 Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/RowTransactional.java create mode 100644 Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/ValueTransactional.java diff --git a/Robust/Transactions/TransactionalIO/src/TransactionalIO/core/TransactionalFile.java b/Robust/Transactions/TransactionalIO/src/TransactionalIO/core/TransactionalFile.java index b7b611a4..e54efa93 100644 --- a/Robust/Transactions/TransactionalIO/src/TransactionalIO/core/TransactionalFile.java +++ b/Robust/Transactions/TransactionalIO/src/TransactionalIO/core/TransactionalFile.java @@ -211,6 +211,7 @@ public class TransactionalFile implements Comparable { if (!(this.inodestate.commitedfilesize.getLengthReaders().contains(me))) { this.inodestate.commitedfilesize.getLengthReaders().add(me); } + tmp.setLocalsize(this.inodestate.commitedfilesize.getLength()); tmp.lenght_read = true; diff --git a/Robust/Transactions/dstm2/src/dstm2/AtomicByteArray.java b/Robust/Transactions/dstm2/src/dstm2/AtomicByteArray.java index d81ec46c..e04f00d1 100644 --- a/Robust/Transactions/dstm2/src/dstm2/AtomicByteArray.java +++ b/Robust/Transactions/dstm2/src/dstm2/AtomicByteArray.java @@ -60,6 +60,10 @@ import java.lang.reflect.Array; version = 0; } + public int length(){ + return array.length; + } + public Byte get(int i) { Transaction me = Thread.getTransaction(); Transaction other = null; diff --git a/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/PagedIndex.java b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/PagedIndex.java index f200fa9b..914f41ff 100644 --- a/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/PagedIndex.java +++ b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/PagedIndex.java @@ -31,17 +31,37 @@ 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{ + + public @atomic interface PageIndexTSInf{ + Long getStat_read(); + Long getStat_write(); + Long getStat_create_page(); + Long getStat_page_next(); + Long getStat_page_branch(); + AtomicArray getRoots(); + + void setRoots(AtomicArray 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; + // private TableIndexPageTransactional[] root=null; 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 index 00000000..76685082 --- /dev/null +++ b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/RowTransactional.java @@ -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 values; + + public @atomic interface RowTSInf{ + + } + + public RowTransactional(String id){ + this.id=id; + size=-1; + values=new HashMap(); + } + + /** + * 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 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 keys=values.keySet(); + out.writeInt(keys.size()); + Iterator 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{"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 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\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("\n"); + return buf.toString(); + } + +} diff --git a/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java index 9385902d..23a25105 100644 --- a/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java +++ b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java @@ -29,12 +29,20 @@ * 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.*; -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(); @@ -59,8 +67,7 @@ public class TableIndexPageTransactional{ 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; @@ -77,7 +84,7 @@ public class TableIndexPageTransactional{ 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; @@ -281,4 +288,4 @@ public class TableIndexPageTransactional{ 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 index 00000000..f3be9829 --- /dev/null +++ b/Robust/Transactions/mytuplesoup/src/com/solidosystems/tuplesoup/core/ValueTransactional.java @@ -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. + *
    + *
  • If this Value is a numeric type, then the other Value will be asked to deliver the same numeric type for the comparison. + *
  • If this Value is a string, then both values will be asked to deliver a double value for the comparison. + *
  • If this Value is a timestamp, then both values will be asked to deliver a long value for the comparison. + *
  • If this Value is a boolean, false will be returned. + *
+ * + * @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() + *
  • If this Value is a numeric type, then the other Value will be asked to deliver the same numeric type for the comparison. + *
  • If this Value is a string, then both values will be asked to deliver a double value for the comparison. + *
  • If this Value is a timestamp, then both values will be asked to deliver a long value for the comparison. + *
  • If this Value is a boolean, false will be returned. + * + * + * @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.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 : return ""+getString()+""; + } + return ""; + } + + /** + * Returns this value as an xml tag. + * The following string is an example of the int value 1234 <value type="int">1234</value> + */ + public String toBasicXMLString(){ + 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 : return ""+getString()+""; + } + return ""; + } + + /** + * 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