1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 package org.apache.directory.server.xdbm; 21 22 23 import java.io.IOException; 24 import java.net.URI; 25 26 import org.apache.directory.api.ldap.model.cursor.Cursor; 27 import org.apache.directory.api.ldap.model.exception.LdapException; 28 import org.apache.directory.api.ldap.model.schema.AttributeType; 29 import org.apache.directory.server.core.api.partition.PartitionTxn; 30 31 32 /** 33 * An index used to retrieve elements into the master table. Each stored element that is 34 * indexed has a unique identifier (ID). We may have more than one element associated with 35 * a value (K). We may cache the retrieved element (O). <br> 36 * Cursors over indices can also be gotten to traverse the 37 * values of the index. 38 * 39 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 40 * @param <K> The Indexed value type, used to retrieve an element 41 * @param <E> The unique identifier type in the master table 42 */ 43 public interface Index<K, E> 44 { 45 /** The default cache size (ie, the number of elements we stored in the cache) */ 46 int DEFAULT_INDEX_CACHE_SIZE = 100; 47 48 // ----------------------------------------------------------------------- 49 // C O N F I G U R A T I O N M E T H O D S 50 // ----------------------------------------------------------------------- 51 52 /** 53 * Gets the attribute identifier set at configuration time for this index which may not 54 * be the OID but an alias name for the attributeType associated with this Index 55 * 56 * @return configured attribute oid or alias name 57 */ 58 String getAttributeId(); 59 60 61 /** 62 * Sets the attribute identifier set at configuration time for this index which may not 63 * be the OID but an alias name for the attributeType associated with this Index 64 * 65 * @param attributeId configured attribute oid or alias name 66 */ 67 void setAttributeId( String attributeId ); 68 69 70 /** 71 * Gets the size of the index cache in terms of the number of index entries to be cached. 72 * 73 * @return the size of the index cache 74 */ 75 int getCacheSize(); 76 77 78 /** 79 * Sets the size of the index cache in terms of the number of index entries to be cached. 80 * 81 * @param cacheSize the size of the index cache 82 */ 83 void setCacheSize( int cacheSize ); 84 85 86 /** 87 * Sets the working directory path to something other than the default. Sometimes more 88 * performance is gained by locating indices on separate disk spindles. 89 * 90 * @param wkDirPath optional working directory path 91 */ 92 void setWkDirPath( URI wkDirPath ); 93 94 95 /** 96 * Gets the working directory path to something other than the default. Sometimes more 97 * performance is gained by locating indices on separate disk spindles. 98 * 99 * @return optional working directory path 100 */ 101 URI getWkDirPath(); 102 103 104 // ----------------------------------------------------------------------- 105 // E N D C O N F I G U R A T I O N M E T H O D S 106 // ----------------------------------------------------------------------- 107 108 /** 109 * Gets the attribute this Index is built upon. 110 * 111 * @return the id of the Index's attribute 112 */ 113 AttributeType getAttribute(); 114 115 116 /** 117 * Gets the total scan count for this index. 118 * 119 * @param partitionTxn The transaction to use 120 * @return the number of key/value pairs in this index 121 * @throws LdapException on failure to access index db files 122 */ 123 long count( PartitionTxn partitionTxn ) throws LdapException; 124 125 126 /** 127 * Gets the scan count for the occurrence of a specific attribute value 128 * within the index. 129 * 130 * @param partitionTxn The transaction to use 131 * @param attrVal the value of the attribute to get a scan count for 132 * @return the number of key/value pairs in this index with the value value 133 * @throws LdapException on failure to access index db files 134 */ 135 long count( PartitionTxn partitionTxn, K attrVal ) throws LdapException; 136 137 138 /** 139 * Find the number of element in a tree above a given key 140 * 141 * @param partitionTxn The transaction to use 142 * @param attrVal The key 143 * @return The number of element above the key 144 * @throws LdapException If the operation failed 145 */ 146 long greaterThanCount( PartitionTxn partitionTxn, K attrVal ) throws LdapException; 147 148 149 /** 150 * Find the number of element in a tree below a given key 151 * 152 * @param partitionTxn The transaction to use 153 * @param attrVal The key 154 * @return The number of element below the key 155 * @throws LdapException If the operation failed 156 */ 157 long lessThanCount( PartitionTxn partitionTxn, K attrVal ) throws LdapException; 158 159 160 /** 161 * Search for a value using the Forward table 162 * 163 * @param partitionTxn The transaction to use 164 * @param attrVal The key to retrieve 165 * @return The found value 166 * @throws LdapException If the operation failed 167 */ 168 E forwardLookup( PartitionTxn partitionTxn, K attrVal ) throws LdapException; 169 170 171 /** 172 * Search for a value using the Reverse table 173 * 174 * @param partitionTxn The transaction to use 175 * @param element The key to retrieve 176 * @return The found value 177 * @throws LdapException If the operation failed 178 */ 179 K reverseLookup( PartitionTxn partitionTxn, E element ) throws LdapException; 180 181 182 /** 183 * Add an entry into the index, associated with the element E. The added 184 * value is the key to retrieve the element having the given ID. 185 * 186 * @param partitionTxn The transaction to use 187 * @param attrVal The added value 188 * @param entryId The entry ID pointed by the added value 189 * @throws LdapException If the addition can't be done 190 */ 191 void add( PartitionTxn partitionTxn, K attrVal, E entryId ) throws LdapException; 192 193 194 /** 195 * Remove all the reference to an entry from the index. 196 * <br> 197 * As an entry might be referenced more than once in the forward index, 198 * depending on which index we are dealing with, we need to iterate 199 * over all the values contained into the reverse index for this entryId. 200 * <br> 201 * For instance, considering the ObjectClass index for an entry having 202 * three ObjectClasses (top, person, inetOrgPerson), then the reverse 203 * index will contain : 204 * <pre> 205 * [entryId, [top, person, inetOrgPerson]] 206 * </pre> 207 * and the forward index will contain many entries like : 208 * <pre> 209 * [top, [..., entryId, ...]] 210 * [person, [..., entryId, ...]] 211 * [inetOrgPerson, [..., entryId, ...]] 212 * </pre> 213 * So dropping the entryId means that we must first get all the values from 214 * the reverse index (and we will get [top, person, inetOrgPerson]) then to 215 * iterate through all those values to remove entryId from the associated 216 * list of entryIds. 217 * 218 * @param partitionTxn The transaction to use 219 * @param entryId The master table entryId to remove 220 * @throws LdapException if we can't drop the element from the index 221 */ 222 void drop( PartitionTxn partitionTxn, E entryId ) throws LdapException; 223 224 225 /** 226 * Remove the pair <K,ID> from the index for the given value and id. 227 * 228 * @param partitionTxn The transaction to use 229 * @param attrVal The value we want to remove from the index 230 * @param entryId The associated ID 231 * @throws LdapException If the removal can't be done 232 */ 233 void drop( PartitionTxn partitionTxn, K attrVal, E entryId ) throws LdapException; 234 235 236 /** 237 * Builds a Cursor on the Forward index 238 * 239 * @param partitionTxn The transaction to use 240 * @return The created Cursor 241 * @throws LdapException If the cursor can't be created 242 */ 243 Cursor<IndexEntry<K, E>> forwardCursor( PartitionTxn partitionTxn ) throws LdapException; 244 245 246 /** 247 * Builds a Cursor on the Forward index, starting at a specific key 248 * 249 * @param partitionTxn The transaction to use 250 * @param key The key to start from 251 * @return The created Cursor 252 * @throws LdapException If the cursor can't be created 253 */ 254 Cursor<IndexEntry<K, E>> forwardCursor( PartitionTxn partitionTxn, K key ) throws LdapException; 255 256 257 /** 258 * Builds a Cursor on the Reverse index, starting at a specific entry Id 259 * 260 * @param partitionTxn The transaction to use 261 * @param entryId The entry ID to start from 262 * @return The created Cursor 263 * @throws LdapException If the cursor can't be created 264 */ 265 Cursor<K> reverseValueCursor( PartitionTxn partitionTxn, E entryId ) throws LdapException; 266 267 268 /** 269 * Builds a Cursor on the Forward index, starting at a specific key 270 * 271 * @param partitionTxn The transaction to use 272 * @param key The key to start from 273 * @return The created Cursor 274 * @throws LdapException If the cursor can't be created 275 */ 276 Cursor<E> forwardValueCursor( PartitionTxn partitionTxn, K key ) throws LdapException; 277 278 279 /** 280 * Try to move forward in the index 281 * 282 * @param partitionTxn The transaction to use 283 * @param attrVal The key we want to start with 284 * @return <tt>true</tt> if we can move forward 285 * @throws LdapException If we had an issue moving forward 286 */ 287 boolean forward( PartitionTxn partitionTxn, K attrVal ) throws LdapException; 288 289 290 /** 291 * Try to move forward in the index 292 * 293 * @param partitionTxn The transaction to use 294 * @param attrVal The key we want to start with 295 * @param entryId The entry ID to start from 296 * @return <tt>true</tt> if we can move forward 297 * @throws LdapException If we had an issue moving forward 298 */ 299 boolean forward( PartitionTxn partitionTxn, K attrVal, E entryId ) throws LdapException; 300 301 302 /** 303 * Try to move backward in the index 304 * 305 * @param partitionTxn The transaction to use 306 * @param entryId The entry we want to start with 307 * @return <tt>true</tt> if we can move backward 308 * @throws LdapException If we had an issue moving backward 309 */ 310 boolean reverse( PartitionTxn partitionTxn, E entryId ) throws LdapException; 311 312 313 /** 314 * Try to move backward in the index 315 * 316 * @param partitionTxn The transaction to use 317 * @param entryId The entry ID to start from 318 * @param attrVal The key we want to start with 319 * @return <tt>true</tt> if we can move backward 320 * @throws LdapException If we had an issue moving backward 321 */ 322 boolean reverse( PartitionTxn partitionTxn, E entryId, K attrVal ) throws LdapException; 323 324 325 /** 326 * Close and index 327 * 328 * @param partitionTxn The transaction to use 329 * @throws LdapException If we weren't able to close the index 330 * @throws IOException If we had an issue with the index file 331 */ 332 void close( PartitionTxn partitionTxn ) throws LdapException, IOException; 333 334 335 /** 336 * tells whether the Index implementation supports storing duplicate keys 337 * 338 * @return true if duplicate keys are allowed false otherwise 339 */ 340 boolean isDupsEnabled(); 341 342 343 /** 344 * Tells if the index has a reverse table or not 345 * @return true if the index has a reverse table 346 */ 347 boolean hasReverse(); 348 }