23a251055a65f6195d236c26da25add0b5eec644
[IRC.git] /
1 /*
2  * Copyright (c) 2007, Solido Systems
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
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.
14  *
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.
18  *
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.
30  */
31  
32 /*package com.solidosystems.tuplesoup.core;
33
34 import TransactionalIO.core.TransactionalFile;
35 import dstm2.AtomicSuperClass;
36 import dstm2.atomic;
37 import java.io.*;
38 import java.util.*;
39
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;
45     
46     public @atomic interface TableIndexPageTSInf{
47         Long getLocation();
48         Integer getSize();
49         Long getNext();
50         Long getLower();
51         Integer getOffset();
52         Integer getStarthash();
53         Integer getEndhash();
54         Boolean getFirst();
55         TableIndexPageTSInf getNextpage();
56         TableIndexPageTSInf getLowerpage();
57         
58      
59         void setLowerpage(TableIndexPageTSInf lowerpage);   
60         void setNextpage(TableIndexPageTSInf nextpage);
61         void setFirst(Boolean val);
62         void setEndhash();
63         void setStarthash();
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);
69     }
70   
71     
72     private long location=-1;
73     private int size=-1;
74     private long next=-1;
75     private long lower=-1;
76     private int offset=0;
77     
78     private int starthash=-1;
79     private int endhash=-1;
80     private boolean first=false;
81     
82     private TableIndexPage nextpage=null;
83     private TableIndexPage lowerpage=null;
84     
85     private PagedIndex index=null;
86     
87     public TableIndexPageTransactional(PagedIndex index,TransactionalFile file) throws IOException{
88         this.file=file;
89         this.index=index;
90         first=false;
91         location=file.getFilePointer();
92         size=file.readInt();
93         next=file.readLong();
94         lower=file.readLong();
95         offset=file.readInt();
96         endhash=file.readInt();
97         if(offset>0)starthash=file.readInt();
98     }
99     
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);
103         file.seek(pre);
104         file.writeInt(size);
105         file.writeLong(-1l);
106         file.writeLong(-1l);
107         file.writeInt(0);
108         file.writeInt(-1);
109         file.seek(pre);
110         index.stat_create_page++;
111         return new TableIndexPage(index,file);
112     }
113     
114     public void setFirst(){
115         first=true;
116     }
117     
118     public long getLocation(){
119         return location;
120     }
121     public long getEndLocation(){
122         return location+size+BASEOFFSET;
123     }
124     
125     public String toString(){
126         StringBuffer buf=new StringBuffer();
127         buf.append("{\n");
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");
135         buf.append("}\n");
136         return buf.toString();
137     }
138     
139     private void updateMeta() throws IOException{
140         file.seek(location);
141         file.writeInt(size);
142         file.writeLong(next);
143         file.writeLong(lower);
144         file.writeInt(offset);
145         file.writeInt(endhash);
146     }
147     
148     public void addEntriesToList(List<TableIndexEntry> lst) throws IOException{
149         if(lower>-1){
150             if(lowerpage==null){
151                 file.seek(lower);
152                 lowerpage=new TableIndexPage(index,file);
153             }
154             lowerpage.addEntriesToList(lst);
155         }
156         if(next>-1){
157             if(nextpage==null){
158                 file.seek(next);
159                 nextpage=new TableIndexPage(index,file);
160             }
161             nextpage.addEntriesToList(lst);
162         }
163         file.seek(location+BASEOFFSET);
164         long pre=file.getFilePointer();
165         while(file.getFilePointer()<pre+offset){
166             TableIndexEntry entry=TableIndexEntry.readData(file);
167             if(entry!=null){
168                 if(entry.getLocation()!=Table.DELETE)lst.add(entry);
169             }
170         }
171     }
172     
173     public TableIndexEntry scanIndex(String id,int hashcode) throws IOException{
174         if(!first){
175             if(hashcode<starthash){
176                 if(lower==-1)return null;
177                 if(lowerpage==null){
178                     file.seek(lower);
179                     lowerpage=new TableIndexPage(index,file);
180                 }
181                 index.stat_page_branch++;
182                 return lowerpage.scanIndex(id,hashcode);
183             }
184         }
185         if(hashcode>endhash){
186             if(next==-1)return null;
187             if(nextpage==null){
188                 file.seek(next);
189                 nextpage=new TableIndexPage(index,file);
190             }
191             index.stat_page_next++;
192             return nextpage.scanIndex(id,hashcode);
193         }
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;
199         }
200         if(next==-1)return null;
201         if(nextpage==null){
202             file.seek(next);
203             nextpage=new TableIndexPage(index,file);
204         }
205         index.stat_page_next++;
206         return nextpage.scanIndex(id,hashcode);
207     }
208     protected long getOffset(String id,int hashcode) throws IOException{
209         if(!first){
210             if(hashcode<starthash){
211                 if(lower==-1)return -1;
212                 if(lowerpage==null){
213                     file.seek(lower);
214                     lowerpage=new TableIndexPage(index,file);
215                 }
216                 index.stat_page_branch++;
217                 return lowerpage.getOffset(id,hashcode);
218             }
219         }
220         if(hashcode>endhash){
221             if(next==-1)return -1;
222             if(nextpage==null){
223                 file.seek(next);
224                 nextpage=new TableIndexPage(index,file);
225             }
226             index.stat_page_next++;
227             return nextpage.getOffset(id,hashcode);
228         }
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;
235         }
236         if(next==-1)return -1;
237         if(nextpage==null){
238             file.seek(next);
239             nextpage=new TableIndexPage(index,file);
240         }
241         index.stat_page_next++;
242         return nextpage.getOffset(id,hashcode);
243     }
244     
245     protected TableIndexPage getFirstFreePage(String id,int hashcode) throws IOException{
246         // Is this an empty page?
247         if(offset==0){
248             return this;
249         }
250         // Is this hash lower than the starthash
251         if(!first){
252             if(hashcode<starthash){
253                 if(lower==-1){
254                     lower=file.length();
255                     updateMeta();
256                     return createNewPage(index,file,PagedIndex.PAGESIZE);
257                 }
258                 if(lowerpage==null){
259                     file.seek(lower);
260                     lowerpage=new TableIndexPage(index,file);
261                 }
262                 index.stat_page_branch++;
263                 return lowerpage.getFirstFreePage(id,hashcode);
264             }
265         }
266         // Do we have space in this page
267         if(size-offset>id.length()*2+4+4+8+1+2)return this;
268         // Check next
269         if(next==-1){
270             next=file.length();
271             updateMeta();
272             return createNewPage(index,file,PagedIndex.PAGESIZE);
273         }
274         if(nextpage==null){
275             file.seek(next);
276             nextpage=new TableIndexPage(index,file);
277         }
278         index.stat_page_next++;
279         return nextpage.getFirstFreePage(id,hashcode);
280     }
281     
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();
289         updateMeta();
290     }
291 }*/