001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.xdbm; 021 022 023import java.io.IOException; 024import java.net.URI; 025 026import org.apache.directory.api.ldap.model.cursor.Cursor; 027import org.apache.directory.api.ldap.model.exception.LdapException; 028import org.apache.directory.api.ldap.model.schema.AttributeType; 029import org.apache.directory.server.core.api.partition.PartitionTxn; 030 031 032/** 033 * An index used to retrieve elements into the master table. Each stored element that is 034 * indexed has a unique identifier (ID). We may have more than one element associated with 035 * a value (K). We may cache the retrieved element (O). <br> 036 * Cursors over indices can also be gotten to traverse the 037 * values of the index. 038 * 039 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 040 * @param <K> The Indexed value type, used to retrieve an element 041 * @param <E> The unique identifier type in the master table 042 */ 043public interface Index<K, E> 044{ 045 /** The default cache size (ie, the number of elements we stored in the cache) */ 046 int DEFAULT_INDEX_CACHE_SIZE = 100; 047 048 // ----------------------------------------------------------------------- 049 // C O N F I G U R A T I O N M E T H O D S 050 // ----------------------------------------------------------------------- 051 052 /** 053 * Gets the attribute identifier set at configuration time for this index which may not 054 * be the OID but an alias name for the attributeType associated with this Index 055 * 056 * @return configured attribute oid or alias name 057 */ 058 String getAttributeId(); 059 060 061 /** 062 * Sets the attribute identifier set at configuration time for this index which may not 063 * be the OID but an alias name for the attributeType associated with this Index 064 * 065 * @param attributeId configured attribute oid or alias name 066 */ 067 void setAttributeId( String attributeId ); 068 069 070 /** 071 * Gets the size of the index cache in terms of the number of index entries to be cached. 072 * 073 * @return the size of the index cache 074 */ 075 int getCacheSize(); 076 077 078 /** 079 * Sets the size of the index cache in terms of the number of index entries to be cached. 080 * 081 * @param cacheSize the size of the index cache 082 */ 083 void setCacheSize( int cacheSize ); 084 085 086 /** 087 * Sets the working directory path to something other than the default. Sometimes more 088 * performance is gained by locating indices on separate disk spindles. 089 * 090 * @param wkDirPath optional working directory path 091 */ 092 void setWkDirPath( URI wkDirPath ); 093 094 095 /** 096 * Gets the working directory path to something other than the default. Sometimes more 097 * performance is gained by locating indices on separate disk spindles. 098 * 099 * @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}