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 * 00027 */ 00028 00029 package org.openmobileis.database.fastobjectdb.db; 00030 00031 import java.io.IOException; 00032 00033 00034 import org.openmobileis.database.fastobjectdb.db.exception.FODBException; 00035 import org.openmobileis.database.fastobjectdb.db.index.FODBIndex; 00036 import org.openmobileis.database.fastobjectdb.db.index.FODBUniqueIndex; 00037 import org.openmobileis.database.fastobjectdb.db.index.SearchResult; 00038 import org.openmobileis.database.fastobjectdb.db.index.node.Node; 00039 00048 public final class BackwardUniqueIndexIterator { 00049 private FODBCollection collection; 00050 private Node currentNode; 00051 private int position = 0; 00052 private boolean begin = false; 00053 private FODBIndex index; 00054 00058 BackwardUniqueIndexIterator(FODBIndex index, FODBCollection collection) throws IOException, ClassNotFoundException, FODBException { 00059 super(); 00060 if (!(index instanceof FODBUniqueIndex)) { 00061 throw new FODBException("Not unique index to iterator awailable"); 00062 } 00063 this.collection = collection; 00064 this.index = index; 00065 collection.getDatabase().getTransactionManager().begin(); 00066 try { 00067 collection.getDatabase().getTransactionManager().enterTransaction(this.collection.getName()); 00068 this.currentNode = index.readRoot(); 00069 if (this.currentNode.nbKey == 0) { //empty index 00070 begin = true; 00071 } 00072 //position at the last element 00073 this.position = this.currentNode.nbKey-1; 00074 long childBranch = currentNode.branchs[this.position+1]; 00075 while (childBranch != Node.NO_NODE) { 00076 this.currentNode = (Node)collection.getNodeAtPos(childBranch); 00077 this.position = this.currentNode.nbKey-1; 00078 childBranch = currentNode.branchs[this.position+1]; 00079 } 00080 } finally { 00081 collection.getDatabase().getTransactionManager().commit(); 00082 } 00083 } 00084 00085 public boolean hasPrev() throws FODBException { 00086 return !begin; 00087 } 00088 00089 public Object prev() throws FODBException { 00090 if (!this.hasPrev()) return null; 00091 collection.getDatabase().getTransactionManager().begin(); 00092 try { 00093 collection.getDatabase().getTransactionManager().enterTransaction(this.collection.getName()); 00094 00095 //read current obj 00096 long objPos= currentNode.ptr[this.position]; 00097 Object ret = collection.getElementAtPos(objPos); 00098 00099 //get next pos 00100 if (currentNode.branchs[(this.position)] != Node.NO_NODE) { //goes down 00101 long childBranch = currentNode.branchs[this.position]; 00102 while (childBranch != Node.NO_NODE) { 00103 this.currentNode = (Node)collection.getNodeAtPos(childBranch); 00104 this.position = currentNode.nbKey-1; 00105 childBranch = currentNode.branchs[this.position+1]; 00106 } 00107 } else { 00108 this.position --; //goes next 00109 while (this.position < 0) { //goes up 00110 long parent = currentNode.parentPtr; 00111 if (parent == Node.NO_NODE) { //root node end index traversal. 00112 begin = true; 00113 break; 00114 } 00115 long nodepos = currentNode.filePtr; 00116 this.currentNode = (Node)collection.getNodeAtPos(parent); 00117 //child node position 00118 int i=0; 00119 for (; i<this.currentNode.branchs.length; i++) { 00120 if (nodepos == this.currentNode.branchs[i]) break; 00121 } 00122 this.position = i-1; 00123 } 00124 } 00125 00126 return ret; 00127 } finally { 00128 collection.getDatabase().getTransactionManager().commit(); 00129 } 00130 } 00131 00132 public void initCurrentNode(Object indexKey) throws FODBException { 00133 collection.getDatabase().getTransactionManager().begin(); 00134 try { 00135 collection.getDatabase().getTransactionManager().enterTransaction(this.collection.getName()); 00136 SearchResult result = ((FODBUniqueIndex)index).getNodeForKey(indexKey); 00137 if (result.found) { 00138 this.currentNode = result.node; 00139 this.position = result.pos; 00140 begin = false; 00141 } 00142 this.prev(); //position to next record. 00143 } finally { 00144 collection.getDatabase().getTransactionManager().commit(); 00145 } 00146 00147 } 00148 }