import java.util.*;
import java.nio.channels.*;
import com.solidosystems.tuplesoup.filter.*;
+import dstm2.atomic;
/**
* The table stores a group of rows.
private int indexcacheusage;
private Hashtable<String,TableIndexNode> indexcache;
+
+ DualFileTableTSInf atomicfields;
// Statistic counters
- long stat_add=0;
+ public @atomic interface DualFileTableTSInf{
+ long getstat_add();
+ long getstat_update();
+ long getstat_delete();
+ long getstat_add_size();
+ long getstat_update_size();
+ long getstat_read_size();
+ long getstat_read();
+ long getstat_cache_hit();
+ long getstat_cache_miss();
+ long getstat_cache_drop();
+
+ void setstat_add(long val);
+ void setstat_update(long val);
+ void setstat_delete(long val);
+ void setstat_add_size(long val);
+ void setstat_update_size(long val);
+ void setstat_read_size(long val);
+ void setstat_read(long val);
+ void setstat_cache_hit(long val);
+ void setstat_cache_miss(long val);
+ void setstat_cache_drop(long val);
+ }
+
+ /*long stat_add=0;
long stat_update=0;
long stat_delete=0;
long stat_add_size=0;
long stat_read=0;
long stat_cache_hit=0;
long stat_cache_miss=0;
- long stat_cache_drop=0;
+ long stat_cache_drop=0;*/
protected String statlock="stat-dummy";
public Hashtable<String,Long> readStatistics(){
Hashtable<String,Long> hash=new Hashtable<String,Long>();
synchronized(statlock){
- hash.put("stat_table_add",stat_add);
- hash.put("stat_table_update",stat_update);
- hash.put("stat_table_delete",stat_delete);
- hash.put("stat_table_add_size",stat_add_size);
- hash.put("stat_table_update_size",stat_update_size);
- hash.put("stat_table_read_size",stat_read_size);
- hash.put("stat_table_read",stat_read);
- hash.put("stat_table_cache_hit",stat_cache_hit);
- hash.put("stat_table_cache_miss",stat_cache_miss);
- hash.put("stat_table_cache_drop",stat_cache_drop);
- stat_add=0;
- stat_update=0;
- stat_delete=0;
- stat_add_size=0;
- stat_update_size=0;
- stat_read_size=0;
- stat_read=0;
- stat_cache_hit=0;
- stat_cache_miss=0;
- stat_cache_drop=0;
+ hash.put("stat_table_add",atomicfields.getstat_add());
+ hash.put("stat_table_update",atomicfields.getstat_update());
+ hash.put("stat_table_delete",atomicfields.getstat_delete());
+ hash.put("stat_table_add_size",atomicfields.getstat_add_size());
+ hash.put("stat_table_update_size",atomicfields.getstat_update_size());
+ hash.put("stat_table_read_size",atomicfields.getstat_read_size());
+ hash.put("stat_table_read",atomicfields.getstat_read());
+ hash.put("stat_table_cache_hit",atomicfields.getstat_cache_hit());
+ hash.put("stat_table_cache_miss",atomicfields.getstat_cache_miss());
+ hash.put("stat_table_cache_drop",atomicfields.getstat_cache_drop());
+ atomicfields.setstat_add(0);
+ atomicfields.setstat_update(0);
+ atomicfields.setstat_delete(0);
+ atomicfields.setstat_add_size(0);
+ atomicfields.setstat_update_size(0);
+ atomicfields.setstat_read_size(0);
+ atomicfields.setstat_read(0);
+ atomicfields.setstat_cache_hit(0);
+ atomicfields.setstat_cache_miss(0);
+ atomicfields.setstat_cache_drop(0);
Hashtable<String,Long> ihash=index.readStatistics();
hash.putAll(ihash);
}
indexcache.remove(node.getData().getId());
indexcacheusage--;
synchronized(statlock){
- stat_cache_drop++;
+ atomicfields.setstat_cache_drop(atomicfields.getstat_cache_drop()+1);
}
indexcachefirst=node.getNext();
if(indexcachefirst==null){
row.writeToStream(fileastream);
int post=fileastream.size();
fileastream.flush();
+
synchronized(statlock){
- stat_add++;
- stat_add_size+=row.getSize();
- }
+ atomicfields.setstat_add(atomicfields.getstat_add()+1);
+ atomicfields.setstat_add_size(atomicfields.getstat_add_size()+row.getSize());
+ }
+
index.addEntry(row.getId(),row.getSize(),FILEA,fileaposition);
if(INDEXCACHESIZE>0){
TableIndexEntry entry=new TableIndexEntry(row.getId(),row.getSize(),FILEA,fileaposition);
int post=filebstream.size();
filebstream.flush();
synchronized(statlock){
- stat_add++;
- stat_add_size+=row.getSize();
+ atomicfields.setstat_add(atomicfields.getstat_add()+1);
+ atomicfields.setstat_add_size(atomicfields.getstat_add_size()+row.getSize());
}
index.addEntry(row.getId(),row.getSize(),FILEB,filebposition);
if(INDEXCACHESIZE>0){
}
indexcacheusage--;
synchronized(statlock){
- stat_cache_drop++;
+ atomicfields.setstat_cache_drop(atomicfields.getstat_cache_drop()+1);
}
}
}
indexcachelast=node;
}
synchronized(statlock){
- stat_cache_hit++;
+ atomicfields.setstat_cache_hit(atomicfields.getstat_cache_hit()+1);
}
return node.getData();
}
}
synchronized(statlock){
- stat_cache_miss++;
+ atomicfields.setstat_cache_miss(atomicfields.getstat_cache_miss()+1);
}
return null;
}
rowswitch=!rowswitch;
}
synchronized(statlock){
- stat_update++;
- stat_update_size+=row.getSize();
+ atomicfields.setstat_update(atomicfields.getstat_update()+1);
+ atomicfields.setstat_update_size(atomicfields.getstat_update_size()+row.getSize());
}
}
}
index.updateEntry(row.getId(),row.getSize(),DELETE,0);
synchronized(statlock){
- stat_delete++;
+ atomicfields.setstat_delete(atomicfields.getstat_delete()+1);
}
}
Row row=Row.readFromStream(data);
data.close();
synchronized(statlock){
- stat_read++;
- stat_read_size+=row.getSize();
+ atomicfields.setstat_read(atomicfields.getstat_read()+1);
+ atomicfields.setstat_read_size(atomicfields.getstat_read_size()+row.getSize());
}
return row;
}
package com.solidosystems.tuplesoup.core;
import dstm2.atomic;
-import dstm2.util.HashMap;
+import dstm2.util.StringKeyHashMap;
import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
/**
*
*/
public class RowTransactional {
private String id;
- private int size;
- private HashMap<ValueTransactional> values;
+ // private int size;
+ RowTSInf atomicfields;
+ private StringKeyHashMap<ValueTransactional> values;
public @atomic interface RowTSInf{
-
+ int getSize();
+ void setSize(int val);
}
public RowTransactional(String id){
this.id=id;
- size=-1;
- values=new HashMap<ValueTransactional>();
+ atomicfields.setSize(-1);
+ values=new StringKeyHashMap<ValueTransactional>();
}
/**
* Returns the actual size in bytes this row will take when written to a stream.
*/
public int getSize(){
- if(size==-1)recalcSize();
- return size;
+ if(atomicfields.getSize()==-1)recalcSize();
+ return atomicfields.getSize();
}
/**
* Stores the given value for the given key.
*/
public void put(String key,ValueTransactional value){
- size=-1;
- values.put(key.hashCode(),value);
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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));
+ atomicfields.setSize(-1);
+ values.put(key,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();
+ if(!values.containsKey(key))return new ValueTransactional();
return values.get(key.hashCode());
}
* See the documentation for Value to learn how the string value is generated.
*/
public String getString(String key){
- if(!values.containsKey(key.hashCode()))return "";
+ if(!values.containsKey(key))return "";
return values.get(key.hashCode()).getString();
}
* 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;
+ if(!values.containsKey(key))return 0;
return values.get(key.hashCode()).getInt();
}
* 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;
+ if(!values.containsKey(key))return 0;
return values.get(key.hashCode()).getLong();
}
* 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;
+ if(!values.containsKey(key))return 0f;
return values.get(key.hashCode()).getFloat();
}
* 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;
+ if(!values.containsKey(key))return 0d;
return values.get(key.hashCode()).getDouble();
}
* 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;
+ if(!values.containsKey(key))return false;
return values.get(key.hashCode()).getBoolean();
}
* 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);
+ if(!values.containsKey(key))return new Date(0);
return values.get(key.hashCode()).getTimestamp();
}
ByteArrayOutputStream bout=new ByteArrayOutputStream();
DataOutputStream dout=new DataOutputStream(bout);
writeToStream(dout);
- size=bout.size();
+ this.atomicfields.setSize(bout.size());
dout.close();
bout.close();
}catch(Exception e){}
out.writeUTF(id);
- Set keys=values.keySet();
- out.writeInt(keys.size());
- Iterator<String> it=keys.iterator();
+ Set<StringKeyHashMap.TEntry<ValueTransactional>> pairs=values.entrySet();
+ out.writeInt(pairs.size());
+ Iterator<StringKeyHashMap.TEntry<ValueTransactional>> it= pairs.iterator();
while(it.hasNext()){
- Integer key= (Integer)it.next();
- ValueTransactional value=values.get(key.hashCode());
+ String key= it.next().getKey();
+ ValueTransactional value= values.get(key);
out.writeUTF(key);
value.writeToFile(out);
}
long post=out.getFilePointer();
int size=(int)(post-pre);
- this.size=size+4;
- out.writeInt(this.size);
+ this.atomicfields.setSize(size+4);
+ out.writeInt(this.atomicfields.getSize());
}
/**
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();
+ Set<StringKeyHashMap.TEntry<ValueTransactional>> pairs=values.entrySet();
+ out.writeInt(pairs.size());
+
+ Iterator<StringKeyHashMap.TEntry<ValueTransactional>> it=pairs.iterator();
while(it.hasNext()){
- String key=it.next();
- ValueTransactional value=values.get(key.hashCode());
+ String key=it.next().getKey();
+ ValueTransactional value=values.get(key);
out.writeUTF(key);
value.writeToStream(out);
}
int post=out.size();
int size=calcSize(pre,post);
- this.size=size+4;
- out.writeInt(this.size);
+ this.atomicfields.setSize(size+4);
+ out.writeInt(this.atomicfields.getSize());
}
/**
* Reads a full row from the given DataInputStream and returns it.
*/
- public static Row readFromStream(DataInputStream in) throws IOException{
+ public static RowTransactional readFromStream(DataInputStream in) throws IOException{
String id=in.readUTF();
- Row row=new Row(id);
+ RowTransactional row=new RowTransactional(id);
int size=in.readInt();
for(int i=0;i<size;i++){
String key=in.readUTF();
- Value value=Value.readFromStream(in);
+ ValueTransactional value=ValueTransactional.readFromStream(in);
row.put(key,value);
}
size=in.readInt();
- row.size=size;
+ row.atomicfields.setSize(size);
return row;
}
public String toString(){
StringBuffer buf=new StringBuffer();
buf.append("("+id+")=>{");
- Iterator<String> it=values.keySet().iterator();
+ Iterator<StringKeyHashMap.TEntry<ValueTransactional>> it=values.entrySet().iterator();
boolean first=true;
while(it.hasNext()){
if(!first){
}else{
first=false;
}
- key=it.next();
+ String key=it.next().getKey();
buf.append("\"");
buf.append(key);
buf.append("\":");
- Value value=values.get(key);
+ ValueTransactional value=values.get(key);
buf.append(value.getTypeName());
buf.append(":");
if(value.getType()==Value.STRING){
StringBuffer buf=new StringBuffer();
buf.append(indentation);
buf.append("<row id=\""+id+"\">\n");
- Iterator it=values.entrySet().iterator();
+ Iterator<StringKeyHashMap.TEntry<ValueTransactional>> it=values.entrySet().iterator();
while(it.hasNext()){
- String key=(String)it.next();
- ValueTransactional value=values.get(key.hashCode());
+ String key=it.next().getKey();
+ ValueTransactional value=values.get(key);
buf.append(indentation);
buf.append(" ");
buf.append(value.toBasicXMLString(key));