--- /dev/null
+/*
+ * 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 TransactionalIO.core.TransactionalFile;
+import TransactionalIO.interfaces.IOOperations;
+import java.io.*;
+import java.util.*;
+import java.nio.channels.*;
+import com.solidosystems.tuplesoup.filter.*;
+import dstm2.Configs;
+import dstm2.SpecialTransactionalFile;
+import dstm2.atomic;
+import dstm2.Thread;
+import dstm2.util.HashMap;
+import dstm2.factory.Factory;
+import java.util.concurrent.Callable;
+
+/**
+ * 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 IOOperations fileastream = null;
+ private IOOperations filebstream = null;
+ private TableIndex index = null;
+ private FilePosition fileaposition;
+ private FilePosition filebposition;
+ private boolean rowswitch = true;
+ private String title;
+ private String location;
+ private TableIndexNode indexcachefirst;
+ private TableIndexNode indexcachelast;
+ private intField indexcacheusage;
+ //private Hashtable<String, TableIndexNode> indexcache;
+ private HashMap<TableIndexNode> indexcache;
+ static Factory<FilePosition> filepositionfactory = Thread.makeFactory(FilePosition.class);
+ static Factory<intField> intfiledfactory = Thread.makeFactory(intField.class);
+ static Factory<TableIndexNode> tableindexnodefactory = Thread.makeFactory(TableIndexNode.class);
+
+ @atomic
+ public interface FilePosition {
+
+ Long getFileposition();
+
+ void setFileposition(Long val);
+ }
+
+ @atomic
+ public interface intField {
+
+ int getintValue();
+
+ void setintValue(int val);
+ }
+
+ /**
+ * 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 {
+
+ fileaposition = filepositionfactory.create();
+ filebposition = filepositionfactory.create();
+
+ fileaposition.setFileposition((long) 0);
+ filebposition.setFileposition((long) 0);
+
+ indexcacheusage = intfiledfactory.create();
+
+ 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.setintValue(0);
+ indexcache = new HashMap<TableIndexNode>();
+ }
+
+ /**
+ * 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();
+ }
+ 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(final int type) throws IOException {
+
+ switch (type) {
+ case FILEA:
+ if (fileastream == null) {
+ if (Configs.inevitable)
+ fileastream = new SpecialTransactionalFile/*RandomAccessFile*//*TransactionalFile*/(getFileName(FILEA), "rw");
+ else
+ fileastream = new TransactionalFile(getFileName(FILEA), "rw");
+
+ File ftest = new File(getFileName(FILEA));
+ fileaposition.setFileposition(ftest.length());
+ fileastream.seek(fileaposition.getFileposition());
+
+ }
+ break;
+ case FILEB:
+ if (filebstream == null) {
+ if (Configs.inevitable)
+ filebstream = new SpecialTransactionalFile/*RandomAccessFile*//*TransactionalFile*/(getFileName(FILEB), "rw");
+ else
+ filebstream = new TransactionalFile(getFileName(FILEB), "rw");
+
+ File ftest = new File(getFileName(FILEB));
+ filebposition.setFileposition(ftest.length());
+ filebstream.seek(filebposition.getFileposition());
+ }
+ 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.getintValue() > INDEXCACHESIZE) {
+ // remove first entry
+
+ TableIndexNode node = indexcachefirst;
+ indexcache.remove(node.getData().getId().hashCode());
+ int tmp = indexcacheusage.getintValue();
+ indexcacheusage.setintValue(tmp - 1);
+ // System.out.println("in the if " + Thread.currentThread());
+ indexcachefirst = node.getNext();
+ if (indexcachefirst == null) {
+ indexcachelast = null;
+ } else {
+ indexcachefirst.setPrevious(null);
+ }
+ }
+ // System.out.println("after first if " + Thread.currentThread() + " objetc " + Thread.getTransaction());
+ //TableIndexNode node = new TableIndexNode(indexcachelast, entry);
+ TableIndexNode node = tableindexnodefactory.create();
+ node.setPrevious(indexcachelast);
+ node.setData(entry);
+ node.setNext(null);
+
+ if (indexcachelast != null) {
+ indexcachelast.setNext(node);
+ }
+ if (indexcachefirst == null) {
+ indexcachefirst = node;
+ }
+ indexcachelast = node;
+ indexcache.put(entry.getId().hashCode(), node);
+
+ int tmp = indexcacheusage.getintValue();
+ indexcacheusage.setintValue(tmp + 1);
+
+ // }
+ }
+
+ private void addRowA(final Row row) throws IOException {
+ // synchronized(objecta){
+ openFile(FILEA);
+ Thread.doIt(new Callable<Boolean>() {
+
+ public Boolean call() throws IOException {
+
+ int pre = (int) fileastream.getFilePointer();
+
+ row.writeToStream(fileastream);
+ int post = (int) fileastream.getFilePointer();
+
+ index.addEntry(row.getId(), row.getSize(), FILEA, fileaposition.getFileposition());
+
+ if (INDEXCACHESIZE > 0) {
+ TableIndexEntry entry = new TableIndexEntry(row.getId(), row.getSize(), FILEA, fileaposition.getFileposition());
+ addCacheEntry(entry);
+ }
+ long tmp = fileaposition.getFileposition();
+ fileaposition.setFileposition(tmp + Row.calcSize(pre, post));
+ return true;
+ }
+ });
+ // }
+ }
+
+ private void addRowB(final Row row) throws IOException {
+ //synchronized(objectb){
+ openFile(FILEB);
+ Thread.doIt(new Callable<Boolean>() {
+
+ public Boolean call() throws IOException {
+
+ int pre = (int) filebstream.getFilePointer();
+
+ row.writeToStream(filebstream);
+ int post = (int) filebstream.getFilePointer();
+ //filebstream.flush();
+ // System.out.println(row);
+
+ index.addEntry(row.getId(), row.getSize(), FILEB, filebposition.getFileposition());
+ if (INDEXCACHESIZE > 0) {
+ TableIndexEntry entry = new TableIndexEntry(row.getId(), row.getSize(), FILEB, filebposition.getFileposition());
+ addCacheEntry(entry);
+ }
+ long tmp = filebposition.getFileposition();
+ filebposition.setFileposition(tmp + Row.calcSize(pre, post));
+ return true;
+ }
+ });
+ // }
+ }
+
+ private TableIndexEntry getCacheEntry(final String id) {
+ // synchronized (indexcache) {
+
+ if (indexcache.containsKey(id.hashCode())) {
+ TableIndexNode node = indexcache.get(id.hashCode());
+ if (node != indexcachelast) {
+ if (node == indexcachefirst) {
+ indexcachefirst = node.getNext();
+ }
+ //node.remove();
+ remove(node);
+ indexcachelast.setNext(node);
+ node.setPrevious(indexcachelast);
+ node.setNext(null);
+ indexcachelast = node;
+ }
+
+ return node.getData();
+ } else {
+ return null;
+ }
+
+ // }
+ }
+
+ /**
+ * Returns a tuplestream containing the given list of rows
+
+ public TupleStream getRows(List<String> 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<String> 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(final String id) throws IOException {
+ TableIndexEntry entry = null;
+ // Handle index entry caching
+ if (INDEXCACHESIZE > 0) {
+ // synchronized(indexcache){
+ entry = Thread.doIt(new Callable<TableIndexEntry>() {
+
+ public TableIndexEntry call() throws IOException {
+ TableIndexEntry entry = getCacheEntry(id);
+ if (entry == null) {
+ entry = index.scanIndex(id);
+ if (entry != null) {
+ addCacheEntry(entry);
+ }
+ }
+ return entry;
+ }
+ });
+ // }
+ } else {
+ entry = index.scanIndex(id);
+ }
+ if (entry != null) {
+ long dataoffset = 0;
+ DataInputStream data = null;
+ 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();
+
+
+ return row;
+ }
+
+ }
+ return null;
+ }
+
+ public void remove(TableIndexNode node) {
+ if (node.getPrevious() != null) {
+ node.getPrevious().setNext(node.getNext());
+ }
+ if (node.getNext() != null) {
+ node.getNext().setPrevious(node.getPrevious());
+ }
+ }
+
+ public TupleStream getRows(List<String> rows) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public TupleStream getRows(RowMatcher matcher) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public TupleStream getRows(List<String> rows, RowMatcher matcher) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public TupleStream getRows() throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 TransactionalIO.core.TransactionalFile;
+import TransactionalIO.interfaces.IOOperations;
+import dstm2.Configs;
+import dstm2.SpecialTransactionalFile;
+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;
+
+ //private RandomAccessFile out=null;
+ private IOOperations out=null;
+ private String filename;
+ private TableIndexPage[] root=null;
+
+
+ public PagedIndex(String filename) throws IOException{
+ this.filename=filename;
+ File ftest=new File(filename);
+ if(!ftest.exists())ftest.createNewFile();
+ //out=new RandomAccessFile(filename,"rw");
+ if (Configs.inevitable)
+ out=new SpecialTransactionalFile(filename,"rw");
+ else
+ out=new TransactionalFile(filename,"rw");
+
+ root=new TableIndexPage[INITIALPAGEHASH];
+ if(out.length()>0){
+ for(int i=0;i<INITIALPAGEHASH;i++){
+ root[i]=new TableIndexPage(this,out);
+ root[i].setFirst();
+ out.seek(root[i].getEndLocation());
+ System.out.println(root[i].getEndLocation());
+ }
+ }else{
+ for(int i=0;i<INITIALPAGEHASH;i++){
+ root[i]=TableIndexPage.createNewPage(this,out,PAGESIZE);
+ root[i].setFirst();
+ }
+ }
+ }
+
+
+
+ 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());
+ }
+
+
+
+
+ public /*synchronized*/ void addEntry(String id,int rowsize,int location,long position) throws IOException{
+ TableIndexPage page=getFirstFreePage(id);
+ page.addEntry(id,rowsize,location,position);
+
+ }
+ public /*synchronized*/ TableIndexEntry scanIndex(String id) throws IOException{
+ if(root==null)return null;
+ return root[rootHash(id)].scanIndex(id,id.hashCode());
+ }
+
+
+ public void close(){
+ try{
+ if(out!=null){
+ out.close();
+ }
+ }catch(Exception e){}
+ }
+
+ public Hashtable<String, Long> readStatistics() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void updateEntry(String id, int rowsize, int location, long position) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public List<TableIndexEntry> scanIndex(List<String> rows) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public List<TableIndexEntry> scanIndex() throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 TransactionalIO.interfaces.IOOperations;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Holds a row of data
+ */
+public class Row {
+
+ private String id;
+ private int size;
+ private Hashtable<String, Value> values;
+
+ /**
+ * Creates a new empty row with the given row id.
+ */
+ public Row(String id) {
+ this.id = id;
+ size = -1;
+ values = new Hashtable<String, Value>();
+ }
+
+ /**
+ * Returns the number of keys in this row.
+ */
+ public int getKeyCount() {
+ return values.size();
+ }
+
+ public Set<String> 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<String> keys = values.keySet();
+ out.writeInt(keys.size());
+ Iterator<String> 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<String> keys = values.keySet();
+ out.writeInt(keys.size());
+ Iterator<String> 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);
+ }
+
+ public void writeToStream(RandomAccessFile out) throws IOException {
+ int pre = (int) out.getFilePointer();
+ out.writeUTF(id);
+ Set<String> keys = values.keySet();
+ out.writeInt(keys.size());
+ Iterator<String> it = keys.iterator();
+ while (it.hasNext()) {
+ String key = it.next();
+ Value value = values.get(key);
+ out.writeUTF(key);
+ value.writeToStream(out);
+ }
+ int post = (int) out.getFilePointer();
+ int size = calcSize(pre, post);
+ this.size = size + 4;
+ out.writeInt(this.size);
+ }
+
+ public void writeToStream(IOOperations out) throws IOException {
+ int pre = (int) out.getFilePointer();
+ out.writeUTF(id);
+ Set<String> keys = values.keySet();
+ out.writeInt(keys.size());
+ Iterator<String> it = keys.iterator();
+ while (it.hasNext()) {
+ String key = it.next();
+ Value value = values.get(key);
+ out.writeUTF(key);
+ value.writeToStream(out);
+ }
+ int post = (int) out.getFilePointer();
+ int size = calcSize(pre, post);
+ this.size = size + 4;
+ out.writeInt(this.size);
+ }
+
+ /**
+ * Reads a full row from the given DataInputStream and returns it.
+ */
+ public static Row readFromStream(DataInputStream in) throws IOException {
+ String id = in.readUTF();
+ Row row = new Row(id);
+ int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ String key = in.readUTF();
+ Value value = Value.readFromStream(in);
+ row.put(key, value);
+ }
+ size = in.readInt();
+ row.size = size;
+ return row;
+ }
+
+ /**
+ * Returns a string representing this row formatted as the following example:
+ * (1732)=>{"name":string:"Kasper J. Jeppesen","age":int:31}
+ *
+ * @return a string representation of this row
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("(" + id + ")=>{");
+ Iterator<String> it = values.keySet().iterator();
+ boolean first = true;
+ while (it.hasNext()) {
+ if (!first) {
+ buf.append(",");
+ } else {
+ first = false;
+ }
+ 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 < indentation; i++) {
+ buf.append(" ");
+ }
+ return toBasicXMLString(buf.toString());
+ }
+
+ /**
+ * Creates a basic xml representation of the row as shown in the following sample:
+ * <row id="1">
+ * <value name="foo" type="string">Bar</value>
+ * </row>
+ */
+ public String toBasicXMLString(String indentation) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(indentation);
+ buf.append("<row id=\"" + id + "\">\n");
+ Iterator<String> 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("</row>\n");
+ return buf.toString();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+
+
+ /**
+ * 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;
+
+
+ /**
+ * Returns a tuplestream containing the given list of rows
+ */
+ public TupleStream getRows(List<String> 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<String> 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
--- /dev/null
+/*
+ * 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.*;
+
+public interface TableIndex{
+ //public Hashtable<String,Long> 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<TableIndexEntry> scanIndex(List<String> rows) throws IOException;
+ public List<TableIndexEntry> scanIndex() throws IOException;
+ public void close();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 TransactionalIO.interfaces.IOOperations;
+import java.io.*;
+
+public class TableIndexEntry implements Comparable<TableIndexEntry>{
+ 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 long getPosition(){
+ return position;
+ }
+
+ public int getLocation(){
+ return location;
+ }
+
+ public int getRowSize(){
+ return rowsize;
+ }
+
+ public int compareTo(TableIndexEntry obj) throws ClassCastException{
+ TableIndexEntry ent=(TableIndexEntry)obj;
+ if(position<ent.position)return -1;
+ if(position==ent.position)return 0;
+ return 1;
+ }
+
+ public boolean equals(Object obj){
+ try{
+ TableIndexEntry ent=(TableIndexEntry)obj;
+ if(ent.location==location){
+ if(ent.position==position){
+ if(ent.id.equals(id)){
+ return true;
+ }
+ }
+ }
+ }catch(ClassCastException e){}
+ return false;
+ }
+
+ public int getSize(){
+ if(size<0)calcSize();
+ return size;
+ }
+ public void setSize(int size){
+ this.size=size;
+ }
+ private void calcSize(){
+ try{
+ ByteArrayOutputStream bout=new ByteArrayOutputStream();
+ DataOutputStream dout=new DataOutputStream(bout);
+ dout.writeInt(id.hashCode());
+ dout.writeShort(id.length());
+ dout.writeChars(id);
+ dout.writeInt(rowsize);
+ dout.writeByte(location);
+ //System.out.println(" index calc long " + position);
+ dout.writeLong(position);
+ setSize(bout.size());
+ dout.close();
+ bout.close();
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ protected void writeData(RandomAccessFile out) throws IOException{
+ long pre=out.getFilePointer();
+ out.writeInt(id.hashCode());
+ out.writeShort(id.length());
+ out.writeChars(id);
+ out.writeInt(rowsize);
+ out.writeByte(location);
+ out.writeLong(position);
+ setSize((int)(out.getFilePointer()-pre));
+ }
+
+ protected void writeData(IOOperations out) throws IOException{
+ long pre=out.getFilePointer();
+ out.writeInt(id.hashCode());
+ out.writeShort(id.length());
+ out.writeChars(id);
+ out.writeInt(rowsize);
+ out.writeByte(location);
+// System.out.println("long index entry" + position);
+ out.writeLong(position);
+ setSize((int)(out.getFilePointer()-pre));
+ }
+
+
+
+
+
+ protected static TableIndexEntry lookForData(String id, IOOperations in) throws IOException{
+ int scanhash=id.hashCode();
+ int datahash=in.readInt();
+ int num=in.readShort();
+ if(scanhash!=datahash){
+ in.skipBytes(4+1+8+num*2);
+ return null;
+ }
+ StringBuilder buf=new StringBuilder(num);
+ for(int i=0;i<num;i++){
+ char c = in.readChar();
+ buf.append(c);
+ }
+ String readid=buf.toString();
+ if(!readid.equals(id)){
+ in.skipBytes(4+1+8);
+ return null;
+ }
+
+ int rowsize=in.readInt();
+ int location=in.readByte();
+ long position=in.readLong();
+ TableIndexEntry tmp=new TableIndexEntry(id,rowsize,location,position);
+ return tmp;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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;
+
+@atomic public interface TableIndexNode extends AtomicSuperClass{
+
+ TableIndexNode getPrevious();
+ TableIndexEntry getData();
+ TableIndexNode getNext();
+
+ void setPrevious(TableIndexNode val);
+ void setData(TableIndexEntry val);
+ void setNext(TableIndexNode val);
+}
+
+/*public class TableIndexNode implements AtomicSuperClass {
+
+ private TableIndexNode previous;
+ private TableIndexEntry data;
+ private TableIndexNode next;
+
+ public TableIndexNode() {
+ previous = null;
+ data = null;
+ next = null;
+ }
+
+ public TableIndexNode(TableIndexEntry entry) {
+ previous = null;
+ data = entry;
+ next = null;
+ }
+
+ public TableIndexNode(TableIndexNode prev, TableIndexEntry entry) {
+ previous = prev;
+ data = entry;
+ next = null;
+ }
+
+ public TableIndexNode(TableIndexNode prev, TableIndexEntry entry, TableIndexNode nex) {
+ previous = prev;
+ data = entry;
+ next = nex;
+ }
+
+ public TableIndexEntry getData() {
+ return data;
+ }
+
+ public TableIndexNode getPrevious() {
+ return previous;
+ }
+
+ public TableIndexNode getNext() {
+ return next;
+ }
+
+ public void setNext(TableIndexNode node) {
+ next = node;
+ }
+
+ public void setPrevious(TableIndexNode node) {
+ previous = node;
+ }
+
+ public void setData(TableIndexEntry entry) {
+ data = entry;
+ }
+
+ public void remove() {
+ if (previous != null) {
+ previous.setNext(next);
+ }
+ if (next != null) {
+ next.setPrevious(previous);
+ }
+ }*/
\ No newline at end of file
--- /dev/null
+/*
+ * 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 TransactionalIO.interfaces.IOOperations;
+import dstm2.atomic;
+import dstm2.Thread;
+import dstm2.factory.Factory;
+import java.io.*;
+import java.util.*;
+
+public class TableIndexPage{
+ private final static int BASEOFFSET=4+8+8+4+4;
+ //private RandomAccessFile file=null;
+ private IOOperations 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;
+ static Factory<TableIndexPageTSInf> factory = Thread.makeFactory(TableIndexPageTSInf.class);
+ TableIndexPageTSInf tableindexpage;
+
+ @atomic public interface TableIndexPageTSInf{
+ Long getNext();
+ Long getLower();
+ Long getLocation();
+ int getSize();
+ int getOffset();
+ int getStarthash();
+ int getEndhash();
+ boolean getFirst();
+ TableIndexPage getNextpage();
+ TableIndexPage getLowerpage();
+
+
+ void setLowerpage(TableIndexPage lowerpage);
+ void setNextpage(TableIndexPage nextpage);
+ void setFirst(boolean val);
+ void setEndhash(int val);
+ void setStarthash(int val);
+ void setOffset(int offset);
+ void setNext(Long next);
+ void setSize(int size);
+ void setLocation(Long location);
+ void setLower(Long val);
+ }
+
+
+ public TableIndexPage(PagedIndex index, IOOperations/*RandomAccessFile*/ file) throws IOException{
+ this.file=file;
+ this.index=index;
+ tableindexpage = factory.create();
+ tableindexpage.setFirst(false);
+ tableindexpage.setLocation(file.getFilePointer());
+ tableindexpage.setSize(file.readInt());
+ tableindexpage.setNext(file.readLong());
+ tableindexpage.setLower(file.readLong());
+ tableindexpage.setOffset(file.readInt());
+ tableindexpage.setEndhash(file.readInt());
+ if(tableindexpage.getOffset()>0) {
+ tableindexpage.setStarthash(file.readInt());
+ }
+ }
+
+ public static TableIndexPage createNewPage(PagedIndex index, IOOperations file,int size) throws IOException{
+ long pre=file.length();
+ file.seek(pre);
+ byte[] dummy = new byte[size+BASEOFFSET];
+ file.write(dummy);
+ //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);
+
+ return new TableIndexPage(index,file);
+ }
+
+
+
+ public void setFirst(){
+ tableindexpage.setFirst(true);
+ }
+
+ public long getLocation(){
+ return tableindexpage.getLocation();
+ }
+ public long getEndLocation(){
+ return tableindexpage.getLocation()+tableindexpage.getSize()+BASEOFFSET;
+ }
+
+ public String toString(){
+ StringBuffer buf=new StringBuffer();
+ buf.append("{\n");
+ buf.append(" location "+tableindexpage.getLocation()+"\n");
+ buf.append(" size "+tableindexpage.getSize()+"\n");
+ buf.append(" next "+tableindexpage.getNext()+"\n");
+ buf.append(" lower "+tableindexpage.getLower()+"\n");
+ buf.append(" offset "+tableindexpage.getOffset()+"\n");
+ buf.append(" starthash "+tableindexpage.getStarthash()+"\n");
+ buf.append(" endhash "+tableindexpage.getEndhash()+"\n");
+ buf.append("}\n");
+ return buf.toString();
+ }
+
+ private void updateMeta() throws IOException{
+ file.seek(tableindexpage.getLocation());
+ file.writeInt(tableindexpage.getSize());
+ file.writeLong(tableindexpage.getNext());
+ file.writeLong(tableindexpage.getLower());
+ file.writeInt(tableindexpage.getOffset());
+ file.writeInt(tableindexpage.getEndhash());
+ }
+
+ public TableIndexEntry scanIndex(String id,int hashcode) throws IOException{
+ if(!tableindexpage.getFirst()){
+ if(hashcode<tableindexpage.getStarthash()){
+ if(tableindexpage.getLower()==-1)return null;
+ if(tableindexpage.getLowerpage()==null){
+ file.seek(tableindexpage.getLower());
+ //tableindexpage.setLowerpage();
+ //TableIndexPage tmp = new TableIndexPage(index,file);
+ //tableindexpage.setLowerpage(tmp.tableindexpage);
+ tableindexpage.setLowerpage(new TableIndexPage(index,file));
+ }
+
+ return tableindexpage.getLowerpage().scanIndex(id,hashcode);
+ }
+ }
+ if(hashcode>tableindexpage.getEndhash()){
+ if(tableindexpage.getNext()==-1)return null;
+ if(tableindexpage.getNextpage()==null){
+ file.seek(tableindexpage.getNext());
+ tableindexpage.setNextpage(new TableIndexPage(index,file));
+ }
+ // index.stat_page_next++;
+ return tableindexpage.getNextpage().scanIndex(id,hashcode);
+ }
+ file.seek(tableindexpage.getLocation()+BASEOFFSET);
+ long pre=file.getFilePointer();
+ while(file.getFilePointer()<pre+tableindexpage.getOffset()){
+ TableIndexEntry entry=TableIndexEntry.lookForData(id,file);
+ if(entry!=null)return entry;
+ }
+ if(tableindexpage.getNext()==-1)return null;
+ if(tableindexpage.getNextpage()==null){
+ file.seek(tableindexpage.getNext());
+ tableindexpage.setNextpage(new TableIndexPage(index,file));
+ }
+
+ return tableindexpage.getNextpage().scanIndex(id,hashcode);
+ }
+
+ protected TableIndexPage getFirstFreePage(String id,int hashcode) throws IOException{
+ // Is this an empty page?
+ if(tableindexpage.getOffset()==0){
+ return this;
+ }
+ // Is this hash lower than the starthash
+ if(!tableindexpage.getFirst()){
+ if(hashcode<tableindexpage.getStarthash()){
+ if(tableindexpage.getLower()==-1){
+ tableindexpage.setLower(file.length());
+ updateMeta();
+ return createNewPage(index,file,PagedIndex.PAGESIZE);
+ }
+ if(tableindexpage.getLowerpage()==null){
+ file.seek(tableindexpage.getLower());
+ tableindexpage.setLowerpage(new TableIndexPage(index,file));
+ }
+ // index.stat_page_branch++;
+ return tableindexpage.getLowerpage().getFirstFreePage(id,hashcode);
+ }
+ }
+ // Do we have space in this page
+ if(tableindexpage.getSize()-tableindexpage.getOffset()>id.length()*2+4+4+8+1+2)return this;
+ // Check next
+ if(tableindexpage.getNext()==-1){
+ tableindexpage.setNext(file.length());
+ updateMeta();
+ return createNewPage(index,file,PagedIndex.PAGESIZE);
+ }
+ if(tableindexpage.getNextpage()==null){
+ file.seek(tableindexpage.getNext());
+ tableindexpage.setNextpage(new TableIndexPage(index,file));
+ }
+
+ return tableindexpage.getNextpage().getFirstFreePage(id,hashcode);
+ }
+
+ public void addEntry(String id,int rowsize,int location,long position) throws IOException{
+ if(tableindexpage.getOffset()==0) tableindexpage.setStarthash(id.hashCode());
+ file.seek(this.tableindexpage.getLocation()+BASEOFFSET+tableindexpage.getOffset());
+ TableIndexEntry entry=new TableIndexEntry(id,rowsize,location,position);
+ entry.writeData(file);
+ tableindexpage.setOffset(tableindexpage.getOffset()+entry.getSize());
+ if(id.hashCode()>tableindexpage.getEndhash())tableindexpage.setEndhash(id.hashCode());
+ updateMeta();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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<TupleStream> streams;
+ private TupleStream current=null;
+ private Row next=null;
+
+ public TupleStreamMerger(){
+ streams=new ArrayList<TupleStream>();
+ }
+
+ 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
--- /dev/null
+/*
+ * 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 TransactionalIO.core.TransactionalFile;
+import TransactionalIO.interfaces.IOOperations;
+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.
+ * <ul>
+ * <li>If this Value is a numeric type, then the other Value will be asked to deliver the same numeric type for the comparison.
+ * <li>If this Value is a string, then both values will be asked to deliver a double value for the comparison.
+ * <li>If this Value is a timestamp, then both values will be asked to deliver a long value for the comparison.
+ * <li>If this Value is a boolean, false will be returned.
+ * </ul>
+ *
+ * @param value the value this value should be compared to
+ * @return true if this value is less than the value given as a parameter, false otherwise
+ */
+ public boolean lessThan(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;
+ }
+
+ /**
+ * Attempts to compare this Value to the value given as parameter and returns true if this value is greater than the value given as a parameter.
+ * The types used for the comparison will always be based on the type of this Value based on the following rules.
+ * <ul>
+ * <li>If this Value is a numeric type, then the other Value will be asked to deliver the same numeric type for the comparison.
+ * <li>If this Value is a string, then both values will be asked to deliver a double value for the comparison.
+ * <li>If this Value is a timestamp, then both values will be asked to deliver a long value for the comparison.
+ * <li>If this Value is a boolean, false will be returned.
+ * </ul>
+ *
+ * @param value the value this value should be compared to
+ * @return true if this value is greater than the value given as a parameter, false otherwise
+ */
+ public boolean greaterThan(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<binary.length;i++){
+ if(binary[i]!=val.binary[i])return false;
+ }
+ }
+ return true;
+ }
+ }
+ }catch(Exception e){}
+ return false;
+ }
+
+ /**
+ * Returns a string representation of this object.
+ */
+ public String toString(){
+ return getString();
+ }
+
+ /**
+ * Returns a string representation of this object (identical to toString)
+ */
+ public String get(){
+ return getString();
+ }
+
+ /**
+ * Returns this value as an xml tag with the given key set as an attribute called name.
+ * The following string is an example of the int value 1234 created with the key foo <value name="foo" type="int">1234</value>
+ */
+ public String toBasicXMLString(String key){
+ switch(type){
+ case STRING : return "<value name=\""+key+"\" type=\"string\">"+str_value+"</value>";
+ case INT : return "<value name=\""+key+"\" type=\"int\">"+int_value+"</value>";
+ case LONG : return "<value name=\""+key+"\" type=\"long\">"+int_value+"</value>";
+ case FLOAT : return "<value name=\""+key+"\" type=\"float\">"+float_value+"</value>";
+ case DOUBLE : return "<value name=\""+key+"\" type=\"double\">"+float_value+"</value>";
+ case BOOLEAN : if(int_value==1){
+ return "<value name=\""+key+"\" type=\"boolean\">TRUE</value>";
+ }else{
+ return "<value name=\""+key+"\" type=\"boolean\">FALSE</value>";
+ }
+ case TIMESTAMP : return "<value name=\""+key+"\" type=\"timestamp\">"+new Date(int_value).toString()+"</value>";
+ case BINARY : return "<value name=\""+key+"\" type=\"binary\">"+getString()+"</value>";
+ }
+ return "<value name=\""+key+"\" type=\"null\"></value>";
+ }
+
+ /**
+ * Returns this value as an xml tag.
+ * The following string is an example of the int value 1234 <value type="int">1234</value>
+ */
+ public String toBasicXMLString(){
+ switch(type){
+ case STRING : return "<value type=\"string\">"+str_value+"</value>";
+ case INT : return "<value type=\"int\">"+int_value+"</value>";
+ case LONG : return "<value type=\"long\">"+int_value+"</value>";
+ case FLOAT : return "<value type=\"float\">"+float_value+"</value>";
+ case DOUBLE : return "<value type=\"double\">"+float_value+"</value>";
+ case BOOLEAN : if(int_value==1){
+ return "<value type=\"boolean\">TRUE</value>";
+ }else{
+ return "<value type=\"boolean\">FALSE</value>";
+ }
+ case TIMESTAMP : return "<value type=\"timestamp\">"+new Date(int_value).toString()+"</value>";
+ case BINARY : return "<value type=\"binary\">"+getString()+"</value>";
+ }
+ return "<value type=\"null\"></value>";
+ }
+
+ /**
+ * Returns a string representation of this value
+ */
+ public String getString(){
+ switch(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<binary.length;i++){
+ byte b=binary[i];
+ buf.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1,3));
+ }
+ return buf.toString();
+ }
+ return "";
+ }
+
+ /**
+ * Attempts to return an integer representation of this value.
+ * Numerical values will be returned directly (demoted if necessary).
+ * Boolean values will be returned as 1 or 0.
+ * Timestamp values will be returned as a unix timestamp representation divided by 1000.
+ * String values will be atempted to be converted into an int, if that fails, 0 will be returned.
+ * Everything else will return 0.
+ */
+ public int getInt(){
+ try{
+ switch(type){
+ case STRING : return Integer.parseInt(str_value);
+ case INT : return (int)int_value;
+ case LONG : return (int)int_value;
+ case FLOAT : return (int)float_value;
+ case DOUBLE : return (int)float_value;
+ case BOOLEAN : return (int)int_value;
+ case TIMESTAMP : return (int)(int_value/1000);
+ }
+ }catch(Exception e){}
+ return 0;
+ }
+
+ /**
+ * Attempts to return a long representation of this value.
+ * Numerical values will be returned directly.
+ * Boolean values will be returned as 1 or 0.
+ * Timestamp values will be returned as a unix timestamp representation.
+ * String values will be atempted to be converted into an int, if that fails, 0 will be returned.
+ * Everything else will return 0.
+ */
+ public long getLong(){
+ try{
+ switch(type){
+ case STRING : return Long.parseLong(str_value);
+ case INT : return int_value;
+ case LONG : return int_value;
+ case FLOAT : return (long)float_value;
+ case DOUBLE : return (long)float_value;
+ case BOOLEAN : return int_value;
+ case TIMESTAMP : return int_value;
+ }
+ }catch(Exception e){}
+ return 0;
+ }
+
+ /**
+ * Attempts to return a float representation of this value.
+ * Numerical values will be returned directly (demoted if necessary).
+ * Boolean values will be returned as 1 or 0.
+ * Timestamp values will be returned as a unix timestamp representation divided by 1000.
+ * String values will be atempted to be converted into a float, if that fails, 0 will be returned.
+ * Everything else will return 0.
+ */
+ public float getFloat(){
+ try{
+ switch(type){
+ case STRING : return Float.parseFloat(str_value);
+ case INT : return (float)int_value;
+ case LONG : return (float)int_value;
+ case FLOAT : return (float)float_value;
+ case DOUBLE : return (float)float_value;
+ case BOOLEAN : return (float)int_value;
+ case TIMESTAMP : return (float)(int_value/1000);
+ }
+ }catch(Exception e){}
+ return 0.0f;
+ }
+
+ /**
+ * Attempts to return a double representation of this value.
+ * Numerical values will be returned directly.
+ * Boolean values will be returned as 1 or 0.
+ * Timestamp values will be returned as a unix timestamp representation divided by 1000.
+ * String values will be atempted to be converted into a float, if that fails, 0 will be returned.
+ * Everything else will return 0.
+ */
+ public double getDouble(){
+ try{
+ switch(type){
+ case STRING : return Double.parseDouble(str_value);
+ case INT : return (double)int_value;
+ case LONG : return (double)int_value;
+ case FLOAT : return (double)float_value;
+ case DOUBLE : return (double)float_value;
+ case BOOLEAN : return (double)int_value;
+ case TIMESTAMP : return (double)(int_value);
+ }
+ }catch(Exception e){}
+ return 0.0;
+ }
+
+ /**
+ * Returns a boolean representation of this value.
+ * Boolean values will be returned directly.
+ * Integer values equalling 1 will be returned as true.
+ * String values equalling true,1,t,yes,on will be returned as true (case insensitive).
+ * Everything else will be returned as false.
+ *
+ * @return a boolean representation of this value.
+ */
+ public boolean getBoolean(){
+ try{
+ switch(type){
+ case STRING : if(str_value.toLowerCase().trim().equals("true"))return true;
+ if(str_value.trim().equals("1"))return true;
+ if(str_value.toLowerCase().trim().equals("t"))return true;
+ if(str_value.toLowerCase().trim().equals("yes"))return true;
+ if(str_value.toLowerCase().trim().equals("on"))return true;
+ case INT : if(int_value==1)return true;
+ case LONG : if(int_value==1)return true;
+ case FLOAT : if(float_value==1.0f)return true;
+ case DOUBLE : if(float_value==1.0)return true;
+ case BOOLEAN : if(int_value==1)return true;
+ }
+ }catch(Exception e){}
+ return false;
+ }
+
+ /**
+ * Attempts to return this value as a Date object.
+ * For non date numerical values, the following rules will be used for conversion:
+ * int and float will be multiplied by 1000 and used as a unix timestamp.
+ * long and double will be used directly as a unix timestamp.
+ * Any other type will result in a Date object initialized with 0.
+ *
+ * @return a Date object representation of this value
+ */
+ public Date getTimestamp(){
+ try{
+ switch(type){
+ case INT : return new Date(int_value*1000l);
+ case LONG : return new Date(int_value);
+ case FLOAT : return new Date((long)(float_value*1000l));
+ case DOUBLE : return new Date((long)float_value);
+ case TIMESTAMP : return new Date(int_value);
+ }
+ }catch(Exception e){}
+ return new Date(0);
+ }
+
+ public byte[] getBinary(){
+ switch(type){
+ case BINARY : return binary;
+ }
+ return null;
+ }
+
+ /**
+ * Attempts to write this Value to the given DataOutputStream.
+ * The Value will be written as a byte signifying the type of the Value, followed by the actual Value in the native format used by DataOutput.
+ * The exception to this is the string which is written as an integer followed by each character as a single char.
+ *
+ * @param out the DataOutputStream the Value should be written to
+ */
+ public void writeToStream(DataOutputStream out) throws IOException{
+ out.writeByte(type);
+ switch(type){
+ case STRING : out.writeInt(str_value.length());
+ for(int i=0;i<str_value.length();i++){
+ out.writeChar(str_value.charAt(i));
+ }
+ break;
+ case INT : out.writeInt((int)int_value);
+ break;
+ case LONG :
+ out.writeLong(int_value);
+ break;
+ case FLOAT : out.writeFloat((float)float_value);
+ break;
+ case DOUBLE :
+ System.out.println("double value" + float_value);
+ out.writeDouble(float_value);
+ break;
+ case BOOLEAN: out.writeBoolean(int_value==1);
+ break;
+ case TIMESTAMP: out.writeLong(int_value);
+ break;
+ case BINARY : out.writeInt(binary.length);
+ out.write(binary,0,binary.length);
+ break;
+ }
+ }
+
+
+ public void writeToStream(RandomAccessFile out) throws IOException{
+ out.writeByte(type);
+ switch(type){
+ case STRING : out.writeInt(str_value.length());
+ for(int i=0;i<str_value.length();i++){
+ out.writeChar(str_value.charAt(i));
+ }
+ break;
+ case INT : out.writeInt((int)int_value);
+ break;
+ case LONG : out.writeLong(int_value);
+ break;
+ case FLOAT : out.writeFloat((float)float_value);
+ break;
+ case DOUBLE : out.writeDouble(float_value);
+ break;
+ case BOOLEAN: out.writeBoolean(int_value==1);
+ break;
+ case TIMESTAMP: out.writeLong(int_value);
+ break;
+ case BINARY : out.writeInt(binary.length);
+ out.write(binary,0,binary.length);
+ break;
+ }
+ }
+
+
+ public void writeToStream(IOOperations out) throws IOException{
+ out.writeByte(type);
+ switch(type){
+ case STRING : out.writeInt(str_value.length());
+ for(int i=0;i<str_value.length();i++){
+ out.writeChar(str_value.charAt(i));
+ }
+ break;
+ case INT : out.writeInt((int)int_value);
+ break;
+ case LONG : out.writeLong(int_value);
+ break;
+ case FLOAT : out.writeFloat((float)float_value);
+ break;
+ case DOUBLE : out.writeDouble(float_value);
+ break;
+ case BOOLEAN: out.writeBoolean(int_value==1);
+ break;
+ case TIMESTAMP: out.writeLong(int_value);
+ break;
+ case BINARY : out.writeInt(binary.length);
+ out.write(binary);
+ //out.write(binary,0,binary.length);
+ break;
+ }
+ }
+
+
+
+ public void writeToStream(TransactionalFile out) throws IOException{
+ out.writeByte(type);
+ switch(type){
+ case STRING : out.writeInt(str_value.length());
+ for(int i=0;i<str_value.length();i++){
+ out.writeChar(str_value.charAt(i));
+ }
+ break;
+ case INT : out.writeInt((int)int_value);
+ break;
+ case LONG : out.writeLong(int_value);
+ break;
+ case FLOAT : out.writeFloat((float)float_value);
+ break;
+ case DOUBLE : out.writeDouble(float_value);
+ break;
+ case BOOLEAN: out.writeBoolean(int_value==1);
+ break;
+ case TIMESTAMP: out.writeLong(int_value);
+ break;
+ case BINARY : out.writeInt(binary.length);
+ out.write(binary,0,binary.length);
+ break;
+ }
+ }
+ /**
+ * Attempts to write this Value to the given DataOutputStream.
+ * The Value will be written as a byte signifying the type of the Value, followed by the actual Value in the native format used by DataOutput.
+ * The exception to this is the string which is written as an integer followed by each character as a single char.
+ *
+ * @param out the DataOutputStream the Value should be written to
+ */
+ public void writeToFile(DataOutput out) throws IOException{
+ out.writeByte(type);
+ switch(type){
+ case STRING : out.writeInt(str_value.length());
+ for(int i=0;i<str_value.length();i++){
+ out.writeChar(str_value.charAt(i));
+ }
+ break;
+ case INT : out.writeInt((int)int_value);
+ break;
+ case LONG : out.writeLong(int_value);
+ break;
+ case FLOAT : out.writeFloat((float)float_value);
+ break;
+ case DOUBLE : out.writeDouble(float_value);
+ break;
+ case BOOLEAN: out.writeBoolean(int_value==1);
+ break;
+ case TIMESTAMP: out.writeLong(int_value);
+ break;
+ case BINARY : out.writeInt(binary.length);
+ out.write(binary,0,binary.length);
+ }
+ }
+
+ /**
+ * Attempts to read a new Value from the given DataInputStream.
+ * The Value should be in the format delivered by writeToStream.
+ *
+ * @param in the DataInputStream the Value should be read from
+ * @return the Value read from the stream
+ */
+ public static Value readFromStream(DataInputStream in) throws IOException{
+ byte type=in.readByte();
+ switch(type){
+ case STRING : int size=in.readInt();
+ StringBuffer buf=new StringBuffer();
+ for(int i=0;i<size;i++){
+ buf.append(in.readChar());
+ }
+ return new Value(buf.toString());
+ case INT : return new Value(in.readInt());
+ case LONG : return new Value(in.readLong());
+ case FLOAT : return new Value(in.readFloat());
+ case DOUBLE : return new Value(in.readDouble());
+ case BOOLEAN: return new Value(in.readBoolean());
+ case TIMESTAMP: return new Value(new Date(in.readLong()));
+ case BINARY : int length=in.readInt();
+ byte[] abuf=new byte[length];
+ int read=0;
+ while(read<length){
+ read+=in.read(abuf,read,length-read);
+ }
+ return new Value(abuf);
+
+ }
+ return new Value();
+ }
+
+ /**
+ * Initializes this Value with the given String.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(String val){
+ str_value=val;
+ type=STRING;
+ }
+
+ public Value(byte[] val){
+ binary=val;
+ type=BINARY;
+ }
+
+ /**
+ * Initializes this Value with the given Date.
+ * The Dates internal long value delivered by the getTime() method will be used.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(Date val){
+ int_value=val.getTime();
+ type=TIMESTAMP;
+ }
+
+ /**
+ * Initializes this Value as null.
+ */
+ public Value(){
+ type=NULL;
+ }
+
+ /**
+ * Initializes this Value with the given int.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(int val){
+ int_value=val;
+ type=INT;
+ }
+
+ /**
+ * Initializes this Value with the given long.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(long val){
+ int_value=val;
+ type=LONG;
+ }
+
+ /**
+ * Initializes this Value with the given float.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(float val){
+ float_value=val;
+ type=FLOAT;
+ }
+
+ /**
+ * Initializes this Value with the given double.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(double val){
+ float_value=val;
+ type=DOUBLE;
+ }
+
+ /**
+ * Initializes this Value with the given boolean.
+ *
+ * @param val the value this Value object should represent
+ */
+ public Value(boolean val){
+ if(val){
+ int_value=1;
+ }else{
+ int_value=0;
+ }
+ type=BOOLEAN;
+ }
+ }
\ No newline at end of file
--- /dev/null
+/*
+ * 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 Conditional extends TupleStream{
+ private TupleStream stream;
+ private RowMatcher matcher;
+ private Row next;
+
+ public Conditional(TupleStream stream, RowMatcher matcher) throws IOException{
+ this.stream=stream;
+ this.matcher=matcher;
+ next=null;
+ readNext();
+ }
+
+ private void readNext() throws IOException{
+ next=null;
+ while(next==null){
+ if(!stream.hasNext())return;
+ Row row=stream.next();
+ if(matcher.matches(row)){
+ next=row;
+ }
+ }
+ }
+
+ public boolean hasNext() throws IOException{
+ if(next!=null)return true;
+ return false;
+ }
+
+ public Row next() throws IOException{
+ Row tmp=next;
+ readNext();
+ return tmp;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 HeapSort extends TupleStream{
+ public HeapSort(){
+
+ }
+ public void initialize(TupleStream source,List<SortRule> lst){
+
+ }
+ public abstract boolean hasNext();
+ public abstract Row next();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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<Row> sortlst;
+ private int offset;
+ private int datasize;
+
+ public JavaSort(){
+ }
+ public void initialize(String filename,TupleStream source,List<SortRule> lst) throws IOException{
+ sortlst=new ArrayList<Row>();
+ offset=0;
+ while(source.hasNext()){
+ sortlst.add(source.next());
+ }
+ Collections.sort(sortlst,new SortComparator(lst));
+ datasize=sortlst.size();
+ }
+ public boolean hasNext(){
+ if(offset<datasize)return true;
+ return false;
+ }
+ public Row next(){
+ return sortlst.get(offset++);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 Join extends TupleStream{
+ public final static int INNER=0;
+
+ private int type;
+ private TupleStream left;
+ private TupleStream right;
+ private String key;
+ private RowBuffer buf;
+ private String filename;
+
+ public Join(String filename,TupleStream left, TupleStream right, String key) throws IOException{
+ this.filename=filename;
+ this.left=left;
+ this.right=right;
+ this.key=key;
+ this.type=INNER;
+ joinData();
+ }
+
+ public Join(String filename,TupleStream left, TupleStream right, String key,int type) throws IOException{
+ this.filename=filename;
+ this.left=left;
+ this.right=right;
+ this.key=key;
+ this.type=type;
+ joinData();
+ }
+
+ private void joinData() throws IOException{
+ buf=new RowBuffer(filename);
+ // Raw nested loop operation
+
+ buf.prepare();
+ }
+
+ public Row next() throws IOException{
+ return buf.next();
+ }
+
+ public boolean hasNext() throws IOException{
+ return buf.hasNext();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 MergeSort extends Sort{
+ private int MEMLIMIT=65536;
+ private int BUFFERCACHE=65536;
+ private int BUFFERLIMIT=8192;
+
+ private RowBuffer result;
+
+ private int bufnum=0;
+
+ private String filename;
+
+ private SortComparator compare;
+
+
+ public MergeSort(int cachesize){
+ if(cachesize<32768){
+ MEMLIMIT=32768;
+ BUFFERCACHE=0;
+ BUFFERLIMIT=0;
+ }else if(cachesize<65536){
+ MEMLIMIT=32768;
+ BUFFERCACHE=cachesize-MEMLIMIT;
+ BUFFERLIMIT=BUFFERCACHE/4;
+ }else{
+ MEMLIMIT=cachesize/2;
+ BUFFERCACHE=MEMLIMIT;
+ BUFFERLIMIT=BUFFERCACHE/16;
+ }
+ if(BUFFERLIMIT<8192)BUFFERLIMIT=8192;
+ }
+
+ public void mergeSort(RowBuffer result,RowBuffer a,RowBuffer b) throws IOException{
+ a.prepare();
+ b.prepare();
+ Row rowb=null;
+ Row rowa=null;
+ while(a.hasNext()&&b.hasNext()){
+ if(rowa==null)rowa=a.next();
+ if(rowb==null)rowb=b.next();
+ int cmp=compare.compare(rowa,rowb);
+ if(cmp<=0){
+ result.addRow(rowa);
+ rowa=null;
+ }else{
+ result.addRow(rowb);
+ rowb=null;
+ }
+ }
+ if(rowa!=null)result.addRow(rowa);
+ if(rowb!=null)result.addRow(rowb);
+ while(a.hasNext()){
+ result.addRow(a.next());
+ }
+ while(b.hasNext()){
+ result.addRow(b.next());
+ }
+ }
+
+ public void mergeSort(List<RowBuffer> 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<SortRule> lst) throws IOException{
+ this.filename=filename;
+ compare=new SortComparator(lst);
+ bufnum=0;
+ result=new RowBuffer(filename+".result");
+ result.setCacheSize(BUFFERLIMIT);
+ List<RowBuffer> buffers=new ArrayList<RowBuffer>();
+ int usage=0;
+ List<Row> sortlst=new ArrayList<Row>();
+ 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.size();i++){
+ buf.addRow(sortlst.get(i));
+ }
+ buffers.add(buf);
+ usage=0;
+ sortlst=new ArrayList<Row>();
+ }
+ 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<sortlst.size();i++){
+ buf.addRow(sortlst.get(i));
+ }
+ buffers.add(buf);
+ mergeSort(buffers);
+ }
+ public boolean hasNext() throws IOException{
+ return result.hasNext();
+ }
+ public Row next() throws IOException{
+ return result.next();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 MergeSort2 extends Sort{
+ private int MEMLIMIT=65536;
+ private int BUFFERCACHE=65536;
+ private int BUFFERLIMIT=8192;
+
+ private int PREBUFFERS=256;
+
+ private RowBuffer result;
+
+ private int bufnum=0;
+
+ private String filename;
+
+ private SortComparator compare;
+
+
+ public MergeSort2(int cachesize){
+ if(cachesize<32768){
+ MEMLIMIT=32768;
+ BUFFERCACHE=0;
+ BUFFERLIMIT=0;
+ }else if(cachesize<65536){
+ MEMLIMIT=32768;
+ BUFFERCACHE=cachesize-MEMLIMIT;
+ BUFFERLIMIT=BUFFERCACHE/4;
+ }else{
+ MEMLIMIT=cachesize/2;
+ BUFFERCACHE=MEMLIMIT;
+ BUFFERLIMIT=BUFFERCACHE/16;
+ }
+ if(BUFFERLIMIT<8192)BUFFERLIMIT=8192;
+ }
+
+ public void mergeSort(RowBuffer result,RowBuffer a,RowBuffer b) throws IOException{
+ a.prepare();
+ b.prepare();
+ Row rowb=null;
+ Row rowa=null;
+ while(a.hasNext()&&b.hasNext()){
+ if(rowa==null)rowa=a.next();
+ if(rowb==null)rowb=b.next();
+ int cmp=compare.compare(rowa,rowb);
+ if(cmp<=0){
+ result.addRow(rowa);
+ rowa=null;
+ }else{
+ result.addRow(rowb);
+ rowb=null;
+ }
+ }
+ if(rowa!=null)result.addRow(rowa);
+ if(rowb!=null)result.addRow(rowb);
+ while(a.hasNext()){
+ result.addRow(a.next());
+ }
+ while(b.hasNext()){
+ result.addRow(b.next());
+ }
+ }
+
+ public void mergeSort(List<RowBuffer> 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<SortRule> 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<RowBuffer> buffers=new ArrayList<RowBuffer>();
+ int usage=0;
+
+ List<RowBuffer> prebuffers=new ArrayList<RowBuffer>();
+ List<Row> prebufferends=new ArrayList<Row>();
+ for(int i=0;i<PREBUFFERS;i++){
+ RowBuffer buf=new RowBuffer(filename+"."+(bufnum++));
+ buf.setCacheSize(allocBuffer());
+ prebuffers.add(buf);
+ }
+ int over=0;
+ RowBuffer overflow=new RowBuffer(filename+"."+(bufnum++));
+ overflow.setCacheSize(allocBuffer());
+ while(source.hasNext()){
+ Row rowa=source.next();
+ for(int i=0;(i<PREBUFFERS)&&(rowa!=null);i++){
+ if(i<prebufferends.size()){
+ Row rowb=prebufferends.get(i);
+ if(compare.compare(rowa,rowb)>0){
+ 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<prebufferends.size();i++){
+ buffers.add(prebuffers.get(i));
+ }
+ long postpart=System.currentTimeMillis();
+ System.out.println("preprocess in "+(postpart-prepart)+" ms overflow:"+over);
+ source=overflow;
+ overflow.prepare();
+
+ List<Row> sortlst=new ArrayList<Row>();
+ 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.size();i++){
+ buf.addRow(sortlst.get(i));
+ }
+ buffers.add(buf);
+ usage=0;
+ sortlst=new ArrayList<Row>();
+ }
+ 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<sortlst.size();i++){
+ buf.addRow(sortlst.get(i));
+ }
+ buffers.add(buf);
+ mergeSort(buffers);
+ }
+ public boolean hasNext() throws IOException{
+ return result.hasNext();
+ }
+ public Row next() throws IOException{
+ return result.next();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 QuickSort extends TupleStream{
+ public QuickSort(){
+
+ }
+ public void initialize(TupleStream source,List<SortRule> lst){
+
+ }
+ public abstract boolean hasNext();
+ public abstract Row next();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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<SortRule> lst){
+
+ }
+ public abstract boolean hasNext();
+ public abstract Row next();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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<Row> membuffer;
+ private String diskbuffer;
+ private DataOutputStream out;
+ private DataInputStream in;
+
+ private Row next=null;
+
+ public RowBuffer(String filename){
+ membuffer=new ArrayList<Row>();
+ 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.size()){
+ next=membuffer.get(mempointer++);
+ }else{
+ if(diskused){
+ try{
+ next=Row.readFromStream(in);
+ }catch(EOFException e){
+ next=null;
+ }
+ }else next=null;
+ }
+ }
+
+ public boolean hasNext() throws IOException{
+ if(next!=null)return true;
+ return false;
+ }
+
+ public Row next() throws IOException{
+ try{
+ if(next!=null){
+ Row tmp=next;
+ readNext();
+ return tmp;
+ }
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 abstract class Sort extends TupleStream{
+ public void initialize(String filename,TupleStream source,String key,int direction) throws IOException{
+ List<SortRule> lst=new ArrayList<SortRule>();
+ 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<SortRule> lst=new ArrayList<SortRule>();
+ 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<SortRule> lst) throws IOException;
+ public abstract boolean hasNext() throws IOException;
+ public abstract Row next() throws IOException;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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<Row>{
+ private List<SortRule> rules;
+
+ public SortComparator(List<SortRule> 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 List<String>errors=new ArrayList<String>();
+ 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
--- /dev/null
+/*
+ * 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.Configs;
+import dstm2.Init;
+import java.util.*;
+import dstm2.Thread;
+import java.io.*;
+
+public class ParallelPerformanceTest extends BasicTest implements Runnable {
+
+ long writetime;
+ long readtime;
+ long randomtime;
+
+ public ParallelPerformanceTest() {
+ String path = "/scratch/TransactionalIO/tuplesoupfiles/";
+ try {
+ int records = 100;
+ for (int i = 1; i < 2; i++) {
+ outbr("Running Parallel DualFileTable Performance test");
+ outbr(1, i + " x " + (records / i) + " Large records");
+ Table table;
+ /* 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 = new DualFileTable("Performance-test", path, Table.PAGED);
+ benchmark(table, 2, (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 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(args[0], Boolean.valueOf(args[1]));
+ new ParallelPerformanceTest();
+ }
+
+ public void benchmark(Table table, int threadcount, int records) throws Exception {
+ writetime = 0;
+ readtime = 0;
+ randomtime = 0;
+ List<Thread> lst = new ArrayList<Thread>();
+ long starttime = System.currentTimeMillis();
+ for (int i = 0; i < threadcount; i++) {
+ Thread thr = new Thread(new ParallelThread(this, table, i + "", records));
+ thr.start();
+ lst.add(thr);
+ }
+ for (int i = 0; i < threadcount; i++) {
+ lst.get(i).join();
+ }
+ long stoptime = System.currentTimeMillis();
+ System.out.println("\n\nExectuin time: " + (long) (stoptime - starttime));
+ long committed = Thread.totalCommitted;
+ long total = Thread.totalTotal;
+ if (total > 0) {
+ System.out.printf("Committed: %d\nTotal: %d\nPercent committed: (%d%%)\n",
+ committed,
+ total,
+ (100 * committed) / total);
+ } else {
+ System.out.println("No transactions executed!");
+ }
+ // outbr(3, "Write " + writetime + " ms");
+ // outbr(3, "Read " + readtime + " ms");
+ // outbr(3, "Random " + randomtime + " ms");
+ }
+
+ public void run() {
+ }
+
+ public long benchmarkLargeWrite(Table table, int records, String id) throws IOException {
+ long pre = System.currentTimeMillis();
+ for (int i = 0; i < records; i++) {
+ Row row = new Row(id + i);
+ if (Configs.inevitable) {
+ row.put("key1", "foobarbazinevitable");
+ } else {
+ row.put("key1", "foobarbaztransactiona");
+ }
+ row.put("key2", 123456);
+ row.put("key3", 3.141592);
+ row.put("key4", true);
+ row.put("key5", new Value(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}));
+ table.addRow(row);
+ }
+ long post = System.currentTimeMillis();
+ return post - pre;
+ }
+
+ public long benchmarkLargeRead(Table table, int records, String id) throws IOException {
+ long pre = System.currentTimeMillis();
+ TupleStream stream = table.getRows();
+ while (stream.hasNext()) {
+ stream.next();
+ }
+ long post = System.currentTimeMillis();
+ return post - pre;
+ }
+
+ public long benchmarkLargeRandomRead(Table table, int records, String id) throws IOException {
+ long pre = System.currentTimeMillis();
+ for (int i = 0; i < records; i++) {
+ Row row = table.getRow(id + (int) (Math.random() * records));
+ System.out.println(Thread.currentThread() + " " + row);
+ }
+ long post = System.currentTimeMillis();
+ return post - pre;
+ }
+
+ public void printStats(Hashtable<String, Long> hash) {
+ Set<String> keys = hash.keySet();
+ Iterator<String> it = keys.iterator();
+ while (it.hasNext()) {
+ String key = it.next();
+ outbr(4, key + " " + hash.get(key));
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.*;
+
+
+
+public class ParallelThread implements Runnable{
+ String id;
+ int records;
+ ParallelPerformanceTest app;
+ Table table;
+
+ public ParallelThread(ParallelPerformanceTest 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