KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > index > ViewIndex


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.index;
6
7 import java.sql.SQLException JavaDoc;
8
9 import org.h2.command.dml.Query;
10 import org.h2.engine.Constants;
11 import org.h2.engine.Session;
12 import org.h2.expression.Comparison;
13 import org.h2.expression.Parameter;
14 import org.h2.expression.ValueExpression;
15 import org.h2.message.Message;
16 import org.h2.result.LocalResult;
17 import org.h2.result.Row;
18 import org.h2.result.SearchRow;
19 import org.h2.table.Column;
20 import org.h2.table.TableView;
21 import org.h2.util.IntArray;
22 import org.h2.util.SmallLRUCache;
23 import org.h2.util.ObjectArray;
24 import org.h2.value.Value;
25
26 public class ViewIndex extends Index {
27
28     private String JavaDoc querySQL;
29     private ObjectArray originalParameters;
30     private Parameter[] params;
31     
32     private SmallLRUCache costCache = new SmallLRUCache(Constants.VIEW_COST_CACHE_SIZE);
33     
34     private Value[] lastParameters;
35     private long lastEvaluated;
36     private LocalResult lastResult;
37     
38     public ViewIndex(TableView view, String JavaDoc querySQL, ObjectArray originalParameters) {
39         super(view, 0, null, null, IndexType.createNonUnique(false));
40         this.querySQL = querySQL;
41         this.originalParameters = originalParameters;
42     }
43     
44     public String JavaDoc getPlanSQL() {
45         return querySQL;
46     }
47
48     public void close(Session session) throws SQLException JavaDoc {
49     }
50
51     public void add(Session session, Row row) throws SQLException JavaDoc {
52         throw Message.getUnsupportedException();
53     }
54
55     public void remove(Session session, Row row) throws SQLException JavaDoc {
56         throw Message.getUnsupportedException();
57     }
58
59     private int getComparisonType(int mask) {
60         if((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
61             return Comparison.EQUAL;
62         } else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
63             // TODO view: how to do range queries?
64
return Comparison.BIGGER_EQUAL;
65         } else if ((mask & IndexCondition.START) == IndexCondition.START) {
66             return Comparison.BIGGER_EQUAL;
67         } else if ((mask & IndexCondition.END) == IndexCondition.END) {
68             return Comparison.SMALLER_EQUAL;
69         }
70         throw Message.getInternalError("unsupported mask "+mask);
71     }
72     
73     private static class CostElement {
74         long evaluatedAt;
75         double cost;
76     }
77     
78     public double getCost(Session session, int[] masks) throws SQLException JavaDoc {
79         IntArray masksArray = new IntArray(masks == null ? new int[0] : masks);
80         CostElement cachedCost = (CostElement) costCache.get(masksArray);
81         if(cachedCost != null) {
82             long time = System.currentTimeMillis();
83             if(time < cachedCost.evaluatedAt + Constants.VIEW_COST_CACHE_MAX_AGE) {
84                 return cachedCost.cost;
85             }
86         }
87         Query query = (Query)session.prepare(querySQL, true);
88         IntArray paramIndex = new IntArray();
89         if(masks == null) {
90             columns = new Column[0];
91             params = new Parameter[0];
92         } else {
93             for(int i=0; i<masks.length; i++) {
94                 int mask = masks[i];
95                 if(mask == 0) {
96                     continue;
97                 }
98                 paramIndex.add(i);
99             }
100             int len = paramIndex.size();
101             columns = new Column[len];
102             params = new Parameter[len];
103             for(int i=0; i<len; i++) {
104                 int idx = paramIndex.get(i);
105                 Column col = table.getColumn(idx);
106                 columns[i] = col;
107                 Parameter param = new Parameter(0);
108                 params[i] = param;
109                 int mask = masks[idx];
110                 int comparisonType = getComparisonType(mask);
111                 query.addGlobalCondition(param, idx, comparisonType);
112             }
113             String JavaDoc sql = query.getSQL();
114             query = (Query)session.prepare(sql);
115         }
116         double cost = query.getCost();
117         cachedCost = new CostElement();
118         cachedCost.evaluatedAt = System.currentTimeMillis();
119         cachedCost.cost = cost;
120         costCache.put(masksArray, cachedCost);
121         return cost;
122     }
123
124     public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException JavaDoc {
125         Query query = (Query)session.prepare(querySQL, true);
126         ObjectArray paramList = query.getParameters();
127         for(int i=0; first != null && i<first.getColumnCount(); i++) {
128             Value v = first.getValue(i);
129             if(v != null) {
130                 query.addGlobalCondition(ValueExpression.get(v), i, Comparison.BIGGER_EQUAL);
131             }
132         }
133         for(int i=0; last != null && i<last.getColumnCount(); i++) {
134             Value v = last.getValue(i);
135             if(v != null) {
136                 query.addGlobalCondition(ValueExpression.get(v), i, Comparison.SMALLER_EQUAL);
137             }
138         }
139         for(int i=0; originalParameters != null && i<originalParameters.size(); i++) {
140             Parameter orig = (Parameter) originalParameters.get(i);
141             Parameter param = (Parameter) paramList.get(i);
142             Value value = orig.getValue(session);
143             param.setValue(value);
144         }
145         boolean canReuse = first == null && last == null;
146         long now = session.getDatabase().getModificationDataId();
147         Value[] params = query.getParameterValues();
148         if(session.getDatabase().getOptimizeReuseResults()) {
149             if(lastResult != null && canReuse) {
150                 if(query.sameResultAsLast(session, params, lastParameters, lastEvaluated)) {
151                     lastResult = lastResult.createShallowCopy(session);
152                     lastResult.reset();
153                     return new ViewCursor(table, lastResult);
154                 }
155             }
156         }
157         query.setSession(session);
158         LocalResult result = query.query(0);
159         if(canReuse) {
160             lastResult = result;
161             lastParameters = params;
162             lastEvaluated = now;
163         }
164         return new ViewCursor(table, result);
165     }
166     
167     public int getCost(int[] masks) throws SQLException JavaDoc {
168         if(masks != null) {
169             throw Message.getUnsupportedException();
170         }
171         return Integer.MAX_VALUE;
172     }
173
174     public void remove(Session session) throws SQLException JavaDoc {
175         throw Message.getUnsupportedException();
176     }
177
178     public void truncate(Session session) throws SQLException JavaDoc {
179         throw Message.getUnsupportedException();
180     }
181
182     public void checkRename() throws SQLException JavaDoc {
183         throw Message.getUnsupportedException();
184     }
185
186     public boolean needRebuild() {
187         return false;
188     }
189     
190     public boolean canGetFirstOrLast(boolean first) {
191         return false;
192     }
193
194     public Value findFirstOrLast(Session session, boolean first) throws SQLException JavaDoc {
195         throw Message.getUnsupportedException();
196     }
197
198 }
199
Popular Tags