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