From a64bb1dfbc64983a134cdef4f903e21b12fcd847 Mon Sep 17 00:00:00 2001 From: navid Date: Tue, 27 Jan 2009 06:22:42 +0000 Subject: [PATCH] *** empty log message *** --- .../tuplesoup/core/DualFileTable.java | 590 +++++++++++++ .../core/DualFileTableTransactional.java | 777 ++++++++++++++++++ .../tuplesoup/core/HashedTable.java | 225 +++++ .../core/HashedTableTransactional.java | 225 +++++ .../tuplesoup/core/IndexedTableReader.java | 261 ++++++ .../core/IndexedTableReaderTransactional.java | 287 +++++++ .../tuplesoup/core/PagedIndex.java | 150 ++++ .../core/PagedIndexTransactional.java | 203 +++++ .../com/solidosystems/tuplesoup/core/Row.java | 400 +++++++++ .../tuplesoup/core/RowMatcher.java | 108 +++ .../core/RowMatcherTransactional.java | 108 +++ .../tuplesoup/core/RowTransactional.java | 398 +++++++++ .../solidosystems/tuplesoup/core/Table.java | 147 ++++ .../tuplesoup/core/TableIndex.java | 46 ++ .../tuplesoup/core/TableIndexEntry.java | 239 ++++++ .../core/TableIndexEntryTransactional.java | 239 ++++++ .../tuplesoup/core/TableIndexNode.java | 87 ++ .../core/TableIndexNodeTransactional.java | 94 +++ .../tuplesoup/core/TableIndexPage.java | 279 +++++++ .../core/TableIndexPageTransactional.java | 318 +++++++ .../core/TableIndexTransactional.java | 22 + .../tuplesoup/core/TableTransactional.java | 157 ++++ .../tuplesoup/core/TupleStream.java | 39 + .../tuplesoup/core/TupleStreamMerger.java | 74 ++ .../core/TupleStreamMergerTransactional.java | 74 ++ .../core/TupleStreamTransactional.java | 17 + .../solidosystems/tuplesoup/core/Value.java | 639 ++++++++++++++ .../tuplesoup/core/ValueTransactional.java | 685 +++++++++++++++ .../tuplesoup/filter/Conditional.java | 71 ++ .../tuplesoup/filter/HeapSort.java | 46 ++ .../tuplesoup/filter/JavaSort.java | 61 ++ .../solidosystems/tuplesoup/filter/Join.java | 80 ++ .../tuplesoup/filter/MergeSort.java | 182 ++++ .../tuplesoup/filter/MergeSort2.java | 227 +++++ .../tuplesoup/filter/QuickSort.java | 46 ++ .../tuplesoup/filter/RadixSort.java | 46 ++ .../tuplesoup/filter/RowBuffer.java | 132 +++ .../filter/RowBufferTransactional.java | 132 +++ .../solidosystems/tuplesoup/filter/Sort.java | 53 ++ .../tuplesoup/filter/SortComparator.java | 67 ++ .../tuplesoup/filter/SortRule.java | 55 ++ .../tuplesoup/test/BasicTest.java | 117 +++ .../test/OrigParralelPerformanceTest.java | 175 ++++ .../tuplesoup/test/OrigParralelThread.java | 74 ++ .../test/ParallelPerformanceTest.java | 176 ++++ .../tuplesoup/test/ParallelThread.java | 74 ++ 46 files changed, 8702 insertions(+) create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTable.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTableTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTable.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTableTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReader.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReaderTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/PagedIndex.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/PagedIndexTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Row.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcher.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcherTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Table.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndex.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexEntry.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexEntryTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexNode.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexNodeTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPage.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStream.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMerger.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMergerTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Value.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/ValueTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/Conditional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/HeapSort.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/JavaSort.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/Join.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/MergeSort.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/MergeSort2.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/QuickSort.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RadixSort.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RowBuffer.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RowBufferTransactional.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/Sort.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortComparator.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortRule.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/BasicTest.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelPerformanceTest.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelThread.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelPerformanceTest.java create mode 100644 Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelThread.java diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTable.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTable.java new file mode 100644 index 00000000..cbc26ac1 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTable.java @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; +import java.nio.channels.*; +import com.solidosystems.tuplesoup.filter.*; + +/** + * The table stores a group of rows. + * Every row must have a unique id within a table. + */ +public class DualFileTable implements Table{ + + + private int INDEXCACHESIZE=8192; + + private String filealock="filea-dummy"; + private String fileblock="fileb-dummy"; + + private DataOutputStream fileastream=null; + private DataOutputStream filebstream=null; + private RandomAccessFile filearandom=null; + private RandomAccessFile filebrandom=null; + FileChannel fca=null; + FileChannel fcb=null; + private TableIndex index=null; + + private long fileaposition=0; + private long filebposition=0; + + private boolean rowswitch=true; + + private String title; + private String location; + + private TableIndexNode indexcachefirst; + private TableIndexNode indexcachelast; + private int indexcacheusage; + private Hashtable indexcache; + + // Statistic counters + long stat_add=0; + long stat_update=0; + long stat_delete=0; + long stat_add_size=0; + long stat_update_size=0; + long stat_read_size=0; + long stat_read=0; + long stat_cache_hit=0; + long stat_cache_miss=0; + long stat_cache_drop=0; + + protected String statlock="stat-dummy"; + + /** + * Return the current values of the statistic counters and reset them. + * The current counters are: + * + * Furthermore, the index will be asked to deliver separate index specific counters + */ + public Hashtable readStatistics(){ + Hashtable hash=new Hashtable(); + 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; + Hashtable ihash=index.readStatistics(); + hash.putAll(ihash); + } + return hash; + } + + /** + * Create a new table object with the default flat index model + */ + + + /** + * Create a new table object with a specific index model + */ + public DualFileTable(String title,String location, int indextype) throws IOException{ + this.title=title; + this.location=location; + if(!this.location.endsWith(File.separator))this.location+=File.separator; + switch(indextype){ + case PAGED : index=new PagedIndex(getFileName(INDEX)); + + break; + + } + indexcachefirst=null; + indexcachelast=null; + indexcacheusage=0; + indexcache=new Hashtable(); + } + + /** + * Set the maximal allowable size of the index cache. + */ + public void setIndexCacheSize(int newsize){ + INDEXCACHESIZE=newsize; + } + + /** + * Close all open file streams + */ + public void close(){ + try{ + if(fileastream!=null)fileastream.close(); + if(filebstream!=null)filebstream.close(); + if(filearandom!=null)filearandom.close(); + if(filebrandom!=null)filebrandom.close(); + index.close(); + }catch(Exception e){} + } + + /** + * Returns the name of this table + */ + public String getTitle(){ + return title; + } + + /** + * Returns the location of this tables datafiles + */ + public String getLocation(){ + return location; + } + + protected String getFileName(int type){ + switch(type){ + case FILEB : return location+title+".a"; + case FILEA : return location+title+".b"; + case INDEX : return location+title+".index"; + } + return null; + } + + /** + * Delete the files created by this table object. + * Be aware that this will delete any data stored in this table! + */ + public void deleteFiles(){ + try{ + File ftest=new File(getFileName(FILEA)); + ftest.delete(); + }catch(Exception e){} + try{ + File ftest=new File(getFileName(FILEB)); + ftest.delete(); + }catch(Exception e){} + try{ + File ftest=new File(getFileName(INDEX)); + ftest.delete(); + }catch(Exception e){} + } + + private synchronized void openFile(int type) throws IOException{ + switch(type){ + case FILEA : if(fileastream==null){ + System.out.println("file a " + getFileName(FILEA)); + fileastream=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(getFileName(FILEA),true))); + File ftest=new File(getFileName(FILEA)); + fileaposition=ftest.length(); + } + break; + case FILEB : if(filebstream==null){ + System.out.println("file b " + getFileName(FILEB)); + filebstream=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(getFileName(FILEB),true))); + File ftest=new File(getFileName(FILEB)); + filebposition=ftest.length(); + } + break; + } + } + + /** + * Adds a row of data to this table. + */ + public void addRow(Row row) throws IOException{ + // Distribute new rows between the two datafiles by using the rowswitch, but don't spend time synchronizing... this does not need to be acurate! + if(rowswitch){ + addRowA(row); + }else{ + addRowB(row); + } + rowswitch=!rowswitch; + } + + private void addCacheEntry(TableIndexEntry entry){ + synchronized(indexcache){ + if(indexcacheusage>INDEXCACHESIZE){ + // remove first entry + TableIndexNode node=indexcachefirst; + indexcache.remove(node.getData().getId()); + indexcacheusage--; + synchronized(statlock){ + stat_cache_drop++; + } + indexcachefirst=node.getNext(); + if(indexcachefirst==null){ + indexcachelast=null; + }else{ + indexcachefirst.setPrevious(null); + } + } + TableIndexNode node=new TableIndexNode(indexcachelast,entry); + if(indexcachelast!=null){ + indexcachelast.setNext(node); + } + if(indexcachefirst==null){ + indexcachefirst=node; + } + indexcachelast=node; + indexcache.put(entry.getId(),node); + indexcacheusage++; + } + } + + private void addRowA(Row row) throws IOException{ + synchronized(filealock){ + openFile(FILEA); + int pre=fileastream.size(); + row.writeToStream(fileastream); + int post=fileastream.size(); + fileastream.flush(); + synchronized(statlock){ + stat_add++; + stat_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); + addCacheEntry(entry); + } + fileaposition+=Row.calcSize(pre,post); + } + } + private void addRowB(Row row) throws IOException{ + synchronized(fileblock){ + openFile(FILEB); + int pre=filebstream.size(); + row.writeToStream(filebstream); + int post=filebstream.size(); + filebstream.flush(); + synchronized(statlock){ + stat_add++; + stat_add_size+=row.getSize(); + } + index.addEntry(row.getId(),row.getSize(),FILEB,filebposition); + if(INDEXCACHESIZE>0){ + TableIndexEntry entry=new TableIndexEntry(row.getId(),row.getSize(),FILEB,filebposition); + addCacheEntry(entry); + } + filebposition+=Row.calcSize(pre,post); + } + } + + + private void updateCacheEntry(TableIndexEntry entry){ + synchronized(indexcache){ + if(indexcache.containsKey(entry.getId())){ + TableIndexNode node=indexcache.get(entry.getId()); + node.setData(entry); + if(node!=indexcachelast){ + if(node==indexcachefirst){ + indexcachefirst=node.getNext(); + } + node.remove(); + indexcachelast.setNext(node); + node.setPrevious(indexcachelast); + node.setNext(null); + indexcachelast=node; + } + }else{ + addCacheEntry(entry); + } + } + } + + private void removeCacheEntry(String id){ + synchronized(indexcache){ + if(indexcache.containsKey(id)){ + TableIndexNode node=indexcache.get(id); + indexcache.remove(id); + if(indexcacheusage==1){ + indexcachefirst=null; + indexcachelast=null; + indexcacheusage=0; + return; + } + if(node==indexcachefirst){ + indexcachefirst=node.getNext(); + indexcachefirst.setPrevious(null); + }else if(node==indexcachelast){ + indexcachelast=node.getPrevious(); + indexcachelast.setNext(null); + }else{ + node.remove(); + } + indexcacheusage--; + synchronized(statlock){ + stat_cache_drop++; + } + } + } + } + + private TableIndexEntry getCacheEntry(String id){ + synchronized(indexcache){ + if(indexcache.containsKey(id)){ + TableIndexNode node=indexcache.get(id); + if(node!=indexcachelast){ + if(node==indexcachefirst){ + indexcachefirst=node.getNext(); + } + node.remove(); + indexcachelast.setNext(node); + node.setPrevious(indexcachelast); + node.setNext(null); + indexcachelast=node; + } + synchronized(statlock){ + stat_cache_hit++; + } + return node.getData(); + } + } + synchronized(statlock){ + stat_cache_miss++; + } + return null; + } + + /** + * Adds a row to this table if it doesn't already exist, if it does it updates the row instead. + * This method is much slower than directly using add or update, so only use it if you don't know wether or not the row already exists. + */ + public void addOrUpdateRow(Row row) throws IOException{ + Row tmprow=getRow(row.getId()); + if(tmprow==null){ + addRow(row); + }else{ + updateRow(row); + } + } + + /** + * Updates a row stored in this table. + */ + public void updateRow(Row row) throws IOException{ + TableIndexEntry entry=null; + // Handle index entry caching + if(INDEXCACHESIZE>0){ + synchronized(indexcache){ + entry=getCacheEntry(row.getId()); + if(entry==null){ + entry=index.scanIndex(row.getId()); + addCacheEntry(entry); + } + } + }else{ + entry=index.scanIndex(row.getId()); + } + if(entry.getRowSize()>=row.getSize()){ + // Add to the existing location + switch(entry.getLocation()){ + case FILEA :synchronized(filealock){ + if(filearandom==null){ + filearandom=new RandomAccessFile(getFileName(FILEA),"rw"); + fca=filearandom.getChannel(); + } + filearandom.seek(entry.getPosition()); + row.writeToFile(filearandom); + + fca.force(false); + } + break; + case FILEB :synchronized(fileblock){ + if(filebrandom==null){ + filebrandom=new RandomAccessFile(getFileName(FILEB),"rw"); + fcb=filebrandom.getChannel(); + } + filebrandom.seek(entry.getPosition()); + row.writeToFile(filebrandom); + + fcb.force(false); + } + break; + } + }else{ + if(rowswitch){ + updateRowA(row); + }else{ + updateRowB(row); + } + rowswitch=!rowswitch; + } + synchronized(statlock){ + stat_update++; + stat_update_size+=row.getSize(); + } + } + + private void updateRowA(Row row) throws IOException{ + synchronized(filealock){ + openFile(FILEA); + int pre=fileastream.size(); + row.writeToStream(fileastream); + int post=fileastream.size(); + fileastream.flush(); + index.updateEntry(row.getId(),row.getSize(),FILEA,fileaposition); + + // Handle index entry caching + if(INDEXCACHESIZE>0){ + updateCacheEntry(new TableIndexEntry(row.getId(),row.getSize(),FILEA,fileaposition)); + } + fileaposition+=Row.calcSize(pre,post); + } + } + + private void updateRowB(Row row) throws IOException{ + synchronized(fileblock){ + openFile(FILEB); + int pre=filebstream.size(); + row.writeToStream(filebstream); + int post=filebstream.size(); + filebstream.flush(); + index.updateEntry(row.getId(),row.getSize(),FILEB,filebposition); + // Handle index entry caching + // Handle index entry caching + if(INDEXCACHESIZE>0){ + updateCacheEntry(new TableIndexEntry(row.getId(),row.getSize(),FILEB,filebposition)); + } + filebposition+=Row.calcSize(pre,post); + } + } + + /** + * Marks a row as deleted in the index. + * Be aware that the space consumed by the row is not actually reclaimed. + */ + public void deleteRow(Row row) throws IOException{ + // Handle index entry caching + if(INDEXCACHESIZE>0){ + removeCacheEntry(row.getId()); + } + index.updateEntry(row.getId(),row.getSize(),DELETE,0); + synchronized(statlock){ + stat_delete++; + } + } + + /** + * Returns a tuplestream containing the given list of rows + */ + public TupleStream getRows(List rows) throws IOException{ + return new IndexedTableReader(this,index.scanIndex(rows)); + } + + /** + * Returns a tuplestream containing the rows matching the given rowmatcher + */ + public TupleStream getRows(RowMatcher matcher) throws IOException{ + return new IndexedTableReader(this,index.scanIndex(),matcher); + } + + /** + * Returns a tuplestream containing those rows in the given list that matches the given RowMatcher + */ + public TupleStream getRows(List rows,RowMatcher matcher) throws IOException{ + return new IndexedTableReader(this,index.scanIndex(rows),matcher); + } + + /** + * Returns a tuplestream of all rows in this table. + */ + public TupleStream getRows() throws IOException{ + // return new TableReader(this); + return new IndexedTableReader(this,index.scanIndex()); + } + + /** + * Returns a single row stored in this table. + * If the row does not exist in the table, null will be returned. + */ + public Row getRow(String id) throws IOException{ + TableIndexEntry entry=null; + // Handle index entry caching + if(INDEXCACHESIZE>0){ + // System.out.println("in h"); + synchronized(indexcache){ + entry=getCacheEntry(id); + // System.out.println(entry); + if(entry==null){ + entry=index.scanIndex(id); + if(entry!=null){ + addCacheEntry(entry); + } + } + } + }else{ + entry=index.scanIndex(id); + } + if(entry!=null){ + long dataoffset=0; + DataInputStream data=null; + // System.out.println(entry); + if(entry.location==Table.FILEA){ + data=new DataInputStream(new BufferedInputStream(new FileInputStream(getFileName(Table.FILEA)))); + }else if(entry.location==Table.FILEB){ + data=new DataInputStream(new BufferedInputStream(new FileInputStream(getFileName(Table.FILEB)))); + } + if(data!=null){ + while(dataoffset!=entry.position){ + dataoffset+=data.skipBytes((int)(entry.position-dataoffset)); + } + Row row=Row.readFromStream(data); + data.close(); + synchronized(statlock){ + stat_read++; + stat_read_size+=row.getSize(); + } + return row; + } + + } + return null; + } + } \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTableTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTableTransactional.java new file mode 100644 index 00000000..228c5bb3 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/DualFileTableTransactional.java @@ -0,0 +1,777 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + + + +import java.io.*; +import java.util.*; +import java.nio.channels.*; +import com.solidosystems.tuplesoup.filter.*; +import dstm2.atomic; +import dstm2.Thread; +import dstm2.factory.Factory; +import dstm2.util.StringKeyHashMap; +import java.util.concurrent.Callable; + +/** + * The table stores a group of rows. + * Every row must have a unique id within a table. + */ +public class DualFileTableTransactional implements TableTransactional{ + + + private int INDEXCACHESIZE=8192; + + private String filealock="filea-dummy"; + private String fileblock="fileb-dummy"; + + private DataOutputStream fileastream=null; + private DataOutputStream filebstream=null; + private RandomAccessFile filearandom=null; + private RandomAccessFile filebrandom=null; + FileChannel fca=null; + FileChannel fcb=null; + + private TableIndexTransactional index=null; + +// private long fileaposition=0; + // private long filebposition=0; + + private boolean rowswitch=true; + + private String title; + private String location; + + private TableIndexNodeTransactional indexcachefirst; + private TableIndexNodeTransactional indexcachelast; + //private int indexcacheusage; + + private StringKeyHashMap indexcache; + //private Hashtable indexcache; + + static Factory factory = Thread.makeFactory(DualFileTableTSInf.class); + // static Factory factory = Thread.makeFactory(FinancialTransactionDS.class); + DualFileTableTSInf atomicfields; + // Statistic counters + + 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(); + Long getFileaposition(); + Long getFilebposition(); + Integer getIndexcacheusage(); + + 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); + void setIndexcacheusage(Integer val); + void setFileaposition(Long val); + void setFilebposition(Long val); + } + + /*long stat_add=0; + long stat_update=0; + long stat_delete=0; + long stat_add_size=0; + long stat_update_size=0; + long stat_read_size=0; + long stat_read=0; + long stat_cache_hit=0; + long stat_cache_miss=0; + long stat_cache_drop=0;*/ + + protected String statlock="stat-dummy"; + + /** + * Return the current values of the statistic counters and reset them. + * The current counters are: + *
    + *
  • stat_table_add + *
  • stat_table_update + *
  • stat_table_delete + *
  • stat_table_add_size + *
  • stat_table_update_size + *
  • stat_table_read_size + *
  • stat_table_read + *
  • stat_table_cache_hit + *
  • stat_table_cache_miss + *
  • stat_table_cache_drop + *
+ * Furthermore, the index will be asked to deliver separate index specific counters + */ + public Hashtable readStatistics(){ + + // synchronized(statlock){ + return Thread.doIt(new Callable>() { + public Hashtable call() throws Exception{ + Hashtable hash=new Hashtable(); + 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(Long.valueOf(0)); + atomicfields.setstat_update(Long.valueOf(0)); + atomicfields.setstat_delete(Long.valueOf(0)); + atomicfields.setstat_add_size(Long.valueOf(0)); + atomicfields.setstat_update_size(Long.valueOf(0)); + atomicfields.setstat_read_size(Long.valueOf(0)); + atomicfields.getstat_read_size(); + atomicfields.setstat_read(Long.valueOf(0)); + atomicfields.setstat_cache_hit(Long.valueOf(0)); + atomicfields.setstat_cache_miss(Long.valueOf(0)); + atomicfields.setstat_cache_drop(Long.valueOf(0)); + Hashtable ihash=index.readStatistics(); + hash.putAll(ihash); + return hash; + } + }); + + } + + /** + * Create a new table object with the default flat index model + */ + + + /** + * Create a new table object with a specific index model + */ + public DualFileTableTransactional(String title,String location, int indextype) throws IOException{ + atomicfields = factory.create(); + + this.title=title; + this.location=location; + if(!this.location.endsWith(File.separator))this.location+=File.separator; + switch(indextype){ + case PAGED : index=new PagedIndexTransactional(getFileName(INDEX)); + break; + + } + indexcachefirst=null; + indexcachelast=null; + atomicfields.setFileaposition(Long.valueOf(0)); + atomicfields.setFilebposition(Long.valueOf(0)); + atomicfields.setstat_update_size(Long.valueOf(0)); + atomicfields.setstat_update(Long.valueOf(0)); + atomicfields.setstat_read_size(Long.valueOf(0)); + atomicfields.setstat_read(Long.valueOf(0)); + atomicfields.setstat_delete(Long.valueOf(0)); + atomicfields.setstat_cache_miss(Long.valueOf(0)); + atomicfields.setstat_cache_hit(Long.valueOf(0)); + atomicfields.setstat_cache_drop(Long.valueOf(0)); + atomicfields.setstat_add_size(Long.valueOf(0)); + atomicfields.setstat_add(Long.valueOf(0)); + atomicfields.setIndexcacheusage(Integer.valueOf(0)); + indexcache=new StringKeyHashMap(); + } + + /** + * Set the maximal allowable size of the index cache. + */ + public void setIndexCacheSize(int newsize){ + INDEXCACHESIZE=newsize; + } + + /** + * Close all open file streams + */ + public void close(){ + try{ + if(fileastream!=null)fileastream.close(); + if(filebstream!=null)filebstream.close(); + if(filearandom!=null)filearandom.close(); + if(filebrandom!=null)filebrandom.close(); + index.close(); + }catch(Exception e){} + } + + /** + * Returns the name of this table + */ + public String getTitle(){ + return title; + } + + /** + * Returns the location of this tables datafiles + */ + public String getLocation(){ + return location; + } + + protected String getFileName(int type){ + switch(type){ + case FILEB : return location+title+".a"; + case FILEA : return location+title+".b"; + case INDEX : return location+title+".index"; + } + return null; + } + + /** + * Delete the files created by this table object. + * Be aware that this will delete any data stored in this table! + */ + public void deleteFiles(){ + try{ + File ftest=new File(getFileName(FILEA)); + ftest.delete(); + }catch(Exception e){} + try{ + File ftest=new File(getFileName(FILEB)); + ftest.delete(); + }catch(Exception e){} + try{ + File ftest=new File(getFileName(INDEX)); + ftest.delete(); + }catch(Exception e){} + } + + private /*synchronized*/ void openFile(int type) throws IOException{ + switch(type){ + case FILEA : if(fileastream==null){ + System.out.println("file a " + getFileName(FILEA)); + fileastream=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(getFileName(FILEA),true))); + File ftest=new File(getFileName(FILEA)); + atomicfields.setFileaposition(ftest.length()); + } + break; + case FILEB : if(filebstream==null){ + System.out.println("file b " + getFileName(FILEB)); + filebstream=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(getFileName(FILEB),true))); + File ftest=new File(getFileName(FILEB)); + atomicfields.setFilebposition(ftest.length()); + } + break; + } + + } + + /** + * Adds a row of data to this table. + */ + public void addRow(RowTransactional row) throws IOException{ + // Distribute new rows between the two datafiles by using the rowswitch, but don't spend time synchronizing... this does not need to be acurate! + if(rowswitch){ + addRowA(row); + }else{ + addRowB(row); + } + rowswitch=!rowswitch; + } + + private void addCacheEntry(TableIndexEntryTransactional entry){ + // synchronized(indexcache){ + if(atomicfields.getIndexcacheusage()>INDEXCACHESIZE){ + // remove first entry + TableIndexNodeTransactional node=indexcachefirst; + indexcache.remove(node.getData().getId()); + atomicfields.setIndexcacheusage(atomicfields.getIndexcacheusage()-1); + // synchronized(statlock){ + atomicfields.setstat_cache_drop(atomicfields.getstat_cache_drop()+1); + // } + indexcachefirst=node.getNext(); + if(indexcachefirst==null){ + indexcachelast=null; + }else{ + indexcachefirst.setPrevious(null); + } + } + TableIndexNodeTransactional node=new TableIndexNodeTransactional(indexcachelast,entry); + if(indexcachelast!=null){ + indexcachelast.setNext(node); + } + if(indexcachefirst==null){ + indexcachefirst=node; + } + indexcachelast=node; + indexcache.put(entry.getId(),node); + atomicfields.setIndexcacheusage(atomicfields.getIndexcacheusage()+1); + // } + } + + private synchronized void addRowA(RowTransactional row) throws IOException{ + synchronized(filealock){ + synchronized(index){ + final Vector args = new Vector(); + args.add(row); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + openFile(FILEA); + int pre=fileastream.size(); + ((RowTransactional)args.get(0)).writeToStream(fileastream); + int post=fileastream.size(); + fileastream.flush(); + + //synchronized(statlock){ + atomicfields.setstat_add(atomicfields.getstat_add()+1); + atomicfields.setstat_add_size(atomicfields.getstat_add_size()+((RowTransactional)args.get(0)).getSize()); + //} + + index.addEntry(((RowTransactional)args.get(0)).getId(),((RowTransactional)args.get(0)).getSize(),FILEA,atomicfields.getFilebposition()); + if(INDEXCACHESIZE>0){ + TableIndexEntryTransactional entry=new TableIndexEntryTransactional(((RowTransactional)args.get(0)).getId(),((RowTransactional)args.get(0)).getSize(),FILEA,atomicfields.getFileaposition()); + addCacheEntry(entry); + } + atomicfields.setFileaposition(atomicfields.getFileaposition()+RowTransactional.calcSize(pre,post)); + return true; + } + }); + } + } + } + private synchronized void addRowB(RowTransactional row) throws IOException{ + synchronized(fileblock){ + synchronized(index){ + + final Vector args = new Vector(); + args.add(row); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + openFile(FILEB); + int pre=filebstream.size(); + ((RowTransactional)args.get(0)).writeToStream(filebstream); + int post=filebstream.size(); + filebstream.flush(); + //int post=filebstream.size(); + //filebstream.flush(); + //synchronized(statlock){ + atomicfields.setstat_add(atomicfields.getstat_add()+1); + atomicfields.setstat_add_size(atomicfields.getstat_add_size()+((RowTransactional)args.get(0)).getSize()); + // } + index.addEntry(((RowTransactional)args.get(0)).getId(),((RowTransactional)args.get(0)).getSize(),FILEB,atomicfields.getFilebposition()); + if(INDEXCACHESIZE>0){ + TableIndexEntryTransactional entry=new TableIndexEntryTransactional(((RowTransactional)args.get(0)).getId(),((RowTransactional)args.get(0)).getSize(),FILEB,atomicfields.getFilebposition()); + addCacheEntry(entry); + } + atomicfields.setFilebposition(atomicfields.getFilebposition()+RowTransactional.calcSize(pre,post)); + return true; + } + }); + } + } + } + + + private void updateCacheEntry(TableIndexEntryTransactional entry){ + + //synchronized(indexcache){ + if(indexcache.containsKey(entry.getId())){ + TableIndexNodeTransactional node=indexcache.get(entry.getId()); + node.setData(entry); + if(node!=indexcachelast){ + if(node==indexcachefirst){ + indexcachefirst=node.getNext(); + } + node.remove(); + indexcachelast.setNext(node); + node.setPrevious(indexcachelast); + node.setNext(null); + indexcachelast=node; + } + }else{ + addCacheEntry(entry); + } + // return true; + // } + // }); + } + + private void removeCacheEntry(String id){ + //synchronized(indexcache){ + final Vector args = new Vector(); + args.add(id); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + + if(indexcache.containsKey((String)(args.get(0)))){ + TableIndexNodeTransactional node=indexcache.get((String)(args.get(0))); + indexcache.remove((String)(args.get(0))); + if(atomicfields.getIndexcacheusage()==1){ + indexcachefirst=null; + indexcachelast=null; + atomicfields.setIndexcacheusage(0); + return true; + } + if(node==indexcachefirst){ + indexcachefirst=node.getNext(); + indexcachefirst.setPrevious(null); + }else if(node==indexcachelast){ + indexcachelast=node.getPrevious(); + indexcachelast.setNext(null); + }else{ + node.remove(); + } + atomicfields.setIndexcacheusage(atomicfields.getIndexcacheusage()-1); + // synchronized(statlock){ + atomicfields.setstat_cache_drop(atomicfields.getstat_cache_drop()+1); + + // } + } + return true; + } + }); + } + + private TableIndexEntryTransactional getCacheEntry(String id){ + + //synchronized(indexcache){ + if(indexcache.containsKey(id)){ + TableIndexNodeTransactional node=indexcache.get(id); + if(node!=indexcachelast){ + if(node==indexcachefirst){ + indexcachefirst=node.getNext(); + } + node.remove(); + indexcachelast.setNext(node); + node.setPrevious(indexcachelast); + node.setNext(null); + indexcachelast=node; + } + // synchronized(statlock){ + atomicfields.setstat_cache_hit(atomicfields.getstat_cache_hit()+1); + // } + return node.getData(); + } + + //synchronized(statlock){ + atomicfields.setstat_cache_miss(atomicfields.getstat_cache_miss()+1); + + //} + return null; + } + + /** + * Adds a row to this table if it doesn't already exist, if it does it updates the row instead. + * This method is much slower than directly using add or update, so only use it if you don't know wether or not the row already exists. + */ + public void addOrUpdateRow(RowTransactional row) throws IOException{ + RowTransactional tmprow=getRow(row.getId()); + if(tmprow==null){ + addRow(row); + }else{ + updateRow(row); + } + } + + /** + * Updates a row stored in this table. + */ + public void updateRow(RowTransactional row) throws IOException{ + TableIndexEntryTransactional entry=null; + final Vector args = new Vector(); + args.add(row); + + // Handle index entry caching + if(INDEXCACHESIZE>0){ + synchronized (index){ + entry = Thread.doIt(new Callable() { + public TableIndexEntryTransactional call() throws Exception { + TableIndexEntryTransactional entry;// = (TableIndexEntryTransactional) (args.get(1)); + RowTransactional row = (RowTransactional) (args.get(0)); + entry = getCacheEntry(row.getId()); + if(entry==null){ + entry=index.scanIndex(row.getId()); + addCacheEntry(entry); + } + return entry; + } + }); + } + /* synchronized(indexcache){ + entry=getCacheEntry(row.getId()); + if(entry==null){ + entry=index.scanIndex(row.getId()); + addCacheEntry(entry); + } + }*/ + }else{ + entry=index.scanIndexTransactional(row.getId()); + } + args.add(entry); + if(entry.getRowSize()>=row.getSize()){ + // Add to the existing location + switch(entry.getLocation()){ + case FILEA : + synchronized(filealock){ + Thread.doIt(new Callable() { + public Boolean call() throws Exception { + if(filearandom==null){ + filearandom=new RandomAccessFile(getFileName(FILEA),"rw"); + // fca=filearandom.getChannel(); + } + filearandom.seek(((TableIndexEntryTransactional) (args.get(1))).getPosition()); + ((RowTransactional) (args.get(0))).writeToFile(filearandom); + fca.force(false); + return true; + + } + }); + } + break; + case FILEB : + synchronized(fileblock){ + Thread.doIt(new Callable() { + public Boolean call() throws Exception { + if(filebrandom==null){ + filebrandom=new RandomAccessFile(getFileName(FILEB),"rw"); + fcb=filebrandom.getChannel(); + } + filebrandom.seek(((TableIndexEntryTransactional) (args.get(1))).getPosition()); + ((RowTransactional) (args.get(0))).writeToFile(filebrandom); + fcb.force(false); + return true; + } + }); + } + break; + } + }else{ + if(rowswitch){ + updateRowA(row); + }else{ + updateRowB(row); + } + rowswitch=!rowswitch; + } + //synchronized(statlock){ + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + atomicfields.setstat_update(atomicfields.getstat_update()+1); + atomicfields.setstat_update_size(atomicfields.getstat_update_size()+((RowTransactional) (args.get(0))).getSize()); + return true; + } + }); + } + + private synchronized void updateRowA(RowTransactional row) throws IOException{ + final Vector args = new Vector(); + args.add(row); + System.out.println("b"); + synchronized(filealock){ + synchronized (index){ + // synchronized (index){ + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + + System.out.println("add a"); + openFile(FILEA); + int pre=filebstream.size(); + ((RowTransactional)(args.get(0))).writeToStream(fileastream); + int post=filebstream.size(); + fileastream.flush(); + index.updateEntry(((RowTransactional)(args.get(0))).getId(),((RowTransactional)(args.get(0))).getSize(),FILEA,atomicfields.getFileaposition()); + + // Handle index entry caching + if(INDEXCACHESIZE>0){ + updateCacheEntry(new TableIndexEntryTransactional(((RowTransactional)(args.get(0))).getId(),((RowTransactional)(args.get(0))).getSize(),FILEA,atomicfields.getFileaposition())); + } + atomicfields.setFileaposition(atomicfields.getFilebposition()+RowTransactional.calcSize(pre,post)); + return true; + } + }); + // } + } + } + } + + private synchronized void updateRowB(RowTransactional row) throws IOException{ + final Vector args = new Vector(); + System.out.println("b"); + args.add(row); + synchronized(fileblock){ + synchronized (index){ + //synchronized (index){ + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + System.out.println("add b"); + + openFile(FILEB); + int pre=filebstream.size(); + ((RowTransactional)(args.get(0))).writeToStream(filebstream); + int post=filebstream.size(); + filebstream.flush(); + index.updateEntry(((RowTransactional)(args.get(0))).getId(),((RowTransactional)(args.get(0))).getSize(),FILEB,atomicfields.getFilebposition()); + // Handle index entry caching + // Handle index entry caching + if(INDEXCACHESIZE>0){ + updateCacheEntry(new TableIndexEntryTransactional(((RowTransactional)(args.get(0))).getId(),((RowTransactional)(args.get(0))).getSize(),FILEB,atomicfields.getFilebposition())); + } + atomicfields.setFilebposition(atomicfields.getFilebposition()+RowTransactional.calcSize(pre,post)); + return true; + } + }); + // } + } + } + } + + /** + * Marks a row as deleted in the index. + * Be aware that the space consumed by the row is not actually reclaimed. + */ + public void deleteRow(RowTransactional row) throws IOException{ + // Handle index entry caching + if(INDEXCACHESIZE>0){ + removeCacheEntry(row.getId()); + } + index.updateEntryTransactional(row.getId(),row.getSize(),DELETE,0); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + //synchronized(statlock){ + atomicfields.setstat_delete(atomicfields.getstat_delete()+1); + return true; + } + }); + // } + } + + /** + * Returns a tuplestream containing the given list of rows + */ + public TupleStreamTransactional getRows(List rows) throws IOException{ + return new IndexedTableReaderTransactional(this,index.scanIndex(rows)); + } + + /** + * Returns a tuplestream containing the rows matching the given rowmatcher + */ + public TupleStreamTransactional getRows(RowMatcherTransactional matcher) throws IOException{ + return new IndexedTableReaderTransactional(this,index.scanIndex(),matcher); + } + + /** + * Returns a tuplestream containing those rows in the given list that matches the given RowMatcher + */ + public TupleStreamTransactional getRows(List rows,RowMatcherTransactional matcher) throws IOException{ + return new IndexedTableReaderTransactional(this,index.scanIndex(rows),matcher); + } + + /** + * Returns a tuplestream of all rows in this table. + */ + public TupleStreamTransactional getRows() throws IOException{ + // return new TableReader(this); + return new IndexedTableReaderTransactional(this,index.scanIndex()); + } + + /** + * Returns a single row stored in this table. + * If the row does not exist in the table, null will be returned. + */ + public RowTransactional getRow(String id) throws IOException{ + TableIndexEntryTransactional entry=null; + final Vector args = new Vector(); + args.add(id); + // args.add(entry); + // Handle index entry caching + if(INDEXCACHESIZE>0){ + + //synchronized(indexcache){ + synchronized (index){ + entry = Thread.doIt(new Callable() { + public TableIndexEntryTransactional call() throws Exception{ + TableIndexEntryTransactional entry;// = (TableIndexEntryTransactional) (args.get(1)); + String id = (String) (args.get(0)); + entry=getCacheEntry(id); + // System.out.println("presalam " + (TableIndexEntryTransactional) (args.get(1))); + if(entry==null){ + entry=index.scanIndex(id); + if(entry!=null){ + addCacheEntry(entry); + } + } + return entry; + } + }); + } + + }else{ + entry=index.scanIndexTransactional(id); + } +// entry = (TableIndexEntryTransactional) (args.get(1)); + // args.clear(); + + if(entry!=null){ + long dataoffset=0; + DataInputStream data=null; + + if(entry.getLocation()==TableTransactional.FILEA){ + data=new DataInputStream(new BufferedInputStream(new FileInputStream(getFileName(TableTransactional.FILEA)))); + }else if(entry.getLocation()==TableTransactional.FILEB){ + data=new DataInputStream(new BufferedInputStream(new FileInputStream(getFileName(TableTransactional.FILEB)))); + } + if(data!=null){ + while(dataoffset!=entry.getPosition()){ + dataoffset+=data.skipBytes((int)(entry.getPosition()-dataoffset)); + } + RowTransactional row=RowTransactional.readFromStream(data); + data.close(); + final Vector args2 = new Vector(); + args2.add(row); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + //synchronized(statlock){ + atomicfields.setstat_read(atomicfields.getstat_read()+1); + atomicfields.setstat_read_size(atomicfields.getstat_read_size()+((RowTransactional)args2.get(0)).getSize()); + return true; + } + }); + return row; + } + + } + return null; + } + } \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTable.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTable.java new file mode 100644 index 00000000..c0588cd7 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTable.java @@ -0,0 +1,225 @@ + +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; +import java.nio.channels.*; +import com.solidosystems.tuplesoup.filter.*; + +/** + * The table stores a group of rows. + * Every row must have a unique id within a table. + */ +public class HashedTable implements Table{ + private int TABLESETSIZE=5; + private List tableset; + private String title; + private String location; + + + + /** + * Create a new table object with a specific index model + */ + public HashedTable(String title,String location, int indextype) throws IOException{ + this.title=title; + this.location=location; + tableset=new ArrayList
(); + for(int i=0;i readStatistics(){ + Hashtable results=new Hashtable(); + for(int i=0;i tmp=tableset.get(i).readStatistics(); + Set keys=tmp.keySet(); + Iterator it=keys.iterator(); + while(it.hasNext()){ + String key=it.next(); + long value=tmp.get(key); + if(results.containsKey(key)){ + results.put(key,results.get(key)+value); + }else{ + results.put(key,value); + } + } + } + return results; + } + + /** + * Returns the name of this table + */ + public String getTitle(){ + return title; + } + + /** + * Returns the location of this tables datafiles + */ + public String getLocation(){ + return location; + } + + /** + * Delete the files created by this table object. + * Be aware that this will delete any data stored in this table! + */ + public void deleteFiles(){ + for(int i=0;i rows) throws IOException{ + List> listset=new ArrayList>(); + for(int i=0;i()); + } + for(int i=0;i0){ + merge.addStream(tableset.get(i).getRows(listset.get(i))); + } + } + return merge; + } + + /** + * Returns a tuplestream containing the rows matching the given rowmatcher + */ + public TupleStream getRows(RowMatcher matcher) throws IOException{ + TupleStreamMerger merge=new TupleStreamMerger(); + for(int i=0;i rows,RowMatcher matcher) throws IOException{ + List> listset=new ArrayList>(); + for(int i=0;i()); + } + for(int i=0;i0){ + merge.addStream(tableset.get(i).getRows(listset.get(i),matcher)); + } + } + return merge; + } + + /** + * Marks a row as deleted in the index. + * Be aware that the space consumed by the row is not actually reclaimed. + */ + public void deleteRow(Row row) throws IOException{ + getTableForId(row.getId()).deleteRow(row); + } + + /** + * Adds a row of data to this table. + */ + public void addRow(Row row) throws IOException{ + getTableForId(row.getId()).addRow(row); + } + + /** + * Adds a row to this table if it doesn't already exist, if it does it updates the row instead. + * This method is much slower than directly using add or update, so only use it if you don't know wether or not the row already exists. + */ + public void addOrUpdateRow(Row row) throws IOException{ + getTableForId(row.getId()).addOrUpdateRow(row); + } + + /** + * Updates a row stored in this table. + */ + public void updateRow(Row row) throws IOException{ + getTableForId(row.getId()).updateRow(row); + } +} diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTableTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTableTransactional.java new file mode 100644 index 00000000..e9b229c5 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/HashedTableTransactional.java @@ -0,0 +1,225 @@ + +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; +import java.nio.channels.*; +import com.solidosystems.tuplesoup.filter.*; + +/** + * The table stores a group of rows. + * Every row must have a unique id within a table. + */ +public class HashedTableTransactional implements TableTransactional{ + private int TABLESETSIZE=5; + private List tableset; + private String title; + private String location; + + + + /** + * Create a new table object with a specific index model + */ + public HashedTableTransactional(String title,String location, int indextype) throws IOException{ + this.title=title; + this.location=location; + tableset=new ArrayList(); + for(int i=0;i readStatistics(){ + Hashtable results=new Hashtable(); + for(int i=0;i tmp=tableset.get(i).readStatistics(); + Set keys=tmp.keySet(); + Iterator it=keys.iterator(); + while(it.hasNext()){ + String key=it.next(); + long value=tmp.get(key); + if(results.containsKey(key)){ + results.put(key,results.get(key)+value); + }else{ + results.put(key,value); + } + } + } + return results; + } + + /** + * Returns the name of this table + */ + public String getTitle(){ + return title; + } + + /** + * Returns the location of this tables datafiles + */ + public String getLocation(){ + return location; + } + + /** + * Delete the files created by this table object. + * Be aware that this will delete any data stored in this table! + */ + public void deleteFiles(){ + for(int i=0;i rows) throws IOException{ + List> listset=new ArrayList>(); + for(int i=0;i()); + } + for(int i=0;i0){ + merge.addStream(tableset.get(i).getRows(listset.get(i))); + } + } + return merge; + } + + /** + * Returns a tuplestream containing the rows matching the given rowmatcher + */ + public TupleStreamTransactional getRows(RowMatcherTransactional matcher) throws IOException{ + TupleStreamMergerTransactional merge=new TupleStreamMergerTransactional(); + for(int i=0;i rows,RowMatcherTransactional matcher) throws IOException{ + List> listset=new ArrayList>(); + for(int i=0;i()); + } + for(int i=0;i0){ + merge.addStream(tableset.get(i).getRows(listset.get(i),matcher)); + } + } + return merge; + } + + /** + * Marks a row as deleted in the index. + * Be aware that the space consumed by the row is not actually reclaimed. + */ + public void deleteRow(RowTransactional row) throws IOException{ + getTableForId(row.getId()).deleteRow(row); + } + + /** + * Adds a row of data to this table. + */ + public void addRow(RowTransactional row) throws IOException{ + getTableForId(row.getId()).addRow(row); + } + + /** + * Adds a row to this table if it doesn't already exist, if it does it updates the row instead. + * This method is much slower than directly using add or update, so only use it if you don't know wether or not the row already exists. + */ + public void addOrUpdateRow(RowTransactional row) throws IOException{ + getTableForId(row.getId()).addOrUpdateRow(row); + } + + /** + * Updates a row stored in this table. + */ + public void updateRow(RowTransactional row) throws IOException{ + getTableForId(row.getId()).updateRow(row); + } +} diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReader.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReader.java new file mode 100644 index 00000000..0684c3b8 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReader.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.core; + + import com.solidosystems.tuplesoup.filter.*; + import java.io.*; + import java.util.*; + +public class IndexedTableReader extends TupleStream{ + private DataInputStream fileastream=null; + private DataInputStream filebstream=null; + private long fileaposition=0; + private long filebposition=0; + + private Listfileaentries; + private Listfilebentries; + + private Listentries; + + private Hashtablefileabuffer; + private Hashtablefilebbuffer; + + private Listrows; + private int rowpointer; + private Row next=null; + + private DualFileTable table; + + private RowMatcher matcher=null; + + public IndexedTableReader(DualFileTable table,Listentries) throws IOException{ + this.table=table; + this.rows=rows; + rowpointer=0; + + this.entries=entries; + fileaentries=new ArrayList(); + filebentries=new ArrayList(); + + Iterator it=entries.iterator(); + while(it.hasNext()){ + TableIndexEntry entry=it.next(); + // TODO: we really shouldn't get nulls here + if(entry!=null){ + if(entry.location==Table.FILEA){ + fileaentries.add(entry); + }else if(entry.location==Table.FILEB){ + filebentries.add(entry); + } + } + } + + Collections.sort(fileaentries); + Collections.sort(filebentries); + + fileabuffer=new Hashtable(); + filebbuffer=new Hashtable(); + + readNext(); + } + + + public IndexedTableReader(DualFileTable table,Listentries,RowMatcher matcher) throws IOException{ + this.table=table; + this.rows=rows; + rowpointer=0; + this.matcher=matcher; + + this.entries=entries; + fileaentries=new ArrayList(); + filebentries=new ArrayList(); + + Iterator it=entries.iterator(); + while(it.hasNext()){ + TableIndexEntry entry=it.next(); + // TODO: we really shouldn't get nulls here + if(entry!=null){ + if(entry.location==Table.FILEA){ + fileaentries.add(entry); + }else if(entry.location==Table.FILEB){ + filebentries.add(entry); + } + } + } + + Collections.sort(fileaentries); + Collections.sort(filebentries); + + fileabuffer=new Hashtable(); + filebbuffer=new Hashtable(); + + readNext(); + } + + private void readNextFromFileA(TableIndexEntry entry) throws IOException{ + if(fileabuffer.containsKey(entry.id)){ + next=fileabuffer.remove(entry.id); + return; + } + while(true){ + if(fileaentries.size()>0){ + TableIndexEntry nextfilea=fileaentries.remove(0); + if(fileastream==null){ + fileastream=new DataInputStream(new BufferedInputStream(new FileInputStream(table.getFileName(Table.FILEA)))); + fileaposition=0; + } + if(fileaposition>nextfilea.position){ + // We have already read this entry... skip it + // readNextFromFileA(entry); + // return; + }else{ + while(fileaposition!=nextfilea.position){ + fileaposition+=fileastream.skipBytes((int)(nextfilea.position-fileaposition)); + } + Row row=Row.readFromStream(fileastream); + synchronized(table.statlock){ + table.stat_read_size+=row.getSize(); + table.stat_read++; + } + fileaposition+=row.getSize(); + if(row.getId().equals(entry.id)){ + next=row; + return; + }else{ + fileabuffer.put(row.getId(),row); + // readNextFromFileA(entry); + } + } + }else{ + next=null; + return; + } + } + } + + private void readNextFromFileB(TableIndexEntry entry) throws IOException{ + if(filebbuffer.containsKey(entry.id)){ + next=filebbuffer.remove(entry.id); + return; + } + while(true){ + if(filebentries.size()>0){ + TableIndexEntry nextfileb=filebentries.remove(0); + if(filebstream==null){ + filebstream=new DataInputStream(new BufferedInputStream(new FileInputStream(table.getFileName(Table.FILEB)))); + filebposition=0; + } + if(filebposition>nextfileb.position){ + // We have already read this entry... skip it + // readNextFromFileB(entry); + // return; + }else{ + while(filebposition!=nextfileb.position){ + filebposition+=filebstream.skipBytes((int)(nextfileb.position-filebposition)); + } + Row row=Row.readFromStream(filebstream); + synchronized(table.statlock){ + table.stat_read_size+=row.getSize(); + table.stat_read++; + } + filebposition+=row.getSize(); + if(row.getId().equals(entry.id)){ + next=row; + return; + }else{ + filebbuffer.put(row.getId(),row); + // readNextFromFileB(entry); + } + } + }else{ + next=null; + return; + } + } + } + + private void readNext() throws IOException{ + if(entries.size()>rowpointer){ + TableIndexEntry entry=entries.get(rowpointer++); + if(entry!=null){ + switch(entry.location){ + case Table.FILEA : readNextFromFileA(entry); + // return; + break; + case Table.FILEB : readNextFromFileB(entry); + // return; + break; + } + if(next!=null){ + if(matcher!=null){ + if(!matcher.matches(next)){ + readNext(); + } + } + } + return; + }else{ + readNext(); + return; + } + } + try{ + if(fileastream!=null)fileastream.close(); + }catch(Exception e){} + try{ + if(filebstream!=null)filebstream.close(); + }catch(Exception e){} + next=null; + } + + public boolean hasNext(){ + if(next!=null)return true; + return false; + } + + public Row next(){ + try{ + if(next!=null){ + Row tmp=next; + readNext(); + return tmp; + } + }catch(Exception e){ + e.printStackTrace(); + } + return null; + } + + public void remove(){ + + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReaderTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReaderTransactional.java new file mode 100644 index 00000000..db2b16ca --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/IndexedTableReaderTransactional.java @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.core; + + + import com.solidosystems.tuplesoup.filter.*; + import java.io.*; + import java.util.*; + import java.util.concurrent.Callable; + import dstm2.Thread; + + +public class IndexedTableReaderTransactional extends TupleStreamTransactional{ + + + + + private DataInputStream fileastream=null; + private DataInputStream filebstream=null; + private long fileaposition=0; + private long filebposition=0; + + private Listfileaentries; + private Listfilebentries; + + private Listentries; + + private Hashtablefileabuffer; + private Hashtablefilebbuffer; + + private Listrows; + private int rowpointer; + private RowTransactional next=null; + + private DualFileTableTransactional table; + + private RowMatcherTransactional matcher=null; + + public IndexedTableReaderTransactional(DualFileTableTransactional table,Listentries) throws IOException{ + this.table=table; + this.rows=rows; + rowpointer=0; + + this.entries=entries; + fileaentries=new ArrayList(); + filebentries=new ArrayList(); + + Iterator it=entries.iterator(); + while(it.hasNext()){ + TableIndexEntryTransactional entry=it.next(); + // TODO: we really shouldn't get nulls here + if(entry!=null){ + if(entry.getLocation()==TableTransactional.FILEA){ + fileaentries.add(entry); + }else if(entry.getLocation()==TableTransactional.FILEB){ + filebentries.add(entry); + } + } + } + + Collections.sort(fileaentries); + Collections.sort(filebentries); + + fileabuffer=new Hashtable(); + filebbuffer=new Hashtable(); + + readNext(); + } + + + public IndexedTableReaderTransactional(DualFileTableTransactional table,Listentries,RowMatcherTransactional matcher) throws IOException{ + this.table=table; + this.rows=rows; + rowpointer=0; + this.matcher=matcher; + + this.entries=entries; + fileaentries=new ArrayList(); + filebentries=new ArrayList(); + + Iterator it=entries.iterator(); + while(it.hasNext()){ + TableIndexEntryTransactional entry=it.next(); + // TODO: we really shouldn't get nulls here + if(entry!=null){ + if(entry.getLocation()==TableTransactional.FILEA){ + fileaentries.add(entry); + }else if(entry.getLocation()==TableTransactional.FILEB){ + filebentries.add(entry); + } + } + } + + Collections.sort(fileaentries); + Collections.sort(filebentries); + + fileabuffer=new Hashtable(); + filebbuffer=new Hashtable(); + + readNext(); + } + + private void readNextFromFileA(TableIndexEntryTransactional entry) throws IOException{ + if(fileabuffer.containsKey(entry.getId())){ + next=fileabuffer.remove(entry.getId()); + return; + } + while(true){ + if(fileaentries.size()>0){ + TableIndexEntryTransactional nextfilea=fileaentries.remove(0); + if(fileastream==null){ + // fileastream=new TransactionalFile(table.getFileName(TableTransactional.FILEA), "rw"); + fileastream=new DataInputStream(new BufferedInputStream(new FileInputStream(table.getFileName(TableTransactional.FILEA)))); + fileaposition=0; + } + if(fileaposition>nextfilea.getPosition()){ + // We have already read this entry... skip it + // readNextFromFileA(entry); + // return; + }else{ + while(fileaposition!=nextfilea.getPosition()){ + fileaposition+=fileastream.skipBytes((int)(nextfilea.getPosition()-fileaposition)); + } + + RowTransactional row=RowTransactional.readFromStream(fileastream); + final Vector args = new Vector(); + args.add(row); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + //synchronized(table.statlock){ + table.atomicfields.setstat_read_size(table.atomicfields.getstat_read_size()+((RowTransactional)(args.get(0))).getSize()); + table.atomicfields.setstat_read(table.atomicfields.getstat_read()+1); + return true; + } + //} + }); + + fileaposition+=row.getSize(); + if(row.getId().equals(entry.getId())){ + next=row; + return; + }else{ + fileabuffer.put(row.getId(),row); + // readNextFromFileA(entry); + } + } + }else{ + next=null; + return; + } + } + } + + private void readNextFromFileB(TableIndexEntryTransactional entry) throws IOException{ + if(filebbuffer.containsKey(entry.getId())){ + next=filebbuffer.remove(entry.getId()); + return; + } + while(true){ + if(filebentries.size()>0){ + TableIndexEntryTransactional nextfileb=filebentries.remove(0); + if(filebstream==null){ + filebstream=new DataInputStream(new BufferedInputStream(new FileInputStream(table.getFileName(TableTransactional.FILEB)))); + filebposition=0; + } + if(filebposition>nextfileb.getPosition()){ + // We have already read this entry... skip it + // readNextFromFileB(entry); + // return; + }else{ + while(filebposition!=nextfileb.getPosition()){ + filebposition+=filebstream.skipBytes((int)(nextfileb.getPosition()-filebposition)); + } + RowTransactional row=RowTransactional.readFromStream(filebstream); + + final Vector args = new Vector(); + args.add(row); + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + //synchronized(table.statlock){ + table.atomicfields.setstat_read_size(table.atomicfields.getstat_read_size()+((RowTransactional)(args.get(0))).getSize()); + table.atomicfields.setstat_read(table.atomicfields.getstat_read()+1); + return true; + } + }); + + filebposition+=row.getSize(); + if(row.getId().equals(entry.getId())){ + next=row; + return; + }else{ + filebbuffer.put(row.getId(),row); + // readNextFromFileB(entry); + } + } + }else{ + next=null; + return; + } + } + } + + private void readNext() throws IOException{ + if(entries.size()>rowpointer){ + TableIndexEntryTransactional entry=entries.get(rowpointer++); + if(entry!=null){ + switch(entry.getLocation()){ + case TableTransactional.FILEA : readNextFromFileA(entry); + // return; + break; + case TableTransactional.FILEB : readNextFromFileB(entry); + // return; + break; + } + if(next!=null){ + if(matcher!=null){ + if(!matcher.matches(next)){ + readNext(); + } + } + } + return; + }else{ + readNext(); + return; + } + } + try{ + if(fileastream!=null)fileastream.close(); + }catch(Exception e){} + try{ + if(filebstream!=null)filebstream.close(); + }catch(Exception e){} + next=null; + } + + public boolean hasNext(){ + if(next!=null)return true; + return false; + } + + public RowTransactional next(){ + try{ + if(next!=null){ + RowTransactional tmp=next; + readNext(); + return tmp; + } + }catch(Exception e){ + e.printStackTrace(); + } + return null; + } + + public void remove(){ + + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/PagedIndex.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/PagedIndex.java new file mode 100644 index 00000000..66144350 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/PagedIndex.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +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{ + +//protected static final int INITIALPAGEHASH=1024; + // protected static final int PAGESIZE=2048; + + protected static final int INITIALPAGEHASH=32; + protected static final int PAGESIZE=64; + + 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; + protected long stat_create_page=0; + protected long stat_page_next=0; + protected long stat_page_branch=0; + + public PagedIndex(String filename) throws IOException{ + this.filename=filename; + File ftest=new File(filename); + if(!ftest.exists())ftest.createNewFile(); + out=new RandomAccessFile(filename,"rw"); + root=new TableIndexPage[INITIALPAGEHASH]; + System.out.println(filename); + System.out.println(out.length()); + if(out.length()>0){ + for(int i=0;i readStatistics(){ + Hashtable hash=new Hashtable(); + hash.put("stat_index_read",stat_read); + hash.put("stat_index_write",stat_write); + hash.put("stat_index_create_page",stat_create_page); + hash.put("stat_index_page_next",stat_page_next); + hash.put("stat_index_page_branch",stat_page_branch); + stat_read=0; + stat_write=0; + stat_create_page=0; + stat_page_next=0; + stat_page_branch=0; + return hash; + } + + private int rootHash(String id){ + return id.hashCode() & (INITIALPAGEHASH-1); + } + + private synchronized TableIndexPage getFirstFreePage(String id) throws IOException{ + return root[rootHash(id)].getFirstFreePage(id,id.hashCode()); + } + + private synchronized long getOffset(String id) throws IOException{ + if(root==null)return -1; + return root[rootHash(id)].getOffset(id,id.hashCode()); + } + + public synchronized void updateEntry(String id,int rowsize,int location,long position) throws IOException{ + long offset=getOffset(id); + out.seek(offset); + TableIndexEntry entry=new TableIndexEntry(id,rowsize,location,position); + entry.updateData(out); + stat_write++; + } + public synchronized void addEntry(String id,int rowsize,int location,long position) throws IOException{ + TableIndexPage page=getFirstFreePage(id); + page.addEntry(id,rowsize,location,position); + stat_write++; + } + public synchronized TableIndexEntry scanIndex(String id) throws IOException{ + if(root==null)return null; + return root[rootHash(id)].scanIndex(id,id.hashCode()); + } + public synchronized List scanIndex(List rows) throws IOException{ + List lst=new ArrayList(); + for(int i=0;i scanIndex() throws IOException{ + ArrayList lst=new ArrayList(); + for(int i=0;i factory = Thread.makeFactory(PageIndexTSInf.class); + + PageIndexTSInf atomicfields; + + + + public @atomic interface PageIndexTSInf{ + String getFilename(); + Long getStat_read(); + Long getStat_write(); + Long getStat_create_page(); + Long getStat_page_next(); + Long getStat_page_branch(); + AtomicArray getRoots(); + + void setFilename(String val); + 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); + } + + + private RandomAccessFile out=null; + + //protected static final int INITIALPAGEHASH=1024; + //protected static final int PAGESIZE=2048; + + protected static final int INITIALPAGEHASH=32; + protected static final int PAGESIZE=64; + + public PagedIndexTransactional(String filename) throws IOException{ + atomicfields = factory.create(); + + atomicfields.setStat_create_page(Long.valueOf(0)); + atomicfields.setStat_page_branch(Long.valueOf(0)); + atomicfields.setStat_page_next(Long.valueOf(0)); + atomicfields.setStat_read(Long.valueOf(0)); + atomicfields.setStat_write(Long.valueOf(0)); + + this.atomicfields.setFilename(filename); + File ftest=new File(filename); + if(!ftest.exists())ftest.createNewFile(); + out=new RandomAccessFile(filename,"rw"); + atomicfields.setRoots(new AtomicArray(TableIndexPageTransactional.class, INITIALPAGEHASH)); + // System.out.println(filename); + // System.out.println(out.length()); + if(out.length()>0){ + for(int i=0;i readStatistics(){ + Hashtable hash=new Hashtable(); + hash.put("stat_index_read",atomicfields.getStat_read()); + hash.put("stat_index_write",atomicfields.getStat_write()); + hash.put("stat_index_create_page",atomicfields.getStat_create_page()); + hash.put("stat_index_page_next",atomicfields.getStat_page_next()); + hash.put("stat_index_page_branch",atomicfields.getStat_page_branch()); + atomicfields.setStat_read((long)0); + atomicfields.setStat_write((long)0); + atomicfields.setStat_create_page((long)0); + atomicfields.setStat_page_next((long)0); + atomicfields.setStat_page_branch((long)0); + return hash; + } + + private int rootHash(String id){ + return id.hashCode() & (INITIALPAGEHASH-1); + } + + private /*synchronized*/ TableIndexPageTransactional getFirstFreePage(String id) throws IOException{ + return atomicfields.getRoots().get(rootHash(id)).getFirstFreePage(id, id.hashCode()); + } + + private /*synchronized*/ long getOffset(String id) throws IOException{ + if(atomicfields.getRoots()==null)return -1; + return atomicfields.getRoots().get(rootHash(id)).getOffset(id,id.hashCode()); + } + + public /*synchronized*/ void updateEntry(String id,int rowsize,int location,long position) throws IOException{ + long offset=getOffset(id); + out.seek(offset); + TableIndexEntryTransactional entry=new TableIndexEntryTransactional(id,rowsize,location,position); + entry.updateData(out); + atomicfields.setStat_write(atomicfields.getStat_write()+1); + } + + public synchronized void updateEntryTransactional(String id,int rowsize,int location,long position) throws IOException{ + final String id2 = id; + final int rowsize2 = rowsize; + final int location2 = location; + final long position2 = position; + + Thread.doIt(new Callable() { + public Boolean call() throws Exception{ + long offset=getOffset(id2); + out.seek(offset); + TableIndexEntryTransactional entry=new TableIndexEntryTransactional(id2,rowsize2,location2,position2); + entry.updateData(out); + atomicfields.setStat_write(atomicfields.getStat_write()+1); + return true; + } + }); + } + + public /*synchronized*/ void addEntry(String id,int rowsize,int location,long position) throws IOException{ + TableIndexPageTransactional page=getFirstFreePage(id); + page.addEntry(id,rowsize,location,position); + atomicfields.setStat_write(atomicfields.getStat_write()+1); + } + public /*synchronized*/ TableIndexEntryTransactional scanIndex(String id) throws IOException{ + if(atomicfields.getRoots()==null)return null; + return atomicfields.getRoots().get(rootHash(id)).scanIndex(id,id.hashCode()); + } + + public synchronized TableIndexEntryTransactional scanIndexTransactional(String id) throws IOException{ + final String id2 = id; + return Thread.doIt(new Callable() { + public TableIndexEntryTransactional call() throws Exception{ + if(atomicfields.getRoots()==null)return null; + return atomicfields.getRoots().get(rootHash(id2)).scanIndex(id2,id2.hashCode()); + } + }); + } + + public synchronized List scanIndex(List rows) throws IOException{ + final List rows2 = rows; + return Thread.doIt(new Callable>() { + public List call() throws Exception{ + List lst=new ArrayList(); + for(int i=0;i scanIndex() throws IOException{ + return Thread.doIt(new Callable>() { + public List call() throws Exception{ + ArrayList lst=new ArrayList(); + System.out.println(Thread.currentThread() + " start"); + for(int i=0;i values; + + /** + * Creates a new empty row with the given row id. + */ + public Row(String id){ + this.id=id; + size=-1; + values=new Hashtable(); + } + + /** + * Returns the number of keys in this row. + */ + public int getKeyCount(){ + return values.size(); + } + + public Set keySet(){ + return values.keySet(); + } + + /** + * 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{ + Row r=(Row)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,Value value){ + size=-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,new Value(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,new Value(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,new Value(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,new Value(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,new Value(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,new Value(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,new Value(value)); + } + + /** + * Returns the value stored for the current key, or a null value (not null) if the key does not exist. + */ + public Value get(String key){ + if(!values.containsKey(key))return new Value(); + return values.get(key); + } + + /** + * 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))return ""; + return values.get(key).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))return 0; + return values.get(key).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))return 0; + return values.get(key).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))return 0f; + return values.get(key).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))return 0d; + return values.get(key).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))return false; + return values.get(key).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))return new Date(0); + return values.get(key).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()){ + String key=it.next(); + Value 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); + } + + /** + * 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(); + Value 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); + } + + /** + * 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; + } + String 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.keySet().iterator(); + while(it.hasNext()){ + String key=it.next(); + Value value=values.get(key); + buf.append(indentation); + buf.append(" "); + buf.append(value.toBasicXMLString(key)); + buf.append("\n"); + } + buf.append(indentation); + buf.append("\n"); + return buf.toString(); + } + } \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcher.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcher.java new file mode 100644 index 00000000..1debd7ba --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcher.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.core; + + import java.io.*; + import java.util.*; + +public class RowMatcher{ + public final static int LESSTHAN=0; + public final static int EQUALS=1; + public final static int GREATERTHAN=2; + public final static int STARTSWITH=3; + public final static int ENDSWITH=4; + public final static int CONTAINS=5; + public final static int ISNULL=6; + + public final static int NOT=7; + public final static int OR=8; + public final static int AND=9; + public final static int XOR=10; + + private String key=null; + private Value value=null; + private int type=-1; + + private RowMatcher match1=null; + private RowMatcher match2=null; + + public RowMatcher(String key,int type,Value value){ + this.key=key; + this.type=type; + this.value=value; + } + + public RowMatcher(String key,int type){ + this.key=key; + this.type=type; + } + + public RowMatcher(RowMatcher match1,int type,RowMatcher match2){ + this.match1=match1; + this.type=type; + this.match2=match2; + } + + public RowMatcher(int type,RowMatcher match1){ + this.match1=match1; + this.type=type; + } + + /** + * This method needs to be seriously optimized... especially the XOR method + */ + public boolean matches(Row row){ + if(value!=null){ + Value compare=row.get(key); + switch(type){ + case LESSTHAN : return compare.lessThan(value); + case EQUALS : return compare.equals(value); + case GREATERTHAN: return compare.greaterThan(value); + case STARTSWITH : return compare.startsWith(value); + case ENDSWITH : return compare.endsWith(value); + case CONTAINS : return compare.contains(value); + } + }else if(type==ISNULL){ + Value compare=row.get(key); + return compare.isNull(); + }else if((type==AND)||(type==OR)||(type==XOR)){ + switch(type){ + case AND : return match1.matches(row)&&match2.matches(row); + case OR : return match1.matches(row)||match2.matches(row); + case XOR : return (match1.matches(row)||match2.matches(row))&&(!(match1.matches(row)&&match2.matches(row))); + } + }else if(type==NOT){ + return !match1.matches(row); + } + return false; + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcherTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcherTransactional.java new file mode 100644 index 00000000..5cd94a53 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowMatcherTransactional.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.core; + + import java.io.*; + import java.util.*; + +public class RowMatcherTransactional{ + public final static int LESSTHAN=0; + public final static int EQUALS=1; + public final static int GREATERTHAN=2; + public final static int STARTSWITH=3; + public final static int ENDSWITH=4; + public final static int CONTAINS=5; + public final static int ISNULL=6; + + public final static int NOT=7; + public final static int OR=8; + public final static int AND=9; + public final static int XOR=10; + + private String key=null; + private ValueTransactional value=null; + private int type=-1; + + private RowMatcherTransactional match1=null; + private RowMatcherTransactional match2=null; + + public RowMatcherTransactional(String key,int type,ValueTransactional value){ + this.key=key; + this.type=type; + this.value=value; + } + + public RowMatcherTransactional(String key,int type){ + this.key=key; + this.type=type; + } + + public RowMatcherTransactional(RowMatcherTransactional match1,int type,RowMatcherTransactional match2){ + this.match1=match1; + this.type=type; + this.match2=match2; + } + + public RowMatcherTransactional(int type,RowMatcherTransactional match1){ + this.match1=match1; + this.type=type; + } + + /** + * This method needs to be seriously optimized... especially the XOR method + */ + public boolean matches(RowTransactional row){ + if(value!=null){ + ValueTransactional compare=row.get(key); + switch(type){ + case LESSTHAN : return compare.lessThan(value); + case EQUALS : return compare.equals(value); + case GREATERTHAN: return compare.greaterThan(value); + case STARTSWITH : return compare.startsWith(value); + case ENDSWITH : return compare.endsWith(value); + case CONTAINS : return compare.contains(value); + } + }else if(type==ISNULL){ + ValueTransactional compare=row.get(key); + return compare.isNull(); + }else if((type==AND)||(type==OR)||(type==XOR)){ + switch(type){ + case AND : return match1.matches(row)&&match2.matches(row); + case OR : return match1.matches(row)||match2.matches(row); + case XOR : return (match1.matches(row)||match2.matches(row))&&(!(match1.matches(row)&&match2.matches(row))); + } + }else if(type==NOT){ + return !match1.matches(row); + } + return false; + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowTransactional.java new file mode 100644 index 00000000..1fc84a0e --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/RowTransactional.java @@ -0,0 +1,398 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.solidosystems.tuplesoup.core; + +import dstm2.atomic; +import dstm2.Thread; +import dstm2.factory.Factory; +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; +/** + * + * @author navid + */ +public class RowTransactional { + Factory factory = Thread.makeFactory(RowTSInf.class); + + private String id; + // private int size; + RowTSInf atomicfields; + private StringKeyHashMap values; + + public @atomic interface RowTSInf{ + int getSize(); + void setSize(int val); + } + + public RowTransactional(String id){ + atomicfields = factory.create(); + + this.id=id; + atomicfields.setSize(-1); + values=new StringKeyHashMap(); + } + + /** + * 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(atomicfields.getSize()==-1)recalcSize(); + return atomicfields.getSize(); + } + + /** + * 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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))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))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))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))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))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))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))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))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); + this.atomicfields.setSize(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> pairs=values.entrySet(); + out.writeInt(pairs.size()); + Iterator> it= pairs.iterator(); + while(it.hasNext()){ + 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.atomicfields.setSize(size+4); + out.writeInt(this.atomicfields.getSize()); + } + + /** + * 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> pairs=values.entrySet(); + out.writeInt(pairs.size()); + + Iterator> it=pairs.iterator(); + while(it.hasNext()){ + 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.atomicfields.setSize(size+4); + out.writeInt(this.atomicfields.getSize()); + } + + /** + * Reads a full row from the given DataInputStream and returns it. + */ + public static RowTransactional readFromStream(DataInputStream in) throws IOException{ + String id=in.readUTF(); + //System.out.println("id " + id); + RowTransactional row=new RowTransactional(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.entrySet().iterator(); + boolean first=true; + while(it.hasNext()){ + if(!first){ + buf.append(","); + }else{ + first=false; + } + String key=it.next().getKey(); + buf.append("\""); + buf.append(key); + buf.append("\":"); + ValueTransactional 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=it.next().getKey(); + ValueTransactional value=values.get(key); + 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/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Table.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Table.java new file mode 100644 index 00000000..5ff49fae --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Table.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; +import java.nio.channels.*; +import com.solidosystems.tuplesoup.filter.*; + +/** + * The table stores a group of rows. + * Every row must have a unique id within a table. + */ +public interface Table{ + // Index type constants + public static final int MEMORY=0; + public static final int FLAT=1; + public static final int PAGED=2; + + // Row location constants + public static final int FILEA=0; + public static final int FILEB=1; + public static final int DELETE=2; + public static final int INDEX=3; + + /** + * Return the current values of the statistic counters and reset them. + * The current counters are: + *
    + *
  • stat_table_add + *
  • stat_table_update + *
  • stat_table_delete + *
  • stat_table_add_size + *
  • stat_table_update_size + *
  • stat_table_read_size + *
  • stat_table_read + *
  • stat_table_cache_hit + *
  • stat_table_cache_miss + *
  • stat_table_cache_drop + *
+ * Furthermore, the index will be asked to deliver separate index specific counters + */ + public Hashtable readStatistics(); + + /** + * Set the maximal allowable size of the index cache. + */ + public void setIndexCacheSize(int newsize); + + /** + * Close all open file streams + */ + public void close(); + + /** + * Returns the name of this table + */ + public String getTitle(); + + /** + * Returns the location of this tables datafiles + */ + public String getLocation(); + + /** + * Delete the files created by this table object. + * Be aware that this will delete any data stored in this table! + */ + public void deleteFiles(); + + /** + * Adds a row of data to this table. + */ + public void addRow(Row row) throws IOException; + + /** + * Adds a row to this table if it doesn't already exist, if it does it updates the row instead. + * This method is much slower than directly using add or update, so only use it if you don't know wether or not the row already exists. + */ + public void addOrUpdateRow(Row row) throws IOException; + + /** + * Updates a row stored in this table. + */ + public void updateRow(Row row) throws IOException; + + /** + * Marks a row as deleted in the index. + * Be aware that the space consumed by the row is not actually reclaimed. + */ + public void deleteRow(Row row) throws IOException; + + /** + * Returns a tuplestream containing the given list of rows + */ + public TupleStream getRows(List rows) throws IOException; + + /** + * Returns a tuplestream containing the rows matching the given rowmatcher + */ + public TupleStream getRows(RowMatcher matcher) throws IOException; + + /** + * Returns a tuplestream containing those rows in the given list that matches the given RowMatcher + */ + public TupleStream getRows(List rows,RowMatcher matcher) throws IOException; + + /** + * Returns a tuplestream of all rows in this table. + */ + public TupleStream getRows() throws IOException; + + /** + * Returns a single row stored in this table. + * If the row does not exist in the table, null will be returned. + */ + public Row getRow(String id) throws IOException; + } \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndex.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndex.java new file mode 100644 index 00000000..242f20a2 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndex.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import dstm2.AtomicSuperClass; +import java.util.*; +import java.io.*; + +public interface TableIndex{ + public Hashtable readStatistics(); + public void updateEntry(String id,int rowsize,int location,long position) throws IOException; + public void addEntry(String id,int rowsize,int location,long position) throws IOException; + public TableIndexEntry scanIndex(String id) throws IOException; + public List scanIndex(List rows) throws IOException; + public List scanIndex() throws IOException; + public void close(); +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexEntry.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexEntry.java new file mode 100644 index 00000000..a944a6c9 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexEntry.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import dstm2.atomic; +import java.io.*; + +public class TableIndexEntry implements Comparable{ + public String id; + public int location; + public long position; + private int size; + private int rowsize; + + + + public TableIndexEntry(String id,int rowsize,int location,long position){ + this.id=id; + this.location=location; + this.position=position; + this.rowsize=rowsize; + size=-1; + } + public String getId(){ + return id; + } + public void setPosition(long position){ + this.position=position; + } + public long getPosition(){ + return position; + } + public void setLocation(int location){ + this.location=location; + } + public int getLocation(){ + return location; + } + + public int getRowSize(){ + return rowsize; + } + + public int compareTo(TableIndexEntry obj) throws ClassCastException{ + TableIndexEntry ent=(TableIndexEntry)obj; + if(position{ + + static Factory factory = Thread.makeFactory(TableIndexEntryTSInf.class); + + TableIndexEntryTSInf atomicfields; + public @atomic interface TableIndexEntryTSInf{ + String getId(); + Integer getLocation(); + Long getPosition(); + Integer getSize(); + Integer getRowsize(); + + void setId(String val); + void setLocation(Integer val); + void setPosition(Long val); + void setSize(Integer val); + void setRowsize(Integer val); + } + + + public TableIndexEntryTransactional(String id,int rowsize,int location,long position){ + atomicfields = factory.create(); + + this.atomicfields.setId(id); + this.atomicfields.setLocation(location); + this.atomicfields.setPosition(position); + this.atomicfields.setRowsize(rowsize); + this.atomicfields.setSize(-1); + } + public String getId(){ + return atomicfields.getId(); + } + public void setPosition(long position){ + this.atomicfields.setPosition(position); + } + public long getPosition(){ + return atomicfields.getPosition(); + } + public void setLocation(int location){ + this.atomicfields.setLocation(location); + } + public int getLocation(){ + return atomicfields.getLocation(); + } + + public int getRowSize(){ + return atomicfields.getRowsize().intValue(); + } + + public int compareTo(TableIndexEntryTransactional obj) throws ClassCastException{ + TableIndexEntryTransactional ent=(TableIndexEntryTransactional)obj; + if(atomicfields.getPosition() factory = Thread.makeFactory(TableIndexInodeTSInf.class); + TableIndexInodeTSInf atomicfields; + + public @atomic interface TableIndexInodeTSInf{ + TableIndexNodeTransactional getPrevious(); + TableIndexEntryTransactional getData(); + TableIndexNodeTransactional getNext(); + + void setPrevious(TableIndexNodeTransactional val); + void setData(TableIndexEntryTransactional val); + void setNext(TableIndexNodeTransactional val); + } + + public TableIndexNodeTransactional(){ + atomicfields = factory.create(); + + atomicfields.setPrevious(null); + atomicfields.setData(null); + atomicfields.setNext(null); + } + + public TableIndexNodeTransactional(TableIndexEntryTransactional entry){ + atomicfields = factory.create(); + + atomicfields.setPrevious(null); + atomicfields.setData(entry); + atomicfields.setNext(null); + + } + + public TableIndexNodeTransactional(TableIndexNodeTransactional prev,TableIndexEntryTransactional entry){ + atomicfields = factory.create(); + + atomicfields.setPrevious(prev); + atomicfields.setData(entry); + atomicfields.setNext(null); + } + + public TableIndexNodeTransactional(TableIndexNodeTransactional prev,TableIndexEntryTransactional entry,TableIndexNodeTransactional nex){ + atomicfields = factory.create(); + + atomicfields.setPrevious(prev); + atomicfields.setData(entry); + atomicfields.setNext(nex); + } + + public TableIndexEntryTransactional getData(){ + return atomicfields.getData(); + } + public TableIndexNodeTransactional getPrevious(){ + return atomicfields.getPrevious(); + } + public TableIndexNodeTransactional getNext(){ + return atomicfields.getNext(); + } + public void setNext(TableIndexNodeTransactional node){ + atomicfields.setNext(node); + } + public void setPrevious(TableIndexNodeTransactional node){ + atomicfields.setPrevious(node); + } + public void setData(TableIndexEntryTransactional entry){ + atomicfields.setData(entry); + } + public void remove(){ + if(atomicfields.getPrevious()!=null){ + atomicfields.getPrevious().setNext(atomicfields.getNext()); + } + if(atomicfields.getNext()!=null){ + atomicfields.getNext().setPrevious(atomicfields.getPrevious()); + } + } +} diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPage.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPage.java new file mode 100644 index 00000000..f260cf2f --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPage.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; + +public class TableIndexPage{ + private final static int BASEOFFSET=4+8+8+4+4; + private RandomAccessFile file=null; + + private long location=-1; + private int size=-1; + private long next=-1; + private long lower=-1; + private int offset=0; + + private int starthash=-1; + private int endhash=-1; + private boolean first=false; + + private TableIndexPage nextpage=null; + private TableIndexPage lowerpage=null; + + private PagedIndex index=null; + + public TableIndexPage(PagedIndex index,RandomAccessFile file) throws IOException{ + this.file=file; + this.index=index; + first=false; + location=file.getFilePointer(); + size=file.readInt(); + next=file.readLong(); + lower=file.readLong(); + offset=file.readInt(); + endhash=file.readInt(); + // System.out.println("si " + size); + // System.out.println("next " + next); + // System.out.println("lower " + lower); + // System.out.println("offset " + offset); + // System.out.println("endhash " + endhash); + if(offset>0)starthash=file.readInt(); + // System.out.println("here tav;eindepage"); + + + } + + public static TableIndexPage createNewPage(PagedIndex index,RandomAccessFile file,int size) throws IOException{ + long pre=file.length(); + + file.setLength(file.length()+size+BASEOFFSET); + file.seek(pre); + + + file.writeInt(size); + file.writeLong(-1l); + file.writeLong(-1l); + file.writeInt(0); + file.writeInt(-1); + file.seek(pre); + index.stat_create_page++; + return new TableIndexPage(index,file); + } + + public void setFirst(){ + first=true; + } + + public long getLocation(){ + return location; + } + public long getEndLocation(){ + return location+size+BASEOFFSET; + } + + public String toString(){ + StringBuffer buf=new StringBuffer(); + buf.append("{\n"); + buf.append(" location "+location+"\n"); + buf.append(" size "+size+"\n"); + buf.append(" next "+next+"\n"); + buf.append(" lower "+lower+"\n"); + buf.append(" offset "+offset+"\n"); + buf.append(" starthash "+starthash+"\n"); + buf.append(" endhash "+endhash+"\n"); + buf.append("}\n"); + return buf.toString(); + } + + private void updateMeta() throws IOException{ + file.seek(location); + file.writeInt(size); + file.writeLong(next); + file.writeLong(lower); + file.writeInt(offset); + file.writeInt(endhash); + } + + public void addEntriesToList(List lst) throws IOException{ + if(lower>-1){ + if(lowerpage==null){ + file.seek(lower); + lowerpage=new TableIndexPage(index,file); + } + lowerpage.addEntriesToList(lst); + } + if(next>-1){ + if(nextpage==null){ + file.seek(next); + nextpage=new TableIndexPage(index,file); + } + nextpage.addEntriesToList(lst); + } + file.seek(location+BASEOFFSET); + long pre=file.getFilePointer(); + System.out.println(Thread.currentThread() + " " +offset + " " + pre); + while(file.getFilePointer()endhash){ + + if(next==-1)return null; + if(nextpage==null){ + file.seek(next); + nextpage=new TableIndexPage(index,file); + } + index.stat_page_next++; + return nextpage.scanIndex(id,hashcode); + } + file.seek(location+BASEOFFSET); + long pre=file.getFilePointer(); + while(file.getFilePointer()endhash){ + if(next==-1)return -1; + if(nextpage==null){ + file.seek(next); + nextpage=new TableIndexPage(index,file); + } + index.stat_page_next++; + return nextpage.getOffset(id,hashcode); + } + file.seek(location+BASEOFFSET); + long pre=file.getFilePointer(); + while(file.getFilePointer()id.length()*2+4+4+8+1+2)return this; + // Check next + if(next==-1){ + next=file.length(); + updateMeta(); + return createNewPage(index,file,PagedIndex.PAGESIZE); + } + if(nextpage==null){ + file.seek(next); + nextpage=new TableIndexPage(index,file); + } + index.stat_page_next++; + return nextpage.getFirstFreePage(id,hashcode); + } + + public void addEntry(String id,int rowsize,int location,long position) throws IOException{ + if(offset==0)starthash=id.hashCode(); + file.seek(this.location+BASEOFFSET+offset); + TableIndexEntry entry=new TableIndexEntry(id,rowsize,location,position); + entry.writeData(file); + offset+=entry.getSize(); + if(id.hashCode()>endhash)endhash=id.hashCode(); + updateMeta(); + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java new file mode 100644 index 00000000..9e57fb68 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexPageTransactional.java @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import dstm2.AtomicSuperClass; +import dstm2.atomic; +import dstm2.Thread; +import dstm2.factory.Factory; +import java.io.*; +import java.util.*; + +public class TableIndexPageTransactional implements AtomicSuperClass{ + static Factory factory = Thread.makeFactory(TableIndexPageTSInf.class); + + /*static*/ TableIndexPageTSInf atomicfields = null; + private final static int BASEOFFSET=4+8+8+4+4; + private RandomAccessFile file=null; + + + + public @atomic interface TableIndexPageTSInf{ + Long getLocation(); + Integer getSize(); + Long getNext(); + Long getLower(); + Integer getOffset(); + Integer getStarthash(); + Integer getEndhash(); + Boolean getFirst(); + TableIndexPageTransactional getNextpage(); + TableIndexPageTransactional getLowerpage(); + PagedIndexTransactional getIndex(); + + + void setLowerpage(TableIndexPageTransactional lowerpage); + void setNextpage(TableIndexPageTransactional nextpage); + void setFirst(Boolean val); + void setEndhash(Integer val); + void setStarthash(Integer val); + void setOffset(Integer offset); + void setNext(Long next); + void setSize(Integer size); + void setLocation(Long location); + void setLower(Long val); + void setIndex(PagedIndexTransactional val); + } + + + + public TableIndexPageTransactional(PagedIndexTransactional index,RandomAccessFile file) throws IOException{ + this.file=file; + atomicfields = factory.create(); + this.atomicfields.setIndex(index); + this.atomicfields.setFirst(false); + this.atomicfields.setLocation(file.getFilePointer()); + // System.out.println(file.getFilePointer()); + this.atomicfields.setSize(file.readInt()); + // System.out.println(file.getFilePointer()); + this.atomicfields.setNext(file.readLong()); + // System.out.println(file.getFilePointer()); + this.atomicfields.setLower(file.readLong()); + // System.out.println(file.getFilePointer()); + // System.out.println(file.getFilePointer()); + this.atomicfields.setOffset(file.readInt()); + // System.out.println(file.getFilePointer()); + this.atomicfields.setEndhash(file.readInt()); + // System.out.println("size " + atomicfields.getSize()); + System.out.println("next " + atomicfields.getNext()); + System.out.println("lower " + atomicfields.getLower()); + System.out.println("offset " + atomicfields.getOffset()); + System.out.println("endhash " + atomicfields.getEndhash()); + if(this.atomicfields.getOffset()>0) + this.atomicfields.setStarthash(file.readInt()); + else + this.atomicfields.setStarthash(-1); + } + + public static TableIndexPageTransactional createNewPage(PagedIndexTransactional index,RandomAccessFile file,int size) throws IOException{ + + long pre=file.length(); + + file.setLength(file.length()+size+BASEOFFSET); + file.seek(pre); + + // System.out.println("pointer2 " + file.getFilePointer()); + file.writeInt(size); + + // System.out.println("pointer2 " + file.getFilePointer()); + file.writeLong(-1l); + // System.out.println("pointer2 " + file.getFilePointer()); + file.writeLong(-1l); + // System.out.println("pointer2 " + file.getFilePointer()); + file.writeInt(0); + // System.out.println("pointer2 " + file.getFilePointer()); + file.writeInt(-1); + file.seek(pre); + // file.readInt(); + // file.readLong(); + // file.readLong(); + // file.readInt(); + // file.readInt(); + // file.seek(pre); + + //index.atomicfields.setStat_create_page((long)2); + index.atomicfields.setStat_create_page(index.atomicfields.getStat_create_page()+1); + return new TableIndexPageTransactional(index,file); + } + + public void setFirst(){ + this.atomicfields.setFirst(true); + } + + public long getLocation(){ + return atomicfields.getLocation(); + } + public long getEndLocation(){ + return this.atomicfields.getLocation()+atomicfields.getSize()+BASEOFFSET; + } + + public String toString(){ + StringBuffer buf=new StringBuffer(); + buf.append("{\n"); + buf.append(" location "+this.atomicfields.getLocation()+"\n"); + buf.append(" size "+this.atomicfields.getSize()+"\n"); + buf.append(" next "+this.atomicfields.getNext()+"\n"); + buf.append(" lower "+this.atomicfields.getLower()+"\n"); + buf.append(" offset "+this.atomicfields.getOffset()+"\n"); + buf.append(" starthash "+this.atomicfields.getStarthash()+"\n"); + buf.append(" endhash "+this.atomicfields.getEndhash()+"\n"); + buf.append("}\n"); + return buf.toString(); + } + + private void updateMeta() throws IOException{ + file.seek(this.atomicfields.getLocation()); + file.writeInt(this.atomicfields.getSize()); + file.writeLong(this.atomicfields.getNext()); + file.writeLong(this.atomicfields.getLower()); + file.writeInt(this.atomicfields.getOffset()); + file.writeInt(this.atomicfields.getEndhash()); + } + + public void addEntriesToList(List lst) throws IOException{ + if(this.atomicfields.getLower()>-1){ + if(this.atomicfields.getLowerpage()==null){ + file.seek(this.atomicfields.getLower()); + this.atomicfields.setLowerpage(new TableIndexPageTransactional(this.atomicfields.getIndex(),file)); + } + this.atomicfields.getLowerpage().addEntriesToList(lst); + } + if(this.atomicfields.getNext()>-1){ + if(this.atomicfields.getNextpage()==null){ + file.seek(this.atomicfields.getNext()); + this.atomicfields.setNextpage(new TableIndexPageTransactional(this.atomicfields.getIndex(),file)); + } + this.atomicfields.getNextpage().addEntriesToList(lst); + } + file.seek(this.atomicfields.getLocation()+BASEOFFSET); + long pre=file.getFilePointer(); + // System.out.println(Thread.currentThread() + " " +this.atomicfields.getOffset() + " " + pre); + while(file.getFilePointer()this.atomicfields.getEndhash()){ + if(this.atomicfields.getNext()==-1)return null; + if(this.atomicfields.getNextpage()==null){ + file.seek(this.atomicfields.getNext()); + this.atomicfields.setNextpage(new TableIndexPageTransactional(this.atomicfields.getIndex(),file)); + } + atomicfields.getIndex().atomicfields.setStat_page_next(atomicfields.getIndex().atomicfields.getStat_page_next()+1); + return this.atomicfields.getNextpage().scanIndex(id,hashcode); + } + file.seek(this.atomicfields.getLocation()+BASEOFFSET); + long pre=file.getFilePointer(); + while(file.getFilePointer()this.atomicfields.getEndhash()){ + if(this.atomicfields.getNext()==-1)return -1; + if(this.atomicfields.getNextpage()==null){ + file.seek(this.atomicfields.getNext()); + this.atomicfields.setNextpage(new TableIndexPageTransactional(this.atomicfields.getIndex(),file)); + } + atomicfields.getIndex().atomicfields.setStat_page_next(atomicfields.getIndex().atomicfields.getStat_page_next()+1); + return this.atomicfields.getNextpage().getOffset(id,hashcode); + } + file.seek(this.atomicfields.getLocation()+BASEOFFSET); + long pre=file.getFilePointer(); + while(file.getFilePointer()id.length()*2+4+4+8+1+2)return this; + // Check next + if(this.atomicfields.getNext()==-1){ + this.atomicfields.setNext(file.length()); + updateMeta(); + return createNewPage(this.atomicfields.getIndex(),file,PagedIndexTransactional.PAGESIZE); + } + if(this.atomicfields.getNextpage()==null){ + file.seek(this.atomicfields.getNext()); + this.atomicfields.setNextpage(new TableIndexPageTransactional(this.atomicfields.getIndex(),file)); + } + atomicfields.getIndex().atomicfields.setStat_page_next(atomicfields.getIndex().atomicfields.getStat_page_next()+1); + return this.atomicfields.getNextpage().getFirstFreePage(id,hashcode); + } + + public void addEntry(String id,int rowsize,int location,long position) throws IOException{ + if(atomicfields.getOffset()==0)this.atomicfields.setStarthash(id.hashCode()); + file.seek(this.atomicfields.getLocation()+BASEOFFSET+this.atomicfields.getOffset()); + TableIndexEntryTransactional entry=new TableIndexEntryTransactional(id,rowsize,location,position); + entry.writeData(file); + this.atomicfields.setOffset(this.atomicfields.getOffset()+entry.getSize()); + if(id.hashCode()>this.atomicfields.getEndhash()) this.atomicfields.setEndhash(id.hashCode()); + updateMeta(); + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexTransactional.java new file mode 100644 index 00000000..b859cc2c --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableIndexTransactional.java @@ -0,0 +1,22 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.solidosystems.tuplesoup.core; + +import dstm2.AtomicSuperClass; +import java.util.*; +import java.io.*; + +public interface TableIndexTransactional extends AtomicSuperClass{ + public Hashtable readStatistics(); + public void updateEntry(String id,int rowsize,int location,long position) throws IOException; + public void updateEntryTransactional(String id,int rowsize,int location,long position) throws IOException; + public void addEntry(String id,int rowsize,int location,long position) throws IOException; + public TableIndexEntryTransactional scanIndex(String id) throws IOException; + public TableIndexEntryTransactional scanIndexTransactional(String id) throws IOException; + public List scanIndex(List rows) throws IOException; + public List scanIndex() throws IOException; + public void close(); +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableTransactional.java new file mode 100644 index 00000000..7f7ba772 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TableTransactional.java @@ -0,0 +1,157 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.solidosystems.tuplesoup.core; + +/** + * + * @author navid + */ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +import java.io.*; +import java.util.*; +import java.nio.channels.*; +import com.solidosystems.tuplesoup.filter.*; + +/** + * The table stores a group of rows. + * Every row must have a unique id within a table. + */ +public interface TableTransactional{ + // Index type constants + public static final int MEMORY=0; + public static final int FLAT=1; + public static final int PAGED=2; + + // Row location constants + public static final int FILEA=0; + public static final int FILEB=1; + public static final int DELETE=2; + public static final int INDEX=3; + + /** + * Return the current values of the statistic counters and reset them. + * The current counters are: + *
    + *
  • stat_table_add + *
  • stat_table_update + *
  • stat_table_delete + *
  • stat_table_add_size + *
  • stat_table_update_size + *
  • stat_table_read_size + *
  • stat_table_read + *
  • stat_table_cache_hit + *
  • stat_table_cache_miss + *
  • stat_table_cache_drop + *
+ * Furthermore, the index will be asked to deliver separate index specific counters + */ + public Hashtable readStatistics(); + + /** + * Set the maximal allowable size of the index cache. + */ + public void setIndexCacheSize(int newsize); + + /** + * Close all open file streams + */ + public void close(); + + /** + * Returns the name of this table + */ + public String getTitle(); + + /** + * Returns the location of this tables datafiles + */ + public String getLocation(); + + /** + * Delete the files created by this table object. + * Be aware that this will delete any data stored in this table! + */ + public void deleteFiles(); + + /** + * Adds a row of data to this table. + */ + public void addRow(RowTransactional row) throws IOException; + + /** + * Adds a row to this table if it doesn't already exist, if it does it updates the row instead. + * This method is much slower than directly using add or update, so only use it if you don't know wether or not the row already exists. + */ + public void addOrUpdateRow(RowTransactional row) throws IOException; + + /** + * Updates a row stored in this table. + */ + public void updateRow(RowTransactional row) throws IOException; + + /** + * Marks a row as deleted in the index. + * Be aware that the space consumed by the row is not actually reclaimed. + */ + public void deleteRow(RowTransactional row) throws IOException; + + /** + * Returns a tuplestream containing the given list of rows + */ + public TupleStreamTransactional getRows(List rows) throws IOException; + + /** + * Returns a tuplestream containing the rows matching the given rowmatcher + */ + public TupleStreamTransactional getRows(RowMatcherTransactional matcher) throws IOException; + + /** + * Returns a tuplestream containing those rows in the given list that matches the given RowMatcher + */ + public TupleStreamTransactional getRows(List rows,RowMatcherTransactional matcher) throws IOException; + + /** + * Returns a tuplestream of all rows in this table. + */ + public TupleStreamTransactional getRows() throws IOException; + + /** + * Returns a single row stored in this table. + * If the row does not exist in the table, null will be returned. + */ + public RowTransactional getRow(String id) throws IOException; + } \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStream.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStream.java new file mode 100644 index 00000000..f6a7e81d --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStream.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; + +public abstract class TupleStream{ + public abstract boolean hasNext() throws IOException; + public abstract Row next() throws IOException; +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMerger.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMerger.java new file mode 100644 index 00000000..8d71ce4c --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMerger.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; + +public class TupleStreamMerger extends TupleStream{ + private List streams; + private TupleStream current=null; + private Row next=null; + + public TupleStreamMerger(){ + streams=new ArrayList(); + } + + public void addStream(TupleStream stream){ + streams.add(stream); + } + + public boolean hasNext() throws IOException{ + if(next!=null)return true; + if(current==null){ + if(streams.size()>0){ + current=streams.remove(0); + }else return false; + } + if(current.hasNext()){ + next=current.next(); + return true; + }else{ + current=null; + return hasNext(); + } + } + + public Row next() throws IOException{ + if(next==null)hasNext(); + Row tmp=next; + next=null; + return tmp; + } + + +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMergerTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMergerTransactional.java new file mode 100644 index 00000000..3070f9e8 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamMergerTransactional.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.*; +import java.util.*; + +public class TupleStreamMergerTransactional extends TupleStreamTransactional{ + private List streams; + private TupleStreamTransactional current=null; + private RowTransactional next=null; + + public TupleStreamMergerTransactional(){ + streams=new ArrayList(); + } + + public void addStream(TupleStreamTransactional stream){ + streams.add(stream); + } + + public boolean hasNext() throws IOException{ + if(next!=null)return true; + if(current==null){ + if(streams.size()>0){ + current=streams.remove(0); + }else return false; + } + if(current.hasNext()){ + next=current.next(); + return true; + }else{ + current=null; + return hasNext(); + } + } + + public RowTransactional next() throws IOException{ + if(next==null)hasNext(); + RowTransactional tmp=next; + next=null; + return tmp; + } + + +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamTransactional.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamTransactional.java new file mode 100644 index 00000000..d65dd22c --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/TupleStreamTransactional.java @@ -0,0 +1,17 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.solidosystems.tuplesoup.core; + +import java.io.IOException; + +/** + * + * @author navid + */ +public abstract class TupleStreamTransactional { + public abstract boolean hasNext() throws IOException; + public abstract RowTransactional next() throws IOException; +} diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Value.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Value.java new file mode 100644 index 00000000..0da44524 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/core/Value.java @@ -0,0 +1,639 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.core; + + import java.util.*; + import java.io.*; + + /** + * The Value class holds a single data value. + * Current size estimate without string data: 8+4+4+8+8 = 32 bytes pr value in mem + */ + public class Value{ + 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 type; + } + + /** + * Returns the name this value's type. + */ + public String getTypeName(){ + switch(type){ + 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(type){ + case STRING : hash+=str_value.hashCode(); + case INT : hash+=(int)int_value; + case LONG : hash+=(int)int_value; + case FLOAT : hash+=(int)float_value; + case DOUBLE : hash+=(int)float_value; + case BOOLEAN : hash+=(int)int_value; + case TIMESTAMP : hash+=(int)int_value; + case BINARY : hash+=binary.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 type==NULL; + } + + /** + * Returns -1, 0 or 1 if this value is smaller, equal or larger than the value given as a parameter. + */ + public int compareTo(Value value){ + if(type==STRING){ + return str_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(Value value){ + switch(type){ + 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(Value value){ + switch(type){ + 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(Value 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(Value 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(Value 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{ + Value val=(Value)obj; + if(val.type==type){ + switch(type){ + case NULL : return true; + case STRING : return str_value.equals(val.str_value); + case INT : return int_value==val.int_value; + case LONG : return int_value==val.int_value; + case FLOAT : return float_value==val.float_value; + case DOUBLE : return float_value==val.float_value; + case BOOLEAN : return int_value==val.int_value; + case TIMESTAMP : return int_value==val.int_value; + case BINARY : if(binary.length==val.binary.length){ + for(int i=0;i"+str_value+""; + case INT : return ""+int_value+""; + case LONG : return ""+int_value+""; + case FLOAT : return ""+float_value+""; + case DOUBLE : return ""+float_value+""; + case BOOLEAN : if(int_value==1){ + return "TRUE"; + }else{ + return "FALSE"; + } + case TIMESTAMP : return ""+new Date(int_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(type){ + case STRING : return ""+str_value+""; + case INT : return ""+int_value+""; + case LONG : return ""+int_value+""; + case FLOAT : return ""+float_value+""; + case DOUBLE : return ""+float_value+""; + case BOOLEAN : if(int_value==1){ + return "TRUE"; + }else{ + return "FALSE"; + } + case TIMESTAMP : return ""+new Date(int_value).toString()+""; + case BINARY : return ""+getString()+""; + } + return ""; + } + + /** + * Returns a string representation of this value + */ + public String getString(){ + switch(type){ + case STRING : return str_value; + case INT : return ""+int_value; + case LONG : return ""+int_value; + case FLOAT : return ""+float_value; + case DOUBLE : return ""+float_value; + case BOOLEAN : if(int_value==1){ + return "TRUE"; + }else{ + return "FALSE"; + } + case TIMESTAMP : return new Date(int_value).toString(); + case BINARY : StringBuffer buf=new StringBuffer(); + for(int i=0;i factory = Thread.makeFactory(ValueTSInf.class); + + 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+=atomicfields.getInt_value(); + case LONG : hash+=atomicfields.getInt_value(); + case FLOAT : hash+=atomicfields.getFloat_value(); + case DOUBLE : hash+=atomicfields.getFloat_value(); + case BOOLEAN : hash+=atomicfields.getInt_value(); + case TIMESTAMP : hash+=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 lst){ + + } + public abstract boolean hasNext(); + public abstract Row next(); +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/JavaSort.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/JavaSort.java new file mode 100644 index 00000000..1dfb4a1f --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/JavaSort.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.filter; + +import com.solidosystems.tuplesoup.core.*; +import java.util.*; +import java.io.*; + +public class JavaSort extends Sort{ + private List sortlst; + private int offset; + private int datasize; + + public JavaSort(){ + } + public void initialize(String filename,TupleStream source,List lst) throws IOException{ + sortlst=new ArrayList(); + offset=0; + while(source.hasNext()){ + sortlst.add(source.next()); + } + Collections.sort(sortlst,new SortComparator(lst)); + datasize=sortlst.size(); + } + public boolean hasNext(){ + if(offset buffers) throws IOException{ + while(buffers.size()>2){ + RowBuffer tmp=new RowBuffer(filename+"."+(bufnum++)); + tmp.setCacheSize(allocBuffer()); + // Grab two and sort to buf + RowBuffer a=buffers.remove(0); + RowBuffer b=buffers.remove(0); + mergeSort(tmp,a,b); + a.close(); + freeBuffer(a); + b.close(); + freeBuffer(b); + buffers.add(tmp); + } + if(buffers.size()==1){ + result.close(); + result=buffers.get(0); + result.prepare(); + return; + } + if(buffers.size()==2){ + RowBuffer a=buffers.get(0); + RowBuffer b=buffers.get(1); + mergeSort(result,a,b); + a.close(); + freeBuffer(a); + b.close(); + freeBuffer(b); + result.prepare(); + return; + } + } + + private int allocBuffer(){ + if(BUFFERCACHE>=BUFFERLIMIT){ + BUFFERCACHE-=BUFFERLIMIT; + return BUFFERLIMIT; + } + int tmp=BUFFERCACHE; + BUFFERCACHE=0; + return tmp; + } + private void freeBuffer(RowBuffer buf){ + BUFFERCACHE+=buf.getCacheSize(); + } + + public void initialize(String filename,TupleStream source,List lst) throws IOException{ + this.filename=filename; + compare=new SortComparator(lst); + bufnum=0; + result=new RowBuffer(filename+".result"); + result.setCacheSize(BUFFERLIMIT); + List buffers=new ArrayList(); + int usage=0; + List sortlst=new ArrayList(); + while(source.hasNext()){ + Row row=source.next(); + if(usage+row.getSize()>MEMLIMIT){ + RowBuffer buf=new RowBuffer(filename+"."+(bufnum++)); + buf.setCacheSize(allocBuffer()); + Collections.sort(sortlst,new SortComparator(lst)); + for(int i=0;i(); + } + sortlst.add(row); + usage+=row.getSize(); + } + RowBuffer buf=new RowBuffer(filename+"."+(bufnum++)); + buf.setCacheSize(allocBuffer()); + Collections.sort(sortlst,new SortComparator(lst)); + for(int i=0;i buffers) throws IOException{ + while(buffers.size()>2){ + RowBuffer tmp=new RowBuffer(filename+"."+(bufnum++)); + tmp.setCacheSize(allocBuffer()); + // Grab two and sort to buf + RowBuffer a=buffers.remove(0); + RowBuffer b=buffers.remove(0); + mergeSort(tmp,a,b); + a.close(); + freeBuffer(a); + b.close(); + freeBuffer(b); + buffers.add(tmp); + } + if(buffers.size()==1){ + result.close(); + result=buffers.get(0); + result.prepare(); + return; + } + if(buffers.size()==2){ + RowBuffer a=buffers.get(0); + RowBuffer b=buffers.get(1); + mergeSort(result,a,b); + a.close(); + freeBuffer(a); + b.close(); + freeBuffer(b); + result.prepare(); + return; + } + } + + private int allocBuffer(){ + if(BUFFERCACHE>=BUFFERLIMIT){ + BUFFERCACHE-=BUFFERLIMIT; + return BUFFERLIMIT; + } + int tmp=BUFFERCACHE; + BUFFERCACHE=0; + return tmp; + } + private void freeBuffer(RowBuffer buf){ + BUFFERCACHE+=buf.getCacheSize(); + } + + public void initialize(String filename,TupleStream source,List lst) throws IOException{ + long prepart=System.currentTimeMillis(); + this.filename=filename; + compare=new SortComparator(lst); + bufnum=0; + result=new RowBuffer(filename+".result"); + result.setCacheSize(BUFFERLIMIT); + List buffers=new ArrayList(); + int usage=0; + + List prebuffers=new ArrayList(); + List prebufferends=new ArrayList(); + for(int i=0;i0){ + RowBuffer tmp=prebuffers.get(i); + tmp.addRow(rowa); + prebufferends.set(i,rowa); + rowa=null; + } + }else{ + prebufferends.add(rowa); + RowBuffer tmp=prebuffers.get(i); + tmp.addRow(rowa); + rowa=null; + } + } + if(rowa!=null){ + overflow.addRow(rowa); + over++; + } + } + for(int i=0;i sortlst=new ArrayList(); + while(source.hasNext()){ + Row row=source.next(); + if(usage+row.getSize()>MEMLIMIT){ + RowBuffer buf=new RowBuffer(filename+"."+(bufnum++)); + buf.setCacheSize(allocBuffer()); + Collections.sort(sortlst,new SortComparator(lst)); + for(int i=0;i(); + } + sortlst.add(row); + usage+=row.getSize(); + } + RowBuffer buf=new RowBuffer(filename+"."+(bufnum++)); + buf.setCacheSize(allocBuffer()); + Collections.sort(sortlst,new SortComparator(lst)); + for(int i=0;i lst){ + + } + public abstract boolean hasNext(); + public abstract Row next(); +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RadixSort.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RadixSort.java new file mode 100644 index 00000000..b64f2086 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RadixSort.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.filter; + +import com.solidosystems.tuplesoup.core.*; +import java.util.*; + +public abstract class RadixSort extends TupleStream{ + public RadixSort(){ + + } + public void initialize(TupleStream source,List lst){ + + } + public abstract boolean hasNext(); + public abstract Row next(); +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RowBuffer.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RowBuffer.java new file mode 100644 index 00000000..3635c2b6 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/RowBuffer.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.filter; + +import java.util.*; +import java.io.*; +import com.solidosystems.tuplesoup.core.*; + +public class RowBuffer extends TupleStream{ + private int CACHESIZE=32768; + private int cacheusage=0; + + private int mempointer=0; + private boolean diskused=false; + + private List membuffer; + private String diskbuffer; + private DataOutputStream out; + private DataInputStream in; + + private Row next=null; + + public RowBuffer(String filename){ + membuffer=new ArrayList(); + diskbuffer=filename; + out=null; + in=null; + } + + public void setCacheSize(int size){ + CACHESIZE=size; + } + public int getCacheSize(){ + return CACHESIZE; + } + + public void addRow(Row row) throws IOException{ + if(cacheusage+row.getSize()<=CACHESIZE){ + membuffer.add(row); + cacheusage+=row.getSize(); + }else{ + cacheusage=CACHESIZE; + if(out==null)out=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(diskbuffer),2048)); + row.writeToStream(out); + diskused=true; + } + } + + public void prepare() throws IOException{ + if(out!=null){ + out.flush(); + out.close(); + } + mempointer=0; + if(diskused)in=new DataInputStream(new BufferedInputStream(new FileInputStream(diskbuffer),2048)); + readNext(); + } + + public void close(){ + try{ + File ftest=new File(diskbuffer); + if(ftest.exists()){ + if(out!=null)out.close(); + if(in!=null)in.close(); + ftest.delete(); + } + }catch(Exception e){ + + } + } + + private void readNext() throws IOException{ + if(mempointer membuffer; + private String diskbuffer; + private DataOutputStream out; + private DataInputStream in; + + private RowTransactional next=null; + + public RowBufferTransactional(String filename){ + membuffer=new ArrayList(); + diskbuffer=filename; + out=null; + in=null; + } + + public void setCacheSize(int size){ + CACHESIZE=size; + } + public int getCacheSize(){ + return CACHESIZE; + } + + public void addRow(RowTransactional row) throws IOException{ + if(cacheusage+row.getSize()<=CACHESIZE){ + membuffer.add(row); + cacheusage+=row.getSize(); + }else{ + cacheusage=CACHESIZE; + if(out==null)out=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(diskbuffer),2048)); + row.writeToStream(out); + diskused=true; + } + } + + public void prepare() throws IOException{ + if(out!=null){ + out.flush(); + out.close(); + } + mempointer=0; + if(diskused)in=new DataInputStream(new BufferedInputStream(new FileInputStream(diskbuffer),2048)); + readNext(); + } + + public void close(){ + try{ + File ftest=new File(diskbuffer); + if(ftest.exists()){ + if(out!=null)out.close(); + if(in!=null)in.close(); + ftest.delete(); + } + }catch(Exception e){ + + } + } + + private void readNext() throws IOException{ + if(mempointer lst=new ArrayList(); + lst.add(new SortRule(key,direction)); + initialize(filename,source,lst); + } + public void initialize(String filename,TupleStream source,String key,int direction,String key2,int direction2) throws IOException{ + List lst=new ArrayList(); + lst.add(new SortRule(key,direction)); + lst.add(new SortRule(key2,direction2)); + initialize(filename,source,lst); + } + public abstract void initialize(String filename,TupleStream source,List lst) throws IOException; + public abstract boolean hasNext() throws IOException; + public abstract Row next() throws IOException; +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortComparator.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortComparator.java new file mode 100644 index 00000000..33fe9093 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortComparator.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.filter; + +import com.solidosystems.tuplesoup.core.*; +import java.util.*; + +public class SortComparator implements Comparator{ + private List rules; + + public SortComparator(List rules){ + this.rules=rules; + } + + private int compare(int rulenum,Row rowa,Row rowb){ + if(rules.size()<=rulenum)return 0; + SortRule rule=rules.get(rulenum); + Value a=rowa.get(rule.getKey()); + Value b=rowb.get(rule.getKey()); + int result=a.compareTo(b); + // TODO: add direction switcher here + if(result==0){ + rulenum++; + return compare(rulenum,rowa,rowb); + }else{ + if(rule.getDirection()==SortRule.DESC){ + if(result==-1){ + result=1; + }else if(result==1)result=-1; + } + return result; + } + } + + public int compare(Row rowa,Row rowb){ + return compare(0,rowa,rowb); + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortRule.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortRule.java new file mode 100644 index 00000000..206ae8d6 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/filter/SortRule.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.filter; + +import com.solidosystems.tuplesoup.core.*; + +public class SortRule{ + public static final int ASC=0; + public static final int DESC=1; + + private String key; + private int direction; + + public SortRule(String key, int direction){ + this.key=key; + this.direction=direction; + } + + public int getDirection(){ + return direction; + } + + public String getKey(){ + return key; + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/BasicTest.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/BasicTest.java new file mode 100644 index 00000000..dabbf7b7 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/BasicTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.solidosystems.tuplesoup.test; + +import java.util.*; + +public class BasicTest{ + public Listerrors=new ArrayList(); + private int lastlength=0; + + public void err(String str){ + while(lastlength<40){ + System.out.print(" "); + lastlength++; + } + outbr(" ERR"); + outbr(" ! "+str); + errors.add(str); + } + + public void printErrorSummary(){ + outbr(""); + if(errors.size()==0){ + outbr("All tests passed!"); + }else if(errors.size()==1){ + outbr("1 test failed!"); + }else{ + outbr(errors.size()+" tests failed!"); + } + } + + public static void die(String reason){ + System.out.println("ERR"); + System.out.println(" ! "+reason); + System.exit(0); + } + + public void ok(){ + while(lastlength<40){ + System.out.print(" "); + lastlength++; + } + outbr(" OK"); + } + + public void outbr(String str){ + outbr(0,str); + } + + public void out(String str){ + out(0,str); + } + + public void outbr(int level, String str){ + switch(level){ + case 0:System.out.print(""); + break; + case 1:System.out.print(" + "); + break; + case 2:System.out.print(" * "); + break; + case 3:System.out.print(" - "); + break; + case 4:System.out.print(" + "); + break; + } + System.out.println(str); + } + + public void out(int level, String str){ + lastlength=0; + switch(level){ + case 0: System.out.print(""); + break; + case 1: System.out.print(" + "); + lastlength+=3; + break; + case 2: System.out.print(" * "); + lastlength+=5; + break; + case 3: System.out.print(" - "); + lastlength+=7; + break; + } + System.out.print(str); + lastlength+=str.length(); + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelPerformanceTest.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelPerformanceTest.java new file mode 100644 index 00000000..b2ece8fd --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelPerformanceTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.test; + + import com.solidosystems.tuplesoup.core.*; + import com.solidosystems.tuplesoup.filter.*; + +import dstm2.Init; + import java.util.*; + import java.io.*; + + +public class OrigParralelPerformanceTest extends BasicTest implements Runnable{ + + long writetime; + long readtime; + long randomtime; + + public OrigParralelPerformanceTest(){ + String path="/home/navid/Volumes/My Book/test/"; + try{ + //int records=50000; + int records=5; + for(int i=1;i<2/*11*/;i++){ + outbr("Running Parallel DualFileTable Performance test"); + outbr(1,i+" x "+(records/i)+" Large records"); + + // outbr(2,"Memory index"); + /* Table table=new DualFileTable("Performance-test",path,Table.MEMORY); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles();*/ + + /* outbr(2,"Flat index"); + table=new DualFileTable("Performance-test",path,Table.FLAT); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles();*/ + + outbr(2,"Paged index"); + Table table=new DualFileTable("Performance-test",path,Table.PAGED); + //TableTransactional table=new DualFileTableTransactional("Performance-test",path,TableTransactional.PAGED); + benchmark(table,5,(records/i)); + table.close(); + // table.deleteFiles(); + + outbr("Running Parallel HashedTable Performance test"); + outbr(1,i+" x "+(records/i)+" Large records"); + + /* outbr(2,"Memory index"); + table=new HashedTable("Performance-test",path,Table.MEMORY); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles(); + + outbr(2,"Flat index"); + table=new HashedTable("Performance-test",path,Table.FLAT); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles();*/ + + // outbr(2,"Paged index"); + //table=new HashedTableTransactional("Performance-test",path,TableTransactional.PAGED); + // table=new HashedTable("Performance-test",path,Table.PAGED); + // benchmark(table,i,(records/i)); + // table.close(); + // table.deleteFiles();*/ + } + + + }catch(Exception e){ + e.printStackTrace(); + } + } + public static void main(String[] args){ + Init.init(); + new OrigParralelPerformanceTest(); + } + + public void benchmark(Table table,int threadcount, int records) throws Exception{ + writetime=0; + readtime=0; + randomtime=0; + List lst=new ArrayList(); + for(int i=0;i hash){ + Set keys=hash.keySet(); + Iterator it=keys.iterator(); + while(it.hasNext()){ + String key=it.next(); + outbr(4,key+" "+hash.get(key)); + } + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelThread.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelThread.java new file mode 100644 index 00000000..fb1ca675 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/OrigParralelThread.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.test; + + import com.solidosystems.tuplesoup.core.*; + import com.solidosystems.tuplesoup.filter.*; + + import java.util.*; + import java.io.*; + + +public class OrigParralelThread implements Runnable{ + String id; + int records; + OrigParralelPerformanceTest app; + Table table; + //TableTransactional table; + + public OrigParralelThread(OrigParralelPerformanceTest app,Table table,String id,int records){ + this.id=id; + this.records=records; + this.app=app; + this.table=table; + } + + public void run(){ + try{ + long time; + time=app.benchmarkLargeWrite(table,records,id); + synchronized(app){ + app.writetime+=time; + } + time=app.benchmarkLargeRead(table,records,id); + synchronized(app){ + app.readtime+=time; + } + time=app.benchmarkLargeRandomRead(table,records,id); + synchronized(app){ + app.randomtime+=time; + } + }catch(Exception e){ + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelPerformanceTest.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelPerformanceTest.java new file mode 100644 index 00000000..5f53131b --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelPerformanceTest.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.test; + + import com.solidosystems.tuplesoup.core.*; + import com.solidosystems.tuplesoup.filter.*; + +import dstm2.Init; + import java.util.*; + import java.io.*; + + +public class ParallelPerformanceTest extends BasicTest implements Runnable{ + + long writetime; + long readtime; + long randomtime; + + public ParallelPerformanceTest(){ + String path="/home/navid/Volumes/My Book/test/"; + try{ + //int records=10; + int records=5; + for(int i=1;i<2;i++){ + outbr("Running Parallel DualFileTable Performance test"); + outbr(1,i+" x "+(records/i)+" Large records"); + + // outbr(2,"Memory index"); + /* Table table=new DualFileTable("Performance-test",path,Table.MEMORY); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles();*/ + + /* outbr(2,"Flat index"); + table=new DualFileTable("Performance-test",path,Table.FLAT); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles();*/ + + outbr(2,"Paged index"); + //Table table=new DualFileTable("Performance-test",path,Table.PAGED); + TableTransactional table=new DualFileTableTransactional("Performance-test",path,TableTransactional.PAGED); + benchmark(table,5,(records/i)); + table.close(); + // table.deleteFiles(); + + // outbr("Running Parallel HashedTable Performance test"); + //outbr(1,i+" x "+(records/i)+" Large records"); + + /* outbr(2,"Memory index"); + table=new HashedTable("Performance-test",path,Table.MEMORY); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles(); + + outbr(2,"Flat index"); + table=new HashedTable("Performance-test",path,Table.FLAT); + benchmark(table,i,(records/i)); + table.close(); + table.deleteFiles();*/ + + // outbr(2,"Paged index"); + //table=new HashedTableTransactional("Performance-test",path,TableTransactional.PAGED); + // table=new HashedTableTransactional("Performance-test",path,TableTransactional.PAGED); + // benchmark(table,i,(records/i)); + // table.close(); + // table.deleteFiles();*/ + } + + + }catch(Exception e){ + e.printStackTrace(); + } + } + public static void main(String[] args){ + Init.init(); + new ParallelPerformanceTest(); + } + + public void benchmark(TableTransactional table/*Table table*/,int threadcount, int records) throws Exception{ + writetime=0; + readtime=0; + randomtime=0; + List lst=new ArrayList(); + for(int i=0;i hash){ + Set keys=hash.keySet(); + Iterator it=keys.iterator(); + while(it.hasNext()){ + String key=it.next(); + outbr(4,key+" "+hash.get(key)); + } + } +} \ No newline at end of file diff --git a/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelThread.java b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelThread.java new file mode 100644 index 00000000..13a1e691 --- /dev/null +++ b/Robust/Transactions/tuplesoupdstm2version/src/com/solidosystems/tuplesoup/test/ParallelThread.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2007, Solido Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of Solido Systems nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + package com.solidosystems.tuplesoup.test; + + import com.solidosystems.tuplesoup.core.*; + import com.solidosystems.tuplesoup.filter.*; + + import java.util.*; + import java.io.*; + + +public class ParallelThread implements Runnable{ + String id; + int records; + ParallelPerformanceTest app; + //Table table; + TableTransactional table; + + public ParallelThread(ParallelPerformanceTest app,TableTransactional table/*Table table*/,String id,int records){ + this.id=id; + this.records=records; + this.app=app; + this.table=table; + } + + public void run(){ + try{ + long time=app.benchmarkLargeWrite(table,records,id); + synchronized(app){ + app.writetime+=time; + } + time=app.benchmarkLargeRead(table,records,id); + synchronized(app){ + app.readtime+=time; + } + time=app.benchmarkLargeRandomRead(table,records,id); + synchronized(app){ + app.randomtime+=time; + } + }catch(Exception e){ + e.printStackTrace(); + } + + } +} \ No newline at end of file -- 2.34.1