Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

FODBStringIndex.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2005 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: openmobileis@e-care.fr
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  *  
00024  *  Modifications :
00025  *  2004 Creation P.Delrieu
00026  *  2004 Modified by Romain Beaugrand
00027  * 
00028  */
00029 package org.openmobileis.database.fastobjectdb.db.index;
00030 
00031 import java.io.IOException;
00032 import java.lang.reflect.*;
00033 
00034 import org.openmobileis.common.util.StringFormater;
00035 import org.openmobileis.common.util.collection.LongArray;
00036 import org.openmobileis.common.util.log.LogManager;
00037 import org.openmobileis.database.fastobjectdb.FODBIndexDescriptor;
00038 import org.openmobileis.database.fastobjectdb.FODBStringIndexDescriptor;
00039 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00040 import org.openmobileis.database.fastobjectdb.db.exception.FODBQueryException;
00041 import org.openmobileis.database.fastobjectdb.db.index.node.StringNode;
00042 import org.openmobileis.database.fastobjectdb.db.index.node.Node;
00043 import org.openmobileis.database.fastobjectdb.db.query.soda.SodaIndexComparator;
00044 import org.openmobileis.database.fastobjectdb.db.query.soda.SodaStringIndexComparator;
00045 import org.openmobileis.database.fastobjectdb.db.store.FODBCollectionIndexFile;
00046 
00049 public abstract class FODBStringIndex extends FODBIndex {
00050   public FODBStringIndex(FODBIndexHeader newHeader, FODBCollectionIndexFile cFile, AccessibleObject accObj) throws FODBException {
00051     super(newHeader, cFile, accObj);
00052   }
00053 
00054   public FODBStringIndex(FODBStringIndexDescriptor descriptor, FODBCollectionIndexFile cFile, AccessibleObject accObj)
00055     throws FODBException {
00056     super(descriptor, cFile, accObj);
00057   }
00058 
00059   protected void specificDescriptorVerifications(FODBIndexDescriptor descriptor) throws FODBException {
00060     if (!(descriptor instanceof FODBStringIndexDescriptor)) {
00061       throw new FODBException("Internal Error");
00062     }
00063 
00064     FODBStringIndexDescriptor desc = (FODBStringIndexDescriptor) descriptor;
00065 
00066     // verify parameters
00067     if (desc.getOrder() < 3)
00068       throw new FODBException("ERROR Bad BTree order. BTree order must be more than 3");
00069     if (desc.getKeyLen() < 1)
00070                         throw new FODBException("ERROR Bad key length. key length must be more than 1");
00071  }
00072 
00073   protected Node initRoot(FODBIndexDescriptor descriptor) throws FODBException {
00074     FODBStringIndexDescriptor desc = (FODBStringIndexDescriptor) descriptor;
00075     return new StringNode(desc.getOrder(), desc.getKeyLen());
00076   }
00077 
00078   protected void specificHeaderInit(FODBIndexDescriptor descriptor) throws FODBException {
00079     FODBStringIndexDescriptor desc = (FODBStringIndexDescriptor) descriptor;
00080     header.order = desc.getOrder();
00081     header.keyLen = desc.getKeyLen();
00082   }
00083         public Object getKey(Object obj) throws FODBException {
00084                 boolean isCaseSensitive = ((FODBStringIndexDescriptor)this.getIndexDescriptor()).isCaseSensitive();
00085                 return this.getKeySensitive(obj, isCaseSensitive);
00086         }
00087 
00088   public Object getKeySensitive(Object obj, boolean isCaseSensitive) throws FODBException {
00089     String key = null;
00090     if (accessObj instanceof Method) {
00091       try {
00092         key = (String) (((Method) accessObj).invoke(obj, new Object[0]));
00093         if (!isCaseSensitive)   {
00094                 key = StringFormater.removeAccent(key).toUpperCase();
00095         }
00096       } catch (InvocationTargetException ex) { 
00097         throw new FODBException("Unable to execute index's method", ex);
00098       } catch (IllegalAccessException ex) { 
00099         throw new FODBException("Unable to execute index's method", ex);
00100       }
00101     } else {
00102       try {
00103         key = (String) (((Field) accessObj).get(obj));
00104                                 if (!isCaseSensitive)   {
00105                                         key = StringFormater.removeAccent(key).toUpperCase();
00106                                 }
00107       } catch (IllegalAccessException ex) { 
00108         throw new FODBException("Unable to access index's field", ex);
00109       }
00110     }
00111 
00112     return key;
00113   }
00114 
00115   protected void insertKey(Object obj, long ptr) throws IOException, ClassNotFoundException, FODBException {
00116     String key = (String)obj;
00117 
00118     if (key == null) {
00119                         return; //no null key can be inserted.
00120 //      throw new FODBException("Trying to add an Element with invalid key: null key, collection : " + this.name );
00121     }
00122     if (key.length() == 0) {
00123         return; //no key with no element can be inserted.
00124      // throw new FODBException("Trying to add an Element with invalid key : key length 0, collection : " + this.name);
00125     }
00126 
00127     if (key.length() > header.keyLen) {
00128       key = key.substring(0, header.keyLen);
00129     }
00130 
00131                 // search for the key
00132                 StringNode root = (StringNode) this.readRoot();
00133                 SearchResult searchResult = new SearchResult();
00134                 searchResult = this.search(root, key, searchResult);
00135 
00136                 if (searchResult.found) {
00137                         // As we called 'add', if we are in a UNIQUE index, we must
00138                         // return an exception.
00139                         if (getType() == UNIQUE) {
00140                                 throw new FODBException("Entry already present in Unique Index");
00141                         }
00142 
00143                         // store new data record pointer
00144                         //                long result = writeKeyPtr(ins.page, ins.pos, pos, oldPos);
00145                         // if we're in a MULTIPLE index, result is :
00146                         //      -> the new pos of the Pointer List if it grew up.
00147                         //      -> NULL_PTR if it didn't.
00148                         //                long modified = this.writeKeyPtr(ins.page, ins.pos, pos, oldPos);
00149                         this.writeKeyPtr(searchResult.node, searchResult.pos, ptr);
00150                         return;
00151                 }
00152                 if (getType() != UNIQUE) {
00153                         ptr = ((FODBMultipleStringIndex) this).createPtrArray(ptr);
00154                 }
00155                 StringNode btreenode = (StringNode) searchResult.node;
00156                 boolean flag;
00157                 for (flag = btreenode.pushInLeaf(key, searchResult.pos, ptr);
00158                         flag && btreenode.parentPtr != Node.NO_NODE;
00159                         btreenode = (StringNode) colFile.readNode(btreenode.parentPtr)) {
00160                         int i1 = this.minKey;
00161                         StringNode btreenode1 = new StringNode(header.order, header.keyLen);
00162                         btreenode1.parentPtr = btreenode.parentPtr;
00163                         int i;
00164                         for (i = i1 + 1; i < btreenode1.getMaxNbKey(); i++) {
00165                                 btreenode1.setKeyPtrAtPos(btreenode.getKeyAtPos(i), btreenode.getNodePtrAtPos(i), i - i1 - 1);
00166                                 btreenode1.branchs[i - i1 - 1] = btreenode.branchs[i];
00167                         }
00168 
00169                         btreenode1.branchs[i - i1 - 1] = btreenode.branchs[i];
00170                         btreenode1.nbKey = btreenode1.getMaxNbKey() - i1 - 1;
00171                         colFile.writeNode(btreenode1, header);
00172                         if (btreenode1.branchs[0] != Node.NO_NODE) {
00173                                 for (int j = 0; j <= btreenode1.nbKey; j++) {
00174                                         StringNode tempNode = (StringNode) colFile.readNode(btreenode1.branchs[j]);
00175                                         tempNode.parentPtr = btreenode1.filePtr;
00176                                         colFile.writeNode(tempNode, header);
00177                                 }
00178 
00179                         }
00180 
00181                         btreenode.nbKey = this.minKey;
00182                         colFile.writeNode(btreenode, header);
00183                         String newkey = btreenode.getKeyAtPos(i1);
00184                         long keyptr = btreenode.getNodePtrAtPos(i1);
00185 
00186                         StringNode parentNode = (StringNode) colFile.readNode(btreenode.parentPtr);
00187                         SearchResult searchResult1 = parentNode.searchNode(newkey, searchResult);
00188                         flag = parentNode.promote(newkey, keyptr, searchResult1.pos, btreenode1.filePtr);
00189                         colFile.writeNode(parentNode, header);
00190 
00191                 }
00192                 colFile.writeNode(btreenode, header);
00193 
00194                 if (!flag)
00195                         return;
00196 
00197                 // work on root
00198                 root = (StringNode) this.readRoot();
00199                 StringNode parent = new StringNode(header.order, header.keyLen);
00200                 colFile.writeNode(parent, header);
00201                 int j1 = this.minKey;
00202                 StringNode btreenode2 = new StringNode(header.order, header.keyLen);
00203                 btreenode2.parentPtr = parent.filePtr;
00204                 int k;
00205                 for (k = j1 + 1; k < btreenode2.getMaxNbKey(); k++) {
00206                         btreenode2.setKeyPtrAtPos(root.getKeyAtPos(k), root.getNodePtrAtPos(k), k - j1 - 1);
00207                         btreenode2.branchs[k - j1 - 1] = root.branchs[k];
00208                 }
00209 
00210                 btreenode2.branchs[k - j1 - 1] = root.branchs[k];
00211                 btreenode2.nbKey = btreenode2.getMaxNbKey() - j1 - 1;
00212                 colFile.writeNode(btreenode2, header);
00213                 if (btreenode2.branchs[0] != Node.NO_NODE) {
00214                         for (int l = 0; l <= btreenode2.nbKey; l++) {
00215                                 StringNode tempNode = (StringNode) colFile.readNode(btreenode2.branchs[l]);
00216                                 tempNode.parentPtr = btreenode2.filePtr;
00217                                 colFile.writeNode(tempNode, header);
00218                         }
00219                 }
00220                 root.nbKey = this.minKey;
00221                 root.parentPtr = parent.filePtr;
00222                 colFile.writeNode(root, header);
00223                 parent.nbKey = 1;
00224                 parent.setKeyPtrAtPos(root.getKeyAtPos(j1), root.getNodePtrAtPos(j1), 0);
00225                 parent.branchs[0] = root.filePtr;
00226                 parent.branchs[1] = btreenode2.filePtr;
00227                 colFile.writeNode(parent, header);
00228                 return;
00229   }
00230 
00231   //-------------------------
00232   // private utility methods
00233   //-------------------------
00234 
00235 
00236         // find a node
00237         private SearchResult search(StringNode node, String key, SearchResult searchResult) throws IOException, ClassNotFoundException {
00238                 int pos = 0;
00239 
00240                 if (node.nbKey == 0) {
00241                         searchResult.found = false;
00242                         searchResult.node = node;
00243                         searchResult.pos = pos;
00244                         return searchResult;
00245                 }
00246                 searchResult = node.searchNode(key, searchResult);
00247                 if (searchResult.found)
00248                         return searchResult;
00249                 if (searchResult.node.branchs[0] == Node.NO_NODE) {
00250                         return searchResult;
00251                 } else {
00252                         StringNode newNode = (StringNode) colFile.readNode(node.branchs[searchResult.pos]);
00253                         //verify parent ptr of the node
00254                         if (newNode.parentPtr != node.filePtr) {
00255                                 LogManager.traceError(0, "ERROR BAD NODE PARENT");
00256                         }
00257                         searchResult = this.search(newNode, key, searchResult);
00258                         return searchResult;
00259                 }
00260 
00261         }
00262         
00263         public SearchResult getNodeForKey(Object key) throws FODBException      {
00264                 try     {
00265                         StringNode root = (StringNode) this.readRoot();
00266                         SearchResult searchResult = new SearchResult();
00267                         searchResult = this.search(root, (String)key, searchResult);
00268                         return searchResult;            
00269                 } catch (Throwable ex)  {
00270                         throw new FODBException(ex);
00271                 }               
00272         }
00273         
00274 
00275         public long[] query(SodaIndexComparator comparator) throws FODBQueryException {
00276                 try     {
00277                         // find record
00278                         LongArray array = new LongArray(15);
00279                         StringNode root = (StringNode) this.readRoot();
00280                         switch (comparator.getSearchAlgo())     {
00281                                 case SodaIndexComparator.INF_EQUALS_TRAVERSAL :
00282                                         this.searchLikeInfEquals(root, array, (SodaStringIndexComparator)comparator);
00283                                         break;
00284                                 case SodaIndexComparator.SUP_EQUALS_TRAVERSAL :
00285                                         this.searchLikeSupEquals(root, array, (SodaStringIndexComparator)comparator);
00286                                         break;
00287                                 case SodaIndexComparator.FULL_TRAVERSAL :
00288                                         this.searchLikeFull(root, array, (SodaStringIndexComparator)comparator);
00289                                         break;
00290                                 default :
00291                                         break;
00292                         }
00293                         
00294         
00295                         int size = array.size();
00296         
00297                         if (size == 0) {
00298                                 return new long[0];
00299                         }
00300         
00301                         return array.toArray();
00302                 } catch (Throwable ex)  {
00303                         throw new FODBQueryException(ex);
00304                 }
00305         }
00306 
00307         // find a node
00308         private void searchLikeInfEquals(StringNode node, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00309                 int pos = 0;
00310 
00311                 if (node.nbKey == 0) {
00312                         return;
00313                 }
00314 
00315                 while (true) {
00316                         if (pos == node.nbKey)
00317                                 break;
00318                         if (comparator.isSelected(node.getKeyAtPos(pos))) {
00319                                 addSearchResult(node, pos, array, comparator);
00320                                 if (node.branchs[pos] != Node.NO_NODE) {
00321                                         searchLikeInfEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00322                                 }
00323                                 ++pos;
00324                         } else {
00325                                 int comp = comparator.compareTo(node.getKeyAtPos(pos));
00326                                 if (comp < 0)
00327                                         ++pos;
00328                                 else
00329                                         break;
00330                         }
00331                 }
00332 
00333                 if (node.branchs[pos] == Node.NO_NODE) {
00334                         return;
00335                 } else {
00336                         searchLikeInfEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00337                 }
00338         }
00339 
00340         // find a node
00341         private void searchLikeSupEquals(StringNode node, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00342                 int pos = node.nbKey;  //begin at last key
00343 
00344                 if (node.nbKey == 0) {
00345                         return;
00346                 }
00347 
00348                 while (true) {
00349                         if (pos == 0)
00350                                 break;
00351                         if (comparator.isSelected(node.getKeyAtPos(pos-1))) {
00352                                 addSearchResult(node, pos-1, array, comparator);
00353                                 if (node.branchs[pos] != Node.NO_NODE) {
00354                                         searchLikeSupEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00355                                 }
00356                                 --pos;
00357                         } else {
00358                                 int comp = comparator.compareTo(node.getKeyAtPos(pos-1));
00359                                 if (comp < 0)
00360                                         --pos;
00361                                 else
00362                                         break;
00363                         }
00364                 }
00365 
00366                 if (node.branchs[pos] == Node.NO_NODE) {
00367                         return;
00368                 } else {
00369                         searchLikeSupEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00370                 }
00371         }
00372 
00373         private void searchLikeFull(StringNode pg, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00374                 int pos = 0;
00375 
00376                 if (pg.nbKey == 0) {
00377                         return;
00378                 }
00379 
00380                 while (true) {
00381                         if (pos == pg.nbKey) {
00382                                 break;
00383                         }
00384                         if (comparator.isSelected(pg.getKeyAtPos(pos))) {
00385                                 addSearchResult(pg, pos, array, comparator);
00386                         }
00387 
00388                         if (pg.branchs[pos] != Node.NO_NODE) {
00389                                 searchLikeFull((StringNode) colFile.readNode(pg.branchs[pos]), array, comparator);
00390                         }
00391 
00392                         ++pos;
00393                 }
00394 
00395                 if (pg.branchs[pos] == Node.NO_NODE) {
00396                         return;
00397                 } else {
00398                         searchLikeFull((StringNode) colFile.readNode(pg.branchs[pos]), array, comparator);
00399                 }
00400         }       
00401         
00402 
00403   protected void parcours(StringNode pg, int level) throws IOException, ClassNotFoundException {
00404     int pos = 0;
00405 
00406     if (pg.nbKey == 0)
00407       return;
00408 
00409     while (true) {
00410       if (pos == pg.nbKey)
00411         break;
00412 
00413       if (pg.branchs[pos] != Node.NO_NODE) {
00414         parcours((StringNode) colFile.readNode(pg.getNodePtrAtPos(pos)), level + 1);
00415       }
00416 
00417       System.out.println("--> " + level + " : " + pg.getKeyAtPos(pos));
00418 
00419       ++pos;
00420     }
00421 
00422     if (pg.branchs[pos] == Node.NO_NODE) {
00423       return;
00424     } else {
00425       parcours((StringNode) colFile.readNode(pg.getNodePtrAtPos(pos)), level + 1);
00426     }
00427     return;
00428   }
00429   
00430 
00431   protected boolean deleteKey(Object keyTodelete, long dbptr) throws IOException, ClassNotFoundException, FODBException {
00432     String key = (String) keyTodelete;
00433 //    System.out.println("" + header.name + " delete : " + key);
00434 
00435     if (key == null) {
00436       return false;
00437     }
00438     if (key.length() == 0) {
00439       return false;
00440     }
00441 
00442     if (key.length() > header.keyLen) {
00443       key = key.substring(0, header.keyLen);
00444     }
00445 
00446                 StringNode root = (StringNode) this.readRoot();
00447                 SearchResult searchResult = new SearchResult();
00448                 searchResult = this.search(root, key, searchResult);
00449                 if (!searchResult.found) {
00450                         return false;
00451                 }
00452                 boolean empty = this.removeKeyPtr(searchResult.node, searchResult.pos, dbptr);
00453                 if (!empty) {
00454                         return true;
00455                 }
00456 
00457                 StringNode btreenode = (StringNode) searchResult.node;
00458                 if (btreenode.branchs[0] != Node.NO_NODE) { //swap key until we find a leaf.
00459                         btreenode = (StringNode) colFile.readNode(btreenode.branchs[searchResult.pos + 1]);
00460                         while (btreenode.branchs[0] != Node.NO_NODE) {
00461                                 btreenode = (StringNode) colFile.readNode(btreenode.branchs[0]);
00462                         }
00463                         StringNode resultNode = (StringNode) searchResult.node;
00464                         resultNode.setKeyPtrAtPos(btreenode.getKeyAtPos(0), btreenode.getNodePtrAtPos(0), searchResult.pos);
00465                         colFile.writeNode(resultNode, header);
00466                         searchResult.node = btreenode; // work on the leaf.
00467                         searchResult.pos = 0;
00468                 }
00469                 btreenode.removeKeyAtPpos(searchResult.pos);
00470                 colFile.writeNode(btreenode,header);
00471                 for (boolean flag = btreenode.nbKey < this.minKey; flag && (btreenode.parentPtr != Node.NO_NODE); flag = btreenode.nbKey < this.minKey) {
00472                         //get the node branch index in parent.
00473                         int i = 0;
00474                         StringNode parentNode = (StringNode) colFile.readNode(btreenode.parentPtr);
00475                         for (i = 0; parentNode.branchs[i] != btreenode.filePtr; i++);
00476                         this.restore(parentNode, i);
00477                         btreenode = parentNode;
00478                 }
00479 
00480                 if (btreenode.parentPtr != Node.NO_NODE)
00481                         return true;
00482                 if (btreenode.nbKey > 0)
00483                         return true;
00484 
00485                 if (btreenode.branchs[0] != Node.NO_NODE) {
00486                         StringNode firstChild = (StringNode) colFile.readNode(root.branchs[0]);
00487                         if (firstChild.nbKey > 0) {
00488                                 firstChild.parentPtr = Node.NO_NODE;
00489                                 colFile.writeNode(firstChild, header);
00490                                 colFile.deleteNode(btreenode);
00491                                 return true;
00492                         }
00493                 }
00494                 return true;
00495   }
00496 
00497   // BTREE Manipulation method
00498 
00499   private void moveLeft(StringNode node, int i) throws IOException, ClassNotFoundException {
00500     StringNode btreenode = (StringNode) colFile.readNode(node.branchs[i]);
00501     btreenode.nbKey++;
00502     btreenode.setKeyPtrAtPos(node.getKeyAtPos(i), node.getNodePtrAtPos(i), btreenode.nbKey - 1);
00503     StringNode branch = (StringNode) colFile.readNode(node.branchs[i + 1]);
00504     btreenode.branchs[btreenode.nbKey] = branch.branchs[0];
00505     colFile.writeNode(btreenode, header);
00506     if (btreenode.branchs[btreenode.nbKey] != Node.NO_NODE) {
00507       StringNode tempNode = (StringNode) colFile.readNode(btreenode.branchs[btreenode.nbKey]); //non passé
00508       tempNode.parentPtr = btreenode.filePtr;
00509       colFile.writeNode(tempNode, header);
00510     }
00511     btreenode = branch;
00512     node.setKeyPtrAtPos(btreenode.getKeyAtPos(0), btreenode.getNodePtrAtPos(0), i);
00513     colFile.writeNode(node, header);
00514 
00515     for (int j = 0; j < btreenode.nbKey - 1; j++) {
00516       btreenode.setKeyPtrAtPos(btreenode.getKeyAtPos(j + 1), btreenode.getNodePtrAtPos(j + 1), j);
00517       btreenode.branchs[j] = btreenode.branchs[j + 1];
00518     }
00519 
00520     btreenode.branchs[btreenode.nbKey - 1] = btreenode.branchs[btreenode.nbKey];
00521     btreenode.nbKey--;
00522     colFile.writeNode(btreenode, header);
00523   }
00524 
00525   private void moveRight(StringNode node, int pos) throws IOException, ClassNotFoundException {
00526     StringNode rightBranch = (StringNode) colFile.readNode(node.branchs[pos + 1]);
00527     rightBranch.branchs[rightBranch.nbKey + 1] = rightBranch.branchs[rightBranch.nbKey];
00528     for (int j = rightBranch.nbKey - 1; j >= 0; j--) {
00529       rightBranch.setKeyPtrAtPos(rightBranch.getKeyAtPos(j), rightBranch.getNodePtrAtPos(j), j + 1);
00530       rightBranch.branchs[j + 1] = rightBranch.branchs[j];
00531     }
00532 
00533     rightBranch.nbKey++;
00534     rightBranch.setKeyPtrAtPos(node.getKeyAtPos(pos), node.getNodePtrAtPos(pos), 0);
00535     StringNode leftBranch = (StringNode) colFile.readNode(node.branchs[pos]);
00536     node.setKeyPtrAtPos(leftBranch.getKeyAtPos(leftBranch.nbKey - 1), leftBranch.getNodePtrAtPos(leftBranch.nbKey - 1), pos);
00537     rightBranch.branchs[0] = leftBranch.branchs[leftBranch.nbKey]; //change child parent ptr.
00538     colFile.writeNode(rightBranch, header);
00539     if (rightBranch.branchs[0] != Node.NO_NODE) {
00540       StringNode tempNode = (StringNode) colFile.readNode(rightBranch.branchs[0]);
00541       tempNode.parentPtr = rightBranch.filePtr;
00542       colFile.writeNode(tempNode, header);
00543     }
00544 
00545     leftBranch.nbKey--;
00546     colFile.writeNode(leftBranch, header);
00547     colFile.writeNode(node, header);
00548   }
00549 
00550   private void combine(StringNode node, int pos) throws IOException, ClassNotFoundException {
00551     StringNode rightBranch = (StringNode) colFile.readNode(node.branchs[pos + 1]);
00552     StringNode leftBranch = (StringNode) colFile.readNode(node.branchs[pos]);
00553     leftBranch.nbKey++;
00554     leftBranch.setKeyPtrAtPos(node.getKeyAtPos(pos), node.getNodePtrAtPos(pos), leftBranch.nbKey - 1);
00555     leftBranch.branchs[leftBranch.nbKey] = rightBranch.branchs[0];
00556     for (int j = 0; j < rightBranch.nbKey; j++) {
00557       leftBranch.nbKey++;
00558       leftBranch.setKeyPtrAtPos(rightBranch.getKeyAtPos(j), rightBranch.getNodePtrAtPos(j), leftBranch.nbKey - 1);
00559       leftBranch.branchs[leftBranch.nbKey] = rightBranch.branchs[j + 1];
00560     }
00561 
00562                 colFile.writeNode(leftBranch, header);
00563     if (leftBranch.branchs[0] != Node.NO_NODE) {
00564       for (int k = 0; k <= leftBranch.nbKey; k++) {
00565         StringNode tempNode = (StringNode) colFile.readNode(leftBranch.branchs[k]); //non passé
00566         tempNode.parentPtr = leftBranch.filePtr;
00567                                 colFile.writeNode(tempNode, header);
00568       }
00569     }
00570 
00571     node.removeKeyAtPpos(pos);
00572                 colFile.writeNode(node, header);
00573                 colFile.deleteNode(rightBranch);
00574   }
00575 
00576   private void restore(StringNode node, int pos) throws IOException, ClassNotFoundException {
00577     if (pos == 0) {
00578       StringNode child = (StringNode) colFile.readNode(node.branchs[1]);
00579       if (child.nbKey > this.minKey) {
00580         this.moveLeft(node, 0);
00581       } else {
00582         this.combine(node, 0);
00583       }
00584     } else if (pos == node.nbKey) {
00585       StringNode child = (StringNode) colFile.readNode(node.branchs[pos - 1]);
00586       if (child.nbKey > this.minKey) {
00587         moveRight(node, pos - 1);
00588       } else {
00589         combine(node, pos - 1);
00590       }
00591     } else {
00592       StringNode childleft = (StringNode) colFile.readNode(node.branchs[pos - 1]);
00593       StringNode childrigth = (StringNode) colFile.readNode(node.branchs[pos + 1]);
00594       if (childleft.nbKey > this.minKey) {
00595         moveRight(node, pos - 1);
00596       } else if (childrigth.nbKey > this.minKey) {
00597         moveLeft(node, pos);
00598       } else {
00599         combine(node, pos);
00600       }
00601     }
00602   }
00603   public org.openmobileis.common.util.collection.Array getArrayKey(Object obj) throws FODBException{
00604         org.openmobileis.common.util.collection.Array keys=new org.openmobileis.common.util.collection.Array();
00605         String key;
00606         String[] keyArray;
00607         boolean isCaseSensitive = ((FODBStringIndexDescriptor)this.getIndexDescriptor()).isCaseSensitive();
00608         if (accessObj instanceof Method) {
00609         try {
00610                 keyArray=(String[])((Method) accessObj).invoke(obj,new Object[0]);
00611                 for(int i=0;i<keyArray.length;i++){
00612                         key=keyArray[i];
00613                         if(key!=null){
00614                                 if (!isCaseSensitive){
00615                                         key=(StringFormater.removeAccent(key).toUpperCase());
00616                                 }
00617                                 keys.add(key);
00618                         }
00619                 }
00620         }catch (InvocationTargetException ex) { 
00621           throw new FODBException("Unable to execute index's method", ex);
00622         } catch (IllegalAccessException ex) { 
00623           throw new FODBException("Unable to execute index's method", ex);
00624         }
00625       }else {
00626         try {
00627                 keyArray=(String[])(((Field) accessObj).get(obj));
00628                 for(int i=0;i<keyArray.length;i++){
00629                         key=keyArray[i];
00630                         if(key!=null){
00631                                 if (!isCaseSensitive){
00632                                         key=(StringFormater.removeAccent(key).toUpperCase());
00633                                 }
00634                                 keys.add(key);
00635                         }
00636                 }
00637         } catch (IllegalAccessException ex) { 
00638           throw new FODBException("Unable to access index's field", ex);
00639         }
00640       }
00641         return keys;
00642   }
00643   protected abstract void writeKeyPtr(Node pg, int pos, long newptr) throws IOException, ClassNotFoundException;
00644   protected abstract void addSearchResult(StringNode pg, int pos, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException;
00645  // protected abstract void addSearchResult(long pos, LongArray array) throws IOException, ClassNotFoundException;
00646 
00647   protected abstract boolean removeKeyPtr(Node pg, int pos, long pointer) throws IOException, ClassNotFoundException;
00648 }

Generated on Wed Dec 14 21:05:33 2005 for OpenMobileIS by  doxygen 1.4.4