1 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 { 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 oid = extent.next(); 115 Object [] 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 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 155 156 public void createObject(ClassDescription meta, LogicalOid floid, Object [] 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 [] 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 [] oldValues, Object [] 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 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 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 [] o = (Object []) physical.readFileObjectAt(INDEX_MANAGER_STATE_IFA).getData(); 259 this.counter = ((Integer ) o[0]).intValue(); 260 this.nodeCounter = ((Integer ) o[1]).intValue(); 261 this.oidsCounter = ((Integer ) o[2]).intValue(); 262 this.indexesIfaList = (List) o[3]; 263 } 264 265 private void updateStateInBase(boolean isUpdate) { 266 Object [] datas = new Object [4]; 267 datas[0] = new Integer (counter); 268 datas[1] = new Integer (nodeCounter); 269 datas[2] = new Integer (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 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 289 290 public static IndexManager getAnIndexManagerImpl(SessionInternal session) { 291 IndexManagerImpl indexManager = new IndexManagerImpl(session); 292 try { 293 indexManager.readStateFromBase(); 294 } catch (Exception 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 IFA_PREFIXE = "ind"; 303 protected static final InFileAddress INDEX_MANAGER_STATE_IFA = new InFileAddress("lstidx"); 304 } 305 | Popular Tags |