KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > smallsql > database > IndexScrollStatus


1 /* =============================================================
2  * SmallSQL : a free Java DBMS library for the Java(tm) platform
3  * =============================================================
4  *
5  * (C) Copyright 2004-2006, by Volker Berlin.
6  *
7  * Project Info: http://www.smallsql.de/
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ---------------
28  * IndexScrollStatus.java
29  * ---------------
30  * Author: Volker Berlin
31  *
32  * Created on 18.04.2005
33  */

34 package smallsql.database;
35
36 /**
37  * This class save the status of the scrolling through a Index. This is like a Cursor.
38  */

39 class IndexScrollStatus {
40     private final IndexNode rootPage;
41     private final Expressions expressions; // is used for the description of ASC and DESC
42

43     private final java.util.Stack JavaDoc nodeStack = new java.util.Stack JavaDoc(); //TODO performance Stack durch nicht synchronisierte Klasse ersetzten
44
/** Used for getRowOffset() as context cash between 2 calls */
45     private LongTreeList longList;
46     private LongTreeListEnum longListEnum = new LongTreeListEnum();
47
48
49     IndexScrollStatus(IndexNode rootPage, Expressions expressions){
50         this.rootPage = rootPage;
51         this.expressions= expressions;
52         reset();
53     }
54     
55     
56     /**
57      * Reset this index to start a new scan of it with nextRowoffset()
58      */

59     final void reset(){
60         nodeStack.clear();
61         boolean asc = (expressions.get(0).getAlias() != SQLTokenizer.DESC_STR);
62         nodeStack.push( new IndexNodeScrollStatus(rootPage, asc, true, 0) );
63     }
64
65     
66     /**
67      * Return the next rowOffset of this index. You need to call reset() before the first use.
68      * @param next if true the next rowOffset else the previous rowOffset
69      */

70     final long getRowOffset( boolean scroll){
71         if(longList != null){
72             long rowOffset = scroll ?
73                                 longList.getNext(longListEnum) :
74                                 longList.getPrevious(longListEnum);
75             if(rowOffset < 0){
76                 // No more enties on this node
77
longList = null;
78             }else{
79                 return rowOffset;
80             }
81         }
82         while(true){
83             IndexNodeScrollStatus status = (IndexNodeScrollStatus)nodeStack.peek();
84             int level = status.level;
85             if(!status.asc ^ scroll){
86                 //ASC order
87
int idx = ++status.idx;
88                 if(idx == -1){
89                     if(status.nodeValue != null){
90                         if(status.nodeValue instanceof IndexNode){
91                             level++;
92                             nodeStack.push(
93                                 new IndexNodeScrollStatus( (IndexNode)status.nodeValue,
94                                                         (expressions.get(level).getAlias() != SQLTokenizer.DESC_STR),
95                                                         scroll, level));
96                             continue;
97                         }else
98                             return getReturnValue(status.nodeValue);
99                     }
100                     //There is no RowOffset in this node
101
idx = ++status.idx;
102                 }
103                 if(idx >= status.nodes.length){
104                     //No more nodes in this level
105
if(nodeStack.size() > 1){
106                         nodeStack.pop();
107                         continue;
108                     }else{
109                         //No more RowOffsets in this Index
110
return -1;
111                     }
112                 }
113                 IndexNode node = status.nodes[idx];
114                 nodeStack.push( new IndexNodeScrollStatus(node, status.asc, scroll, level) );
115             }else{
116                 //DESC order
117
int idx = --status.idx;
118                 if(idx == -1){
119                     if(status.nodeValue != null){
120                         if(status.nodeValue instanceof IndexNode){
121                             level++;
122                             nodeStack.push(
123                                 new IndexNodeScrollStatus( (IndexNode)status.nodeValue,
124                                                         (expressions.get(level).getAlias() != SQLTokenizer.DESC_STR),
125                                                         scroll, level));
126                             continue;
127                         }else
128                             return getReturnValue(status.nodeValue);
129                     }
130                     //There is no RowOffset in this node
131
}
132                 if(idx < 0){
133                     //No more nodes in this level
134
if(nodeStack.size() > 1){
135                         nodeStack.pop();
136                         continue;
137                     }else{
138                         //No more RowOffsets in this Index
139
return -1;
140                     }
141                 }
142                 IndexNode node = status.nodes[idx];
143                 nodeStack.push( new IndexNodeScrollStatus(node, status.asc, scroll, level) );
144             }
145         }
146     }
147         
148
149     /**
150      * Move the index after the last position. The next call nextRowOffset() returns a -1
151      *
152      */

153     final void afterLast(){
154         longList = null;
155         nodeStack.setSize(1);
156         ((IndexNodeScrollStatus)nodeStack.peek()).afterLast();
157     }
158     
159     
160     private final long getReturnValue( Object JavaDoc value){
161         if(rootPage.getUnique()){
162             return ((Long JavaDoc)value).longValue();
163         }else{
164             longList = (LongTreeList)value;
165             longListEnum.reset();
166             return longList.getNext(longListEnum); // there be should one value as minimum
167
}
168         
169     }
170     
171     
172         
173
174 }
175
Popular Tags