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 TransactionalIO.core.TransactionalFile;
35 import dstm2.AtomicSuperClass;
40 public class TableIndexPageTransactional implements AtomicSuperClass{
41 TableIndexPageTSInf atomicfields;
42 private final static int BASEOFFSET=4+8+8+4+4;
43 //private RandomAccessFile file=null;
44 private TransactionalFile file = null;
46 public @atomic interface TableIndexPageTSInf{
52 Integer getStarthash();
55 TableIndexPageTSInf getNextpage();
56 TableIndexPageTSInf getLowerpage();
59 void setLowerpage(TableIndexPageTSInf lowerpage);
60 void setNextpage(TableIndexPageTSInf nextpage);
61 void setFirst(Boolean val);
64 void setOffset(Integer offset);
65 void setNext(Long next);
66 void setSize(Integer size);
67 void setLocation(Long location);
68 void setLower(Long val);
72 private long location=-1;
75 private long lower=-1;
78 private int starthash=-1;
79 private int endhash=-1;
80 private boolean first=false;
82 private TableIndexPage nextpage=null;
83 private TableIndexPage lowerpage=null;
85 private PagedIndex index=null;
87 public TableIndexPageTransactional(PagedIndex index,TransactionalFile file) throws IOException{
91 location=file.getFilePointer();
94 lower=file.readLong();
95 offset=file.readInt();
96 endhash=file.readInt();
97 if(offset>0)starthash=file.readInt();
100 public static TableIndexPage createNewPage(PagedIndex index,RandomAccessFile file,int size) throws IOException{
101 long pre=file.length();
102 file.setLength(file.length()+size+BASEOFFSET);
110 index.stat_create_page++;
111 return new TableIndexPage(index,file);
114 public void setFirst(){
118 public long getLocation(){
121 public long getEndLocation(){
122 return location+size+BASEOFFSET;
125 public String toString(){
126 StringBuffer buf=new StringBuffer();
128 buf.append(" location "+location+"\n");
129 buf.append(" size "+size+"\n");
130 buf.append(" next "+next+"\n");
131 buf.append(" lower "+lower+"\n");
132 buf.append(" offset "+offset+"\n");
133 buf.append(" starthash "+starthash+"\n");
134 buf.append(" endhash "+endhash+"\n");
136 return buf.toString();
139 private void updateMeta() throws IOException{
142 file.writeLong(next);
143 file.writeLong(lower);
144 file.writeInt(offset);
145 file.writeInt(endhash);
148 public void addEntriesToList(List<TableIndexEntry> lst) throws IOException{
152 lowerpage=new TableIndexPage(index,file);
154 lowerpage.addEntriesToList(lst);
159 nextpage=new TableIndexPage(index,file);
161 nextpage.addEntriesToList(lst);
163 file.seek(location+BASEOFFSET);
164 long pre=file.getFilePointer();
165 while(file.getFilePointer()<pre+offset){
166 TableIndexEntry entry=TableIndexEntry.readData(file);
168 if(entry.getLocation()!=Table.DELETE)lst.add(entry);
173 public TableIndexEntry scanIndex(String id,int hashcode) throws IOException{
175 if(hashcode<starthash){
176 if(lower==-1)return null;
179 lowerpage=new TableIndexPage(index,file);
181 index.stat_page_branch++;
182 return lowerpage.scanIndex(id,hashcode);
185 if(hashcode>endhash){
186 if(next==-1)return null;
189 nextpage=new TableIndexPage(index,file);
191 index.stat_page_next++;
192 return nextpage.scanIndex(id,hashcode);
194 file.seek(location+BASEOFFSET);
195 long pre=file.getFilePointer();
196 while(file.getFilePointer()<pre+offset){
197 TableIndexEntry entry=TableIndexEntry.lookForData(id,file);
198 if(entry!=null)return entry;
200 if(next==-1)return null;
203 nextpage=new TableIndexPage(index,file);
205 index.stat_page_next++;
206 return nextpage.scanIndex(id,hashcode);
208 protected long getOffset(String id,int hashcode) throws IOException{
210 if(hashcode<starthash){
211 if(lower==-1)return -1;
214 lowerpage=new TableIndexPage(index,file);
216 index.stat_page_branch++;
217 return lowerpage.getOffset(id,hashcode);
220 if(hashcode>endhash){
221 if(next==-1)return -1;
224 nextpage=new TableIndexPage(index,file);
226 index.stat_page_next++;
227 return nextpage.getOffset(id,hashcode);
229 file.seek(location+BASEOFFSET);
230 long pre=file.getFilePointer();
231 while(file.getFilePointer()<pre+offset){
232 long prescan=file.getFilePointer();
233 TableIndexEntry entry=TableIndexEntry.lookForData(id,file);
234 if(entry!=null)return prescan;
236 if(next==-1)return -1;
239 nextpage=new TableIndexPage(index,file);
241 index.stat_page_next++;
242 return nextpage.getOffset(id,hashcode);
245 protected TableIndexPage getFirstFreePage(String id,int hashcode) throws IOException{
246 // Is this an empty page?
250 // Is this hash lower than the starthash
252 if(hashcode<starthash){
256 return createNewPage(index,file,PagedIndex.PAGESIZE);
260 lowerpage=new TableIndexPage(index,file);
262 index.stat_page_branch++;
263 return lowerpage.getFirstFreePage(id,hashcode);
266 // Do we have space in this page
267 if(size-offset>id.length()*2+4+4+8+1+2)return this;
272 return createNewPage(index,file,PagedIndex.PAGESIZE);
276 nextpage=new TableIndexPage(index,file);
278 index.stat_page_next++;
279 return nextpage.getFirstFreePage(id,hashcode);
282 public void addEntry(String id,int rowsize,int location,long position) throws IOException{
283 if(offset==0)starthash=id.hashCode();
284 file.seek(this.location+BASEOFFSET+offset);
285 TableIndexEntry entry=new TableIndexEntry(id,rowsize,location,position);
286 entry.writeData(file);
287 offset+=entry.getSize();
288 if(id.hashCode()>endhash)endhash=id.hashCode();