KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jalisto > se > query > IndexManagerImpl


1 /*
2  * Jalisto - JAva LIght STOrage
3  * Copyright (C) 2000-2005 Xcalia http://www.xcalia.com
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Xcalia
20  * 71, rue Desnouettes
21  * 75014 Paris - France
22  * http://www.xcalia.com
23  */

24 package org.objectweb.jalisto.se.query;
25
26 import org.objectweb.jalisto.se.api.ClassDescription;
27 import org.objectweb.jalisto.se.impl.LogicalOid;
28 import org.objectweb.jalisto.se.impl.InFileAddress;
29 import org.objectweb.jalisto.se.api.internal.InternalPhysicalFileAccess;
30 import org.objectweb.jalisto.se.api.query.Index;
31 import org.objectweb.jalisto.se.api.internal.SessionInternal;
32 import org.objectweb.jalisto.se.api.internal.LogicalSystemPageAccess;
33 import org.objectweb.jalisto.se.api.query.IndexManager;
34 import org.objectweb.jalisto.se.query.exception.QueryEngineException;
35 import org.objectweb.jalisto.se.impl.meta.ClassDescriptionImpl;
36 import org.objectweb.jalisto.se.impl.meta.IndexDescription;
37 import org.objectweb.jalisto.se.impl.server.page.Page;
38 import org.objectweb.jalisto.se.query.btree.BTree;
39 import org.objectweb.jalisto.se.query.btree.BTreeNode;
40 import org.objectweb.jalisto.se.query.btree.OidCollection;
41 import org.objectweb.jalisto.se.query.index.IndexBTreeImpl;
42 import org.objectweb.jalisto.se.query.index.IndexHashMapImpl;
43
44 import java.util.*;
45
46 public class IndexManagerImpl implements IndexManager {
47
48     private IndexManagerImpl(SessionInternal session) {
49         this.session = session;
50         this.sessionId = session.getSessionId();
51         this.logical = session.getFileAccess();
52         this.physical = logical.getPhysicalAccess();
53         this.indexes = new HashMap();
54         this.indexesIfaList = new LinkedList();
55         this.counter = 0;
56     }
57
58     public Index getIndex(ClassDescription meta, int fieldIndex) {
59         if (!session.currentTransaction().isActive()) {
60             throw new QueryEngineException("session must be active to call resolveLeafOnIndex method");
61         }
62         InFileAddress ifa = ((ClassDescriptionImpl) meta).getIndexIfa(fieldIndex);
63         if (ifa == null) {
64             throw new QueryEngineException("no index for this field");
65         }
66         Index index = (Index) indexes.get(ifa);
67         if (index == null) {
68             return loadIndex(ifa);
69         }
70         return index;
71     }
72
73     public Index getIndex(InFileAddress ifa) {
74         if (!session.currentTransaction().isActive()) {
75             throw new QueryEngineException("session must be active to call resolveLeafOnIndex method");
76         }
77         if (ifa == null) {
78             throw new QueryEngineException("no index for this field");
79         }
80         Index index = (Index) indexes.get(ifa);
81         if (index == null) {
82             return loadIndex(ifa);
83         }
84         return index;
85     }
86
87     public Index buildIndexOnField(ClassDescription meta, int fieldIndex) {
88         if (!session.currentTransaction().isActive()) {
89             throw new QueryEngineException("session must be active to call buildIndexOnField method");
90         }
91         ClassDescriptionImpl metaImpl = (ClassDescriptionImpl) meta;
92         InFileAddress ifa = metaImpl.getIndexIfa(fieldIndex);
93         if (ifa != null) {
94             return getIndex(metaImpl, fieldIndex);
95         }
96         ifa = new InFileAddress(IFA_PREFIXE + counter);
97         counter++;
98         indexesIfaList.add(ifa);
99         updateStateInBase(true);
100         metaImpl.setIndexIfa(fieldIndex, ifa);
101         metaImpl.updateInBase();
102
103         Index index;
104         if (metaImpl.getIndexType(fieldIndex) == IndexHashMapImpl.TYPE) {
105             index = new IndexHashMapImpl(ifa, fieldIndex, metaImpl);
106         } else { // default
107
index = new IndexBTreeImpl(ifa, fieldIndex, metaImpl, this);
108         }
109         physical.writeObjectInBase(ifa, index, false);
110         indexes.put(ifa, index);
111
112         Iterator extent = session.getExtent(metaImpl.getClassName()).readFully().iterator();
113         while (extent.hasNext()) {
114             Object JavaDoc oid = extent.next();
115             Object JavaDoc[] o = session.readObjectByOid(oid, true);
116             index.put(o[fieldIndex], (LogicalOid) oid);
117         }
118
119         return index;
120     }
121
122     public void updateIndexInBase(Index index) {
123         physical.writeObjectInBase(index.getIfa(), index, true);
124     }
125
126     public void deleteIndexOnField(ClassDescription meta, int fieldIndex) {
127         if (!session.currentTransaction().isActive()) {
128             throw new QueryEngineException("session must be active to call deleteIndexOnField method");
129         }
130         ClassDescriptionImpl metaImpl = (ClassDescriptionImpl) meta;
131         InFileAddress ifa = metaImpl.getIndexIfa(fieldIndex);
132         if (ifa != null) {
133             Index index = getIndex(metaImpl, fieldIndex);
134             InFileAddress indexIfa = index.getIfa();
135             index.deleteIndex();
136             indexes.remove(indexIfa);
137             metaImpl.setIndexIfa(fieldIndex, null);
138             metaImpl.updateInBase();
139 // session.getMetaRepository().updateStateInBase(true);
140
physical.deleteFileObject(ifa);
141         }
142     }
143
144     public void deleteIndexesOnClass(ClassDescription meta) {
145         Iterator descriptions = meta.getIndexedFieldDescription();
146         while (descriptions.hasNext()) {
147             IndexDescription indexDescription = (IndexDescription) descriptions.next();
148             deleteIndexOnField(meta, indexDescription.getFieldDescription().getIndex());
149         }
150     }
151
152     /**
153      * ************************ insert/update/remove datas **********************************
154      */

155
156     public void createObject(ClassDescription meta, LogicalOid floid, Object JavaDoc[] values) {
157         Iterator descriptions = meta.getIndexedFieldDescription();
158         while (descriptions.hasNext()) {
159             IndexDescription indexDescription = (IndexDescription) descriptions.next();
160             InFileAddress ifa = indexDescription.getValueIndexIfa();
161             getIndex(ifa).put(values[indexDescription.getFieldDescription().getIndex()], floid);
162         }
163     }
164
165     public void removeObject(ClassDescription meta, LogicalOid floid, Object JavaDoc[] values) {
166         Iterator descriptions = meta.getIndexedFieldDescription();
167         while (descriptions.hasNext()) {
168             IndexDescription indexDescription = (IndexDescription) descriptions.next();
169             InFileAddress ifa = indexDescription.getValueIndexIfa();
170             getIndex(ifa).remove(values[indexDescription.getFieldDescription().getIndex()], floid);
171         }
172     }
173
174     public void updateObject(ClassDescription meta, LogicalOid floid, Object JavaDoc[] oldValues, Object JavaDoc[] newValues) {
175         Iterator descriptions = meta.getIndexedFieldDescription();
176         while (descriptions.hasNext()) {
177             IndexDescription indexDescription = (IndexDescription) descriptions.next();
178             int index = indexDescription.getFieldDescription().getIndex();
179             if (!oldValues[index].equals(newValues[index])) {
180                 getIndex(meta, index).remove(oldValues[index], floid);
181                 getIndex(meta, index).put(oldValues[index], floid);
182             }
183         }
184     }
185
186     /**
187      * ************************ read/write for btrees **************************************
188      */

189
190     public OidCollection readOidsInBase(BTree tree, InFileAddress ifa) {
191         OidCollection oids = (OidCollection) tree.getLoadedElements().get(ifa);
192         if (oids == null) {
193             oids = (OidCollection) logical.readLeaf(sessionId, ifa);
194             oids.setIfa(ifa);
195             tree.getLoadedElements().put(ifa, oids);
196         }
197         return oids;
198     }
199
200     public InFileAddress getNewOidsCollIfaAndInsert(BTree tree, OidCollection oids) {
201         InFileAddress leafIfa = logical.allocateLeafAddressAndInsert(
202                 sessionId, tree.getFieldDescription(), oids);
203         tree.getLoadedElements().put(leafIfa, oids);
204         return leafIfa;
205     }
206
207     public void updateLeaf(OidCollection oids) {
208         logical.updateLeaf(sessionId, oids.getIfa(), oids);
209     }
210
211     public void removeLeaf(BTree tree, InFileAddress ifa) {
212         logical.removeLeaf(sessionId, ifa);
213         tree.getLoadedElements().remove(ifa);
214     }
215
216     public BTreeNode readNodeInBase(BTree tree, InFileAddress ifa) {
217         BTreeNode node = (BTreeNode) tree.getLoadedElements().get(ifa);
218         if (node == null) {
219             node = (BTreeNode) logical.readNode(sessionId, ifa);
220             node.setTree(tree);
221             node.setIfa(ifa);
222             tree.getLoadedElements().put(ifa, node);
223         }
224         return node;
225     }
226
227     public InFileAddress getNewNodeIfaAndInsert(BTree tree, BTreeNode node) {
228         InFileAddress nodeIfa = logical.allocateNodeAddressAndInsert(sessionId, tree.getFieldDescription(), node);
229         tree.getLoadedElements().put(nodeIfa, node);
230         return nodeIfa;
231     }
232
233     public void updateNode(BTreeNode node) {
234         logical.updateNode(sessionId, node.getIfa(), node);
235     }
236
237     public void removeNode(BTree tree, InFileAddress ifa) {
238         logical.removeNode(sessionId, ifa);
239         tree.getLoadedElements().remove(ifa);
240     }
241
242     public Page getPageForIfa(InFileAddress ifa) {
243         return (Page) physical.readFileObjectAt(ifa);
244     }
245
246     /**
247      * ************************** PRIVATE *****************************************
248      */

249
250     private Index loadIndex(InFileAddress ifa) {
251         Index index = (Index) physical.readFileObjectAt(ifa).getData();
252         index.setIndexManager(this);
253         indexes.put(ifa, index);
254         return index;
255     }
256
257     private void readStateFromBase() {
258         Object JavaDoc[] o = (Object JavaDoc[]) physical.readFileObjectAt(INDEX_MANAGER_STATE_IFA).getData();
259         this.counter = ((Integer JavaDoc) o[0]).intValue();
260         this.nodeCounter = ((Integer JavaDoc) o[1]).intValue();
261         this.oidsCounter = ((Integer JavaDoc) o[2]).intValue();
262         this.indexesIfaList = (List) o[3];
263     }
264
265     private void updateStateInBase(boolean isUpdate) {
266         Object JavaDoc[] datas = new Object JavaDoc[4];
267         datas[0] = new Integer JavaDoc(counter);
268         datas[1] = new Integer JavaDoc(nodeCounter);
269         datas[2] = new Integer JavaDoc(oidsCounter);
270         datas[3] = indexesIfaList;
271         physical.writeObjectInBase(INDEX_MANAGER_STATE_IFA, datas, isUpdate);
272     }
273
274
275     private HashMap indexes;
276     private SessionInternal session;
277     private Object JavaDoc sessionId;
278     private InternalPhysicalFileAccess physical;
279     private LogicalSystemPageAccess logical;
280     private List indexesIfaList;
281     private int counter;
282     private int nodeCounter;
283     private int oidsCounter;
284
285
286     /**
287      * ************************************ STATIC *********************************************
288      */

289
290     public static IndexManager getAnIndexManagerImpl(SessionInternal session) {
291         IndexManagerImpl indexManager = new IndexManagerImpl(session);
292         try {
293             indexManager.readStateFromBase();
294         } catch (Exception JavaDoc e) {
295             indexManager.indexesIfaList = new LinkedList();
296             indexManager.counter = 0;
297             indexManager.updateStateInBase(false);
298         }
299         return indexManager;
300     }
301
302     protected static final String JavaDoc IFA_PREFIXE = "ind";
303     protected static final InFileAddress INDEX_MANAGER_STATE_IFA = new InFileAddress("lstidx");
304 }
305
Popular Tags