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