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 java.io.IOException;
00032 import java.lang.reflect.AccessibleObject;
00033
00034 import org.openmobileis.common.util.collection.LongArray;
00035 import org.openmobileis.database.fastobjectdb.FODBIndexDescriptor;
00036 import org.openmobileis.database.fastobjectdb.FODBLongIndexDescriptor;
00037 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00038 import org.openmobileis.database.fastobjectdb.db.index.node.LongNode;
00039 import org.openmobileis.database.fastobjectdb.db.index.node.Node;
00040 import org.openmobileis.database.fastobjectdb.db.index.node.StringNode;
00041 import org.openmobileis.database.fastobjectdb.db.query.soda.SodaStringIndexComparator;
00042 import org.openmobileis.database.fastobjectdb.db.store.FODBCollectionIndexFile;
00043
00046 public class FODBMultipleLongIndex extends FODBLongIndex implements FODBMultipleIndex {
00047 private int incTabSize;
00048
00049 public FODBMultipleLongIndex(FODBIndexHeader newHeader, FODBCollectionIndexFile cFile, AccessibleObject accObj) throws FODBException {
00050 super(newHeader, cFile, accObj);
00051 }
00052
00053 public FODBMultipleLongIndex(FODBLongIndexDescriptor descriptor, FODBCollectionIndexFile cFile, AccessibleObject accObj) throws FODBException {
00054 super(descriptor, cFile, accObj);
00055 incTabSize = descriptor.getIncTabSize();
00056 }
00057
00058 protected void specificHeaderInit(FODBIndexDescriptor descriptor) throws FODBException {
00059 super.specificHeaderInit(descriptor);
00060 FODBLongIndexDescriptor desc = (FODBLongIndexDescriptor) descriptor;
00061 header.incTabSize = desc.getIncTabSize();
00062 }
00063
00064
00065
00066
00067 public int getType() {
00068 return FODBIndex.MULTIPLE;
00069 }
00070
00074 protected void writeKeyPtr(Node pg, int pos, long newptr) throws IOException, ClassNotFoundException {
00075 long arrayPtr = pg.ptr[pos];
00076 long[] ptrList = (long[])colFile.readLongPtr(arrayPtr);
00077 int size = ptrList.length;
00078
00079
00080 int i = 0;
00081 for (i=0; i<size; i++) {
00082 if (ptrList[i] == Node.NO_NODE) {
00083 break;
00084 }
00085 }
00086 if (i == size) {
00087 long[] newptrlist = new long[size+header.incTabSize];
00088 System.arraycopy(ptrList, 0, newptrlist, 0, ptrList.length);
00089 newptrlist[size] = newptr;
00090 for (i=size+1; i<newptrlist.length; i++) {
00091 newptrlist[i] = Node.NO_NODE;
00092 }
00093 colFile.deleteLongPtr(arrayPtr);
00094 long modified = colFile.writeLongPtr(newptrlist);
00095 pg.ptr[pos] = modified;
00096 colFile.rewriteNode(pg, pg.filePtr);
00097 return;
00098 } else {
00099 ptrList[i] = newptr;
00100 colFile.rewriteLongPtr(ptrList, arrayPtr);
00101 return;
00102 }
00103
00104 }
00105
00106 protected long createPtrArray(long ptr) throws IOException, ClassNotFoundException {
00107 long[] newptrlist = new long[header.incTabSize];
00108 newptrlist[0] = ptr;
00109 for (int i=1; i<newptrlist.length; i++) {
00110 newptrlist[i] = Node.NO_NODE;
00111 }
00112 return colFile.writeLongPtr(newptrlist);
00113 }
00114
00115 protected void addSearchResult(LongNode pg, int pos, LongArray array) throws IOException, ClassNotFoundException {
00116 long[] ptrList = this.readPtrAtPos(pg, pos);
00117 array.add(ptrList);
00118 }
00119
00120 protected void addSearchResult(StringNode node, int pos, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00121 if (comparator.isDistinct()) {
00122 long[] ptrList = this.readPtrAtPos(node, pos);
00123 array.add(ptrList[0]);
00124 } else {
00125 long[] ptrList = this.readPtrAtPos(node, pos);
00126 array.add(ptrList);
00127 }
00128
00129 }
00130
00131 private long[] readPtrAtPos(Node pg, int pos) throws IOException, ClassNotFoundException {
00132 long arrayPtr = pg.ptr[pos];
00133
00134 long[] arrayList = (long[])colFile.readLongPtr(arrayPtr);
00135
00136 int i = 0;
00137 for (i=0; i<arrayList.length; i++) {
00138 if (arrayList[i] == Node.NO_NODE) {
00139 break;
00140 }
00141 }
00142 if (i==arrayList.length) {
00143 return arrayList;
00144 }
00145 long[] newArrayList = new long[i];
00146 System.arraycopy(arrayList, 0, newArrayList, 0, newArrayList.length);
00147 return newArrayList;
00148 }
00149
00154 protected boolean removeKeyPtr(Node pg, int pos, long pointer) throws IOException, ClassNotFoundException {
00155 long arrayPtr = pg.ptr[pos];
00156 long[] ptrList = (long[])colFile.readLongPtr(arrayPtr);
00157
00158
00159 int i=0;
00160 int size = ptrList.length;
00161 for (i=0; i<size; i++) {
00162 if (ptrList[i] == pointer) {
00163 ptrList[i] = Node.NO_NODE;
00164 break;
00165 }
00166 }
00167 if (i == size) {
00168 throw new IOException("Pointer not found !!!");
00169 }
00170 int nbnull = 1;
00171 for (int j=i+1; j<size ; j++) {
00172 if (ptrList[j] == Node.NO_NODE) {
00173 nbnull++;
00174 } else {
00175 ptrList[j-1] = ptrList[j];
00176 ptrList[j] = Node.NO_NODE;
00177 }
00178 }
00179 if (nbnull == header.incTabSize) {
00180 if (size > header.incTabSize) {
00181 long[] newptrlist = new long[size - header.incTabSize];
00182 System.arraycopy(ptrList, 0, newptrlist, 0, newptrlist.length);
00183 colFile.deleteLongPtr(arrayPtr);
00184 pg.ptr[pos] = colFile.writeLongPtr(newptrlist);
00185
00186 colFile.rewriteNode(pg, pg.filePtr);
00187 return false;
00188 } else {
00189 colFile.deleteLongPtr(arrayPtr);
00190 return true;
00191 }
00192 }
00193
00194 colFile.rewriteLongPtr(ptrList, arrayPtr);
00195 return false;
00196 }
00197
00198 public FODBIndexDescriptor getIndexDescriptor() {
00199 return new FODBLongIndexDescriptor(this.header.getName(), FODBIndexDescriptor.MULTIPLE, this.header.getMemberName(), this.header.order, this.header.incTabSize);
00200 }
00201 }