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

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                 long found = Node.NO_NODE;
00136 
00137                 if (searchResult.found) {
00138                         // As we called 'add', if we are in a UNIQUE index, we must
00139                         // return an exception.
00140                         if (getType() == UNIQUE) {
00141                                 throw new FODBException("Entry already present in Unique Index");
00142                         }
00143 
00144                         // store new data record pointer
00145                         //                long result = writeKeyPtr(ins.page, ins.pos, pos, oldPos);
00146                         // if we're in a MULTIPLE index, result is :
00147                         //      -> the new pos of the Pointer List if it grew up.
00148                         //      -> NULL_PTR if it didn't.
00149                         //                long modified = this.writeKeyPtr(ins.page, ins.pos, pos, oldPos);
00150                         this.writeKeyPtr(searchResult.node, searchResult.pos, ptr);
00151                         return;
00152                 }
00153                 if (getType() != UNIQUE) {
00154                         ptr = ((FODBMultipleStringIndex) this).createPtrArray(ptr);
00155                 }
00156                 StringNode btreenode = (StringNode) searchResult.node;
00157                 boolean flag;
00158                 for (flag = btreenode.pushInLeaf(key, searchResult.pos, ptr);
00159                         flag && btreenode.parentPtr != Node.NO_NODE;
00160                         btreenode = (StringNode) colFile.readNode(btreenode.parentPtr)) {
00161                         int i1 = this.minKey;
00162                         StringNode btreenode1 = new StringNode(header.order, header.keyLen);
00163                         btreenode1.parentPtr = btreenode.parentPtr;
00164                         int i;
00165                         for (i = i1 + 1; i < btreenode1.getMaxNbKey(); i++) {
00166                                 btreenode1.setKeyPtrAtPos(btreenode.getKeyAtPos(i), btreenode.getNodePtrAtPos(i), i - i1 - 1);
00167                                 btreenode1.branchs[i - i1 - 1] = btreenode.branchs[i];
00168                         }
00169 
00170                         btreenode1.branchs[i - i1 - 1] = btreenode.branchs[i];
00171                         btreenode1.nbKey = btreenode1.getMaxNbKey() - i1 - 1;
00172                         colFile.writeNode(btreenode1, header);
00173                         if (btreenode1.branchs[0] != Node.NO_NODE) {
00174                                 for (int j = 0; j <= btreenode1.nbKey; j++) {
00175                                         StringNode tempNode = (StringNode) colFile.readNode(btreenode1.branchs[j]);
00176                                         tempNode.parentPtr = btreenode1.filePtr;
00177                                         colFile.writeNode(tempNode, header);
00178                                 }
00179 
00180                         }
00181 
00182                         btreenode.nbKey = this.minKey;
00183                         colFile.writeNode(btreenode, header);
00184                         String newkey = btreenode.getKeyAtPos(i1);
00185                         long keyptr = btreenode.getNodePtrAtPos(i1);
00186 
00187                         StringNode parentNode = (StringNode) colFile.readNode(btreenode.parentPtr);
00188                         SearchResult searchResult1 = parentNode.searchNode(newkey, searchResult);
00189                         flag = parentNode.promote(newkey, keyptr, searchResult1.pos, btreenode1.filePtr);
00190                         colFile.writeNode(parentNode, header);
00191 
00192                 }
00193                 colFile.writeNode(btreenode, header);
00194 
00195                 if (!flag)
00196                         return;
00197 
00198                 // work on root
00199                 root = (StringNode) this.readRoot();
00200                 StringNode parent = new StringNode(header.order, header.keyLen);
00201                 colFile.writeNode(parent, header);
00202                 int j1 = this.minKey;
00203                 StringNode btreenode2 = new StringNode(header.order, header.keyLen);
00204                 btreenode2.parentPtr = parent.filePtr;
00205                 int k;
00206                 for (k = j1 + 1; k < btreenode2.getMaxNbKey(); k++) {
00207                         btreenode2.setKeyPtrAtPos(root.getKeyAtPos(k), root.getNodePtrAtPos(k), k - j1 - 1);
00208                         btreenode2.branchs[k - j1 - 1] = root.branchs[k];
00209                 }
00210 
00211                 btreenode2.branchs[k - j1 - 1] = root.branchs[k];
00212                 btreenode2.nbKey = btreenode2.getMaxNbKey() - j1 - 1;
00213                 colFile.writeNode(btreenode2, header);
00214                 if (btreenode2.branchs[0] != Node.NO_NODE) {
00215                         for (int l = 0; l <= btreenode2.nbKey; l++) {
00216                                 StringNode tempNode = (StringNode) colFile.readNode(btreenode2.branchs[l]);
00217                                 tempNode.parentPtr = btreenode2.filePtr;
00218                                 colFile.writeNode(tempNode, header);
00219                         }
00220                 }
00221                 root.nbKey = this.minKey;
00222                 root.parentPtr = parent.filePtr;
00223                 colFile.writeNode(root, header);
00224                 parent.nbKey = 1;
00225                 parent.setKeyPtrAtPos(root.getKeyAtPos(j1), root.getNodePtrAtPos(j1), 0);
00226                 parent.branchs[0] = root.filePtr;
00227                 parent.branchs[1] = btreenode2.filePtr;
00228                 colFile.writeNode(parent, header);
00229                 return;
00230   }
00231 
00232   //-------------------------
00233   // private utility methods
00234   //-------------------------
00235 
00236 
00237         // find a node
00238         private SearchResult search(StringNode node, String key, SearchResult searchResult) throws IOException, ClassNotFoundException {
00239                 int pos = 0;
00240 
00241                 if (node.nbKey == 0) {
00242                         searchResult.found = false;
00243                         searchResult.node = node;
00244                         searchResult.pos = pos;
00245                         return searchResult;
00246                 }
00247                 searchResult = node.searchNode(key, searchResult);
00248                 if (searchResult.found)
00249                         return searchResult;
00250                 if (searchResult.node.branchs[0] == Node.NO_NODE) {
00251                         return searchResult;
00252                 } else {
00253                         StringNode newNode = (StringNode) colFile.readNode(node.branchs[searchResult.pos]);
00254                         //verify parent ptr of the node
00255                         if (newNode.parentPtr != node.filePtr) {
00256                                 LogManager.traceError(0, "ERROR BAD NODE PARENT");
00257                         }
00258                         searchResult = this.search(newNode, key, searchResult);
00259                         return searchResult;
00260                 }
00261 
00262         }
00263         
00264         public SearchResult getNodeForKey(Object key) throws FODBException      {
00265                 try     {
00266                         StringNode root = (StringNode) this.readRoot();
00267                         SearchResult searchResult = new SearchResult();
00268                         searchResult = this.search(root, (String)key, searchResult);
00269                         return searchResult;            
00270                 } catch (Throwable ex)  {
00271                         throw new FODBException(ex);
00272                 }               
00273         }
00274         
00275 
00276         public long[] query(SodaIndexComparator comparator) throws FODBQueryException {
00277                 try     {
00278                         // find record
00279                         LongArray array = new LongArray(15);
00280                         StringNode root = (StringNode) this.readRoot();
00281                         switch (comparator.getSearchAlgo())     {
00282                                 case SodaIndexComparator.INF_EQUALS_TRAVERSAL :
00283                                         this.searchLikeInfEquals(root, array, (SodaStringIndexComparator)comparator);
00284                                         break;
00285                                 case SodaIndexComparator.SUP_EQUALS_TRAVERSAL :
00286                                         this.searchLikeSupEquals(root, array, (SodaStringIndexComparator)comparator);
00287                                         break;
00288                                 case SodaIndexComparator.FULL_TRAVERSAL :
00289                                         this.searchLikeFull(root, array, (SodaStringIndexComparator)comparator);
00290                                         break;
00291                                 default :
00292                                         break;
00293                         }
00294                         
00295         
00296                         int size = array.size();
00297         
00298                         if (size == 0) {
00299                                 return new long[0];
00300                         }
00301         
00302                         return array.toArray();
00303                 } catch (Throwable ex)  {
00304                         throw new FODBQueryException(ex);
00305                 }
00306         }
00307 
00308         // find a node
00309         private void searchLikeInfEquals(StringNode node, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00310                 int pos = 0;
00311 
00312                 if (node.nbKey == 0) {
00313                         return;
00314                 }
00315 
00316                 while (true) {
00317                         if (pos == node.nbKey)
00318                                 break;
00319                         if (comparator.isSelected(node.getKeyAtPos(pos))) {
00320                                 addSearchResult(node, pos, array, comparator);
00321                                 if (node.branchs[pos] != Node.NO_NODE) {
00322                                         searchLikeInfEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00323                                 }
00324                                 ++pos;
00325                         } else {
00326                                 int comp = comparator.compareTo(node.getKeyAtPos(pos));
00327                                 if (comp < 0)
00328                                         ++pos;
00329                                 else
00330                                         break;
00331                         }
00332                 }
00333 
00334                 if (node.branchs[pos] == Node.NO_NODE) {
00335                         return;
00336                 } else {
00337                         searchLikeInfEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00338                 }
00339         }
00340 
00341         // find a node
00342         private void searchLikeSupEquals(StringNode node, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00343                 int pos = node.nbKey;  //begin at last key
00344 
00345                 if (node.nbKey == 0) {
00346                         return;
00347                 }
00348 
00349                 while (true) {
00350                         if (pos == 0)
00351                                 break;
00352                         if (comparator.isSelected(node.getKeyAtPos(pos-1))) {
00353                                 addSearchResult(node, pos-1, array, comparator);
00354                                 if (node.branchs[pos] != Node.NO_NODE) {
00355                                         searchLikeSupEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00356                                 }
00357                                 --pos;
00358                         } else {
00359                                 int comp = comparator.compareTo(node.getKeyAtPos(pos-1));
00360                                 if (comp < 0)
00361                                         --pos;
00362                                 else
00363                                         break;
00364                         }
00365                 }
00366 
00367                 if (node.branchs[pos] == Node.NO_NODE) {
00368                         return;
00369                 } else {
00370                         searchLikeSupEquals((StringNode)colFile.readNode(node.branchs[pos]), array, comparator);
00371                 }
00372         }
00373 
00374         private void searchLikeFull(StringNode pg, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException {
00375                 int pos = 0;
00376 
00377                 if (pg.nbKey == 0) {
00378                         return;
00379                 }
00380 
00381                 while (true) {
00382                         if (pos == pg.nbKey) {
00383                                 break;
00384                         }
00385                         if (comparator.isSelected(pg.getKeyAtPos(pos))) {
00386                                 addSearchResult(pg, pos, array, comparator);
00387                         }
00388 
00389                         if (pg.branchs[pos] != Node.NO_NODE) {
00390                                 searchLikeFull((StringNode) colFile.readNode(pg.branchs[pos]), array, comparator);
00391                         }
00392 
00393                         ++pos;
00394                 }
00395 
00396                 if (pg.branchs[pos] == Node.NO_NODE) {
00397                         return;
00398                 } else {
00399                         searchLikeFull((StringNode) colFile.readNode(pg.branchs[pos]), array, comparator);
00400                 }
00401         }       
00402         
00403 
00404   protected void parcours(StringNode pg, int level) throws IOException, ClassNotFoundException {
00405     int pos = 0;
00406 
00407     if (pg.nbKey == 0)
00408       return;
00409 
00410     while (true) {
00411       if (pos == pg.nbKey)
00412         break;
00413 
00414       if (pg.branchs[pos] != Node.NO_NODE) {
00415         parcours((StringNode) colFile.readNode(pg.getNodePtrAtPos(pos)), level + 1);
00416       }
00417 
00418       System.out.println("--> " + level + " : " + pg.getKeyAtPos(pos));
00419 
00420       ++pos;
00421     }
00422 
00423     if (pg.branchs[pos] == Node.NO_NODE) {
00424       return;
00425     } else {
00426       parcours((StringNode) colFile.readNode(pg.getNodePtrAtPos(pos)), level + 1);
00427     }
00428     return;
00429   }
00430   
00431 
00432   protected boolean deleteKey(Object keyTodelete, long dbptr) throws IOException, ClassNotFoundException, FODBException {
00433     String key = (String) keyTodelete;
00434 //    System.out.println("" + header.name + " delete : " + key);
00435 
00436     if (key == null) {
00437       return false;
00438     }
00439     if (key.length() == 0) {
00440       return false;
00441     }
00442 
00443     if (key.length() > header.keyLen) {
00444       key = key.substring(0, header.keyLen);
00445     }
00446 
00447                 StringNode root = (StringNode) this.readRoot();
00448                 SearchResult searchResult = new SearchResult();
00449                 searchResult = this.search(root, key, searchResult);
00450                 if (!searchResult.found) {
00451                         return false;
00452                 }
00453                 boolean empty = this.removeKeyPtr(searchResult.node, searchResult.pos, dbptr);
00454                 if (!empty) {
00455                         return true;
00456                 }
00457                 long found = searchResult.node.getNodePtrAtPos(searchResult.pos);
00458 
00459                 StringNode btreenode = (StringNode) searchResult.node;
00460                 if (btreenode.branchs[0] != Node.NO_NODE) { //swap key until we find a leaf.
00461                         btreenode = (StringNode) colFile.readNode(btreenode.branchs[searchResult.pos + 1]);
00462                         while (btreenode.branchs[0] != Node.NO_NODE) {
00463                                 btreenode = (StringNode) colFile.readNode(btreenode.branchs[0]);
00464                         }
00465                         StringNode resultNode = (StringNode) searchResult.node;
00466                         resultNode.setKeyPtrAtPos(btreenode.getKeyAtPos(0), btreenode.getNodePtrAtPos(0), searchResult.pos);
00467                         colFile.writeNode(resultNode, header);
00468                         searchResult.node = btreenode; // work on the leaf.
00469                         searchResult.pos = 0;
00470                 }
00471                 btreenode.removeKeyAtPpos(searchResult.pos);
00472                 colFile.writeNode(btreenode,header);
00473                 for (boolean flag = btreenode.nbKey < this.minKey; flag && (btreenode.parentPtr != Node.NO_NODE); flag = btreenode.nbKey < this.minKey) {
00474                         //get the node branch index in parent.
00475                         int i = 0;
00476                         StringNode parentNode = (StringNode) colFile.readNode(btreenode.parentPtr);
00477                         for (i = 0; parentNode.branchs[i] != btreenode.filePtr; i++);
00478                         this.restore(parentNode, i);
00479                         btreenode = parentNode;
00480                 }
00481 
00482                 if (btreenode.parentPtr != Node.NO_NODE)
00483                         return true;
00484                 if (btreenode.nbKey > 0)
00485                         return true;
00486 
00487                 if (btreenode.branchs[0] != Node.NO_NODE) {
00488                         StringNode firstChild = (StringNode) colFile.readNode(root.branchs[0]);
00489                         if (firstChild.nbKey > 0) {
00490                                 firstChild.parentPtr = Node.NO_NODE;
00491                                 colFile.writeNode(firstChild, header);
00492                                 colFile.deleteNode(btreenode);
00493                                 return true;
00494                         }
00495                 }
00496                 return true;
00497   }
00498 
00499   // BTREE Manipulation method
00500 
00501   private void moveLeft(StringNode node, int i) throws IOException, ClassNotFoundException {
00502     StringNode btreenode = (StringNode) colFile.readNode(node.branchs[i]);
00503     btreenode.nbKey++;
00504     btreenode.setKeyPtrAtPos(node.getKeyAtPos(i), node.getNodePtrAtPos(i), btreenode.nbKey - 1);
00505     StringNode branch = (StringNode) colFile.readNode(node.branchs[i + 1]);
00506     btreenode.branchs[btreenode.nbKey] = branch.branchs[0];
00507     colFile.writeNode(btreenode, header);
00508     if (btreenode.branchs[btreenode.nbKey] != Node.NO_NODE) {
00509       StringNode tempNode = (StringNode) colFile.readNode(btreenode.branchs[btreenode.nbKey]); //non passé
00510       tempNode.parentPtr = btreenode.filePtr;
00511       colFile.writeNode(tempNode, header);
00512     }
00513     btreenode = branch;
00514     node.setKeyPtrAtPos(btreenode.getKeyAtPos(0), btreenode.getNodePtrAtPos(0), i);
00515     colFile.writeNode(node, header);
00516 
00517     for (int j = 0; j < btreenode.nbKey - 1; j++) {
00518       btreenode.setKeyPtrAtPos(btreenode.getKeyAtPos(j + 1), btreenode.getNodePtrAtPos(j + 1), j);
00519       btreenode.branchs[j] = btreenode.branchs[j + 1];
00520     }
00521 
00522     btreenode.branchs[btreenode.nbKey - 1] = btreenode.branchs[btreenode.nbKey];
00523     btreenode.nbKey--;
00524     colFile.writeNode(btreenode, header);
00525   }
00526 
00527   private void moveRight(StringNode node, int pos) throws IOException, ClassNotFoundException {
00528     StringNode rightBranch = (StringNode) colFile.readNode(node.branchs[pos + 1]);
00529     rightBranch.branchs[rightBranch.nbKey + 1] = rightBranch.branchs[rightBranch.nbKey];
00530     for (int j = rightBranch.nbKey - 1; j >= 0; j--) {
00531       rightBranch.setKeyPtrAtPos(rightBranch.getKeyAtPos(j), rightBranch.getNodePtrAtPos(j), j + 1);
00532       rightBranch.branchs[j + 1] = rightBranch.branchs[j];
00533     }
00534 
00535     rightBranch.nbKey++;
00536     rightBranch.setKeyPtrAtPos(node.getKeyAtPos(pos), node.getNodePtrAtPos(pos), 0);
00537     StringNode leftBranch = (StringNode) colFile.readNode(node.branchs[pos]);
00538     node.setKeyPtrAtPos(leftBranch.getKeyAtPos(leftBranch.nbKey - 1), leftBranch.getNodePtrAtPos(leftBranch.nbKey - 1), pos);
00539     rightBranch.branchs[0] = leftBranch.branchs[leftBranch.nbKey]; //change child parent ptr.
00540     colFile.writeNode(rightBranch, header);
00541     if (rightBranch.branchs[0] != Node.NO_NODE) {
00542       StringNode tempNode = (StringNode) colFile.readNode(rightBranch.branchs[0]);
00543       tempNode.parentPtr = rightBranch.filePtr;
00544       colFile.writeNode(tempNode, header);
00545     }
00546 
00547     leftBranch.nbKey--;
00548     colFile.writeNode(leftBranch, header);
00549     colFile.writeNode(node, header);
00550   }
00551 
00552   private void combine(StringNode node, int pos) throws IOException, ClassNotFoundException {
00553     StringNode rightBranch = (StringNode) colFile.readNode(node.branchs[pos + 1]);
00554     StringNode leftBranch = (StringNode) colFile.readNode(node.branchs[pos]);
00555     leftBranch.nbKey++;
00556     leftBranch.setKeyPtrAtPos(node.getKeyAtPos(pos), node.getNodePtrAtPos(pos), leftBranch.nbKey - 1);
00557     leftBranch.branchs[leftBranch.nbKey] = rightBranch.branchs[0];
00558     for (int j = 0; j < rightBranch.nbKey; j++) {
00559       leftBranch.nbKey++;
00560       leftBranch.setKeyPtrAtPos(rightBranch.getKeyAtPos(j), rightBranch.getNodePtrAtPos(j), leftBranch.nbKey - 1);
00561       leftBranch.branchs[leftBranch.nbKey] = rightBranch.branchs[j + 1];
00562     }
00563 
00564                 colFile.writeNode(leftBranch, header);
00565     if (leftBranch.branchs[0] != Node.NO_NODE) {
00566       for (int k = 0; k <= leftBranch.nbKey; k++) {
00567         StringNode tempNode = (StringNode) colFile.readNode(leftBranch.branchs[k]); //non passé
00568         tempNode.parentPtr = leftBranch.filePtr;
00569                                 colFile.writeNode(tempNode, header);
00570       }
00571     }
00572 
00573     node.removeKeyAtPpos(pos);
00574                 colFile.writeNode(node, header);
00575                 colFile.deleteNode(rightBranch);
00576   }
00577 
00578   private void restore(StringNode node, int pos) throws IOException, ClassNotFoundException {
00579     if (pos == 0) {
00580       StringNode child = (StringNode) colFile.readNode(node.branchs[1]);
00581       if (child.nbKey > this.minKey) {
00582         this.moveLeft(node, 0);
00583       } else {
00584         this.combine(node, 0);
00585       }
00586     } else if (pos == node.nbKey) {
00587       StringNode child = (StringNode) colFile.readNode(node.branchs[pos - 1]);
00588       if (child.nbKey > this.minKey) {
00589         moveRight(node, pos - 1);
00590       } else {
00591         combine(node, pos - 1);
00592       }
00593     } else {
00594       StringNode childleft = (StringNode) colFile.readNode(node.branchs[pos - 1]);
00595       StringNode childrigth = (StringNode) colFile.readNode(node.branchs[pos + 1]);
00596       if (childleft.nbKey > this.minKey) {
00597         moveRight(node, pos - 1);
00598       } else if (childrigth.nbKey > this.minKey) {
00599         moveLeft(node, pos);
00600       } else {
00601         combine(node, pos);
00602       }
00603     }
00604   }
00605   public org.openmobileis.common.util.collection.Array getArrayKey(Object obj) throws FODBException{
00606         org.openmobileis.common.util.collection.Array keys=new org.openmobileis.common.util.collection.Array();
00607         String key;
00608         String[] keyArray;
00609         boolean isCaseSensitive = ((FODBStringIndexDescriptor)this.getIndexDescriptor()).isCaseSensitive();
00610         if (accessObj instanceof Method) {
00611         try {
00612                 keyArray=(String[])((Method) accessObj).invoke(obj,new Object[0]);
00613                 for(int i=0;i<keyArray.length;i++){
00614                         key=keyArray[i];
00615                         if(key!=null){
00616                                 if (!isCaseSensitive){
00617                                         key=(StringFormater.removeAccent(key).toUpperCase());
00618                                 }
00619                                 keys.add(key);
00620                         }
00621                 }
00622         }catch (InvocationTargetException ex) { 
00623           throw new FODBException("Unable to execute index's method", ex);
00624         } catch (IllegalAccessException ex) { 
00625           throw new FODBException("Unable to execute index's method", ex);
00626         }
00627       }else {
00628         try {
00629                 keyArray=(String[])(((Field) accessObj).get(obj));
00630                 for(int i=0;i<keyArray.length;i++){
00631                         key=keyArray[i];
00632                         if(key!=null){
00633                                 if (!isCaseSensitive){
00634                                         key=(StringFormater.removeAccent(key).toUpperCase());
00635                                 }
00636                                 keys.add(key);
00637                         }
00638                 }
00639         } catch (IllegalAccessException ex) { 
00640           throw new FODBException("Unable to access index's field", ex);
00641         }
00642       }
00643         return keys;
00644   }
00645   protected abstract void writeKeyPtr(Node pg, int pos, long newptr) throws IOException, ClassNotFoundException;
00646   protected abstract void addSearchResult(StringNode pg, int pos, LongArray array, SodaStringIndexComparator comparator) throws IOException, ClassNotFoundException;
00647  // protected abstract void addSearchResult(long pos, LongArray array) throws IOException, ClassNotFoundException;
00648 
00649   protected abstract boolean removeKeyPtr(Node pg, int pos, long pointer) throws IOException, ClassNotFoundException;
00650 }

Generated on Thu Oct 6 10:06:33 2005 for OpenMobileIS by  doxygen 1.4.3