00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package org.openmobileis.database.fastobjectdb.db.index;
00030
00031 import org.openmobileis.common.util.collection.Array;
00032 import org.openmobileis.database.fastobjectdb.FODBIndexDescriptor;
00033 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00034 import org.openmobileis.database.fastobjectdb.db.exception.FODBQueryException;
00035 import org.openmobileis.database.fastobjectdb.db.index.node.Node;
00036 import org.openmobileis.database.fastobjectdb.db.query.soda.SodaIndexComparator;
00037 import org.openmobileis.database.fastobjectdb.db.store.FODBCollectionIndexFile;
00038
00039 import java.io.IOException;
00040 import java.lang.reflect.*;
00041
00042
00050 public abstract class FODBIndex {
00051 public static final int UNIQUE = 1;
00052 public static final int MULTIPLE = 2;
00053
00054 protected String name;
00055 protected final AccessibleObject accessObj;
00056 protected FODBCollectionIndexFile colFile;
00057 protected FODBIndexHeader header;
00058 protected int minKey;
00059
00065 public FODBIndex(FODBIndexHeader newHeader, FODBCollectionIndexFile cFile, AccessibleObject accObj) {
00066 header = newHeader;
00067 minKey = (int) Math.ceil((double) header.order / 2D) - 1;
00068 name = header.getName();
00069 colFile = cFile;
00070 accessObj = accObj;
00071 }
00072
00073 public Node readRoot() throws IOException, ClassNotFoundException {
00074 return (Node) colFile.readNode(header.rootPtr);
00075 }
00076
00084 public FODBIndex(FODBIndexDescriptor descriptor, FODBCollectionIndexFile cFile, AccessibleObject accObj) throws FODBException {
00085 name = descriptor.getName();
00086 colFile = cFile;
00087 accessObj = accObj;
00088 try {
00089
00090
00091 specificDescriptorVerifications(descriptor);
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 if (accessObj instanceof Method) {
00104 header = new FODBIndexHeader(name, (((Method) accessObj).getName()).concat("()"));
00105
00106
00107
00108 } else {
00109 header = new FODBIndexHeader(name, ((Field) accessObj).getName());
00110 }
00111
00112 header.type = getType();
00113 header.rootPtr = Node.NO_NODE;
00114
00115 specificHeaderInit(descriptor);
00116
00117
00118
00119 long pos = colFile.writeHeader(header);
00120
00121 header.pos = pos;
00122 colFile.rewriteHeader(header, pos);
00123
00124 colFile.addIndexPointerToTable(pos);
00125
00126
00127 Node root = initRoot(descriptor);
00128
00129
00130 root.filePtr = colFile.writeNode(root, header);
00131
00132
00133 } catch (Throwable ex) {
00134 throw new FODBException(ex);
00135 }
00136 minKey = (int) Math.ceil((double) header.order / 2D) - 1;
00137 }
00138
00139 public String getName() {
00140 return name;
00141 }
00142
00143 public long getPos() {
00144 return header.pos;
00145 }
00146
00151 public boolean isEmpty() throws FODBException {
00152 try {
00153 Node root = colFile.readNode(header.rootPtr);
00154 if (root == null) {
00155 throw new FODBException("Index closed");
00156 }
00157
00158 return (root.nbKey == 0);
00159 } catch (Throwable ex) {
00160 throw new FODBException(ex);
00161 }
00162 }
00163
00173 public void add(Object obj, long pos) throws FODBException {
00174 try {
00175 Class accessObjType=getAccessObjType();
00176 if(accessObjType.getName().startsWith("[")){
00177
00178 Array keys=getArrayKey(obj);
00179 for(int i=0;i<keys.size();i++){
00180 Object key=keys.get(i);
00181 if(key!=null){
00182 insertKey(key,pos);
00183 }
00184 }
00185 }else{
00186
00187 Object key=getKey(obj);
00188 insertKey(key,pos);
00189 }
00190 } catch (Throwable ex) {
00191 throw new FODBException(ex);
00192 }
00193 }
00194
00195 public Class getAccessObjType(){
00196 if(accessObj instanceof Method)
00197 return ((Method)accessObj).getReturnType();
00198 else
00199 return ((Field)accessObj).getType();
00200 }
00201
00202
00211 public boolean delObjectWithKey(Object obj, long pos) throws FODBException {
00212 try {
00213 boolean result=true;
00214 Class accessObjType=getAccessObjType();
00215 if(accessObjType.getName().startsWith("[")){
00216
00217 Array keys=getArrayKey(obj);
00218 for(int i=0;i<keys.size();i++){
00219 Object key=keys.get(i);
00220 if(key!=null){
00221 result=result && deleteKey(key,pos);
00222 }
00223 }
00224 }else{
00225
00226 Object key=getKey(obj);
00227 result=deleteKey(key,pos);
00228 }
00229 return result;
00230 } catch (Throwable ex) {
00231 throw new FODBException(ex);
00232 }
00233 }
00234
00235 public FODBIndexHeader getIndexHeader() {
00236 return this.header;
00237 }
00238
00239 public abstract long[] query(SodaIndexComparator comparator) throws FODBQueryException;
00240 protected abstract void specificDescriptorVerifications(FODBIndexDescriptor descriptor) throws FODBException;
00241 protected abstract Node initRoot(FODBIndexDescriptor descriptor) throws FODBException;
00242 protected abstract void specificHeaderInit(FODBIndexDescriptor descriptor) throws FODBException;
00243 public abstract int getType();
00244
00245 protected abstract void insertKey(Object key, long pos) throws IOException, ClassNotFoundException, FODBException;
00246 protected abstract boolean deleteKey(Object obj, long pos) throws IOException, ClassNotFoundException, FODBException;
00247 public abstract FODBIndexDescriptor getIndexDescriptor();
00248
00249 public abstract Object getKey(Object obj) throws FODBException;
00250 public abstract org.openmobileis.common.util.collection.Array getArrayKey(Object obj) throws FODBException;
00254 public String toString() {
00255 String result = "FODBIndex[" + name + ", ";
00256
00257 if (accessObj instanceof Method) {
00258 result = result.concat((((Method) accessObj).getName()).concat("()"));
00259 } else {
00260 result = result.concat(((Field) accessObj).getName());
00261 }
00262
00263 result =
00264 result.concat(
00265 ", "
00266 + header.getName()
00267 + ", "
00268 + header.getMemberName()
00269 + ", "
00270 + header.type
00271 + ", "
00272 + header.order
00273 + ", "
00274 + header.keyLen
00275 + ", "
00276 + header.pos
00277 + ", "
00278 + header.rootPtr);
00279
00280 result = result.concat("]");
00281
00282 return result;
00283 }
00284
00285 }