2 * Copyright (c) 2007, Solido Systems
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
15 * Neither the name of Solido Systems nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 package com.solidosystems.tuplesoup.core;
34 import dstm2.AtomicArray;
38 import java.nio.channels.*;
40 public class PagedIndex implements TableIndex{
42 public @atomic interface PageIndexTSInf{
45 Long getStat_create_page();
46 Long getStat_page_next();
47 Long getStat_page_branch();
48 AtomicArray<TableIndexPageTransactional> getRoots();
50 void setRoots(AtomicArray<TableIndexPageTransactional> roots);
51 void setStat_read(Long val);
52 void setStat_write(Long val);
53 void setStat_create_page(Long val);
54 void setStat_page_next(Long val);
55 void setStat_page_branch(Long val);
58 protected static final int INITIALPAGEHASH=1024;
59 protected static final int PAGESIZE=2048;
61 private RandomAccessFile out=null;
62 private String filename;
63 private TableIndexPage[] root=null;
64 // private TableIndexPageTransactional[] root=null;
66 private long stat_read=0;
67 private long stat_write=0;
68 protected long stat_create_page=0;
69 protected long stat_page_next=0;
70 protected long stat_page_branch=0;
72 public PagedIndex(String filename) throws IOException{
73 this.filename=filename;
74 File ftest=new File(filename);
75 if(!ftest.exists())ftest.createNewFile();
76 out=new RandomAccessFile(filename,"rw");
77 root=new TableIndexPage[INITIALPAGEHASH];
79 for(int i=0;i<INITIALPAGEHASH;i++){
80 root[i]=new TableIndexPage(this,out);
82 out.seek(root[i].getEndLocation());
85 for(int i=0;i<INITIALPAGEHASH;i++){
86 root[i]=TableIndexPage.createNewPage(this,out,PAGESIZE);
92 public Hashtable<String,Long> readStatistics(){
93 Hashtable<String,Long> hash=new Hashtable<String,Long>();
94 hash.put("stat_index_read",stat_read);
95 hash.put("stat_index_write",stat_write);
96 hash.put("stat_index_create_page",stat_create_page);
97 hash.put("stat_index_page_next",stat_page_next);
98 hash.put("stat_index_page_branch",stat_page_branch);
107 private int rootHash(String id){
108 return id.hashCode() & (INITIALPAGEHASH-1);
111 private synchronized TableIndexPage getFirstFreePage(String id) throws IOException{
112 return root[rootHash(id)].getFirstFreePage(id,id.hashCode());
115 private synchronized long getOffset(String id) throws IOException{
116 if(root==null)return -1;
117 return root[rootHash(id)].getOffset(id,id.hashCode());
120 public synchronized void updateEntry(String id,int rowsize,int location,long position) throws IOException{
121 long offset=getOffset(id);
123 TableIndexEntry entry=new TableIndexEntry(id,rowsize,location,position);
124 entry.updateData(out);
127 public synchronized void addEntry(String id,int rowsize,int location,long position) throws IOException{
128 TableIndexPage page=getFirstFreePage(id);
129 page.addEntry(id,rowsize,location,position);
132 public synchronized TableIndexEntry scanIndex(String id) throws IOException{
133 if(root==null)return null;
134 return root[rootHash(id)].scanIndex(id,id.hashCode());
136 public synchronized List<TableIndexEntry> scanIndex(List<String> rows) throws IOException{
137 List<TableIndexEntry> lst=new ArrayList<TableIndexEntry>();
138 for(int i=0;i<rows.size();i++){
139 String id=rows.get(i);
140 TableIndexEntry entry=scanIndex(id);
142 if(entry.getLocation()!=Table.DELETE)lst.add(entry);
147 public synchronized List<TableIndexEntry> scanIndex() throws IOException{
148 ArrayList<TableIndexEntry> lst=new ArrayList<TableIndexEntry>();
149 for(int i=0;i<INITIALPAGEHASH;i++){
150 root[i].addEntriesToList(lst);
159 }catch(Exception e){}