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.util.Comparator; 024 025import org.apache.directory.api.ldap.model.cursor.Cursor; 026import org.apache.directory.api.ldap.model.cursor.Tuple; 027import org.apache.directory.api.ldap.model.exception.LdapException; 028import org.apache.directory.server.core.api.partition.PartitionTxn; 029 030 031/** 032 * A wrapper interface around BTree implementations used to abstract away 033 * implementation details. 034 * 035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 036 */ 037public interface Table<K, V> 038{ 039 /** 040 * Gets the key comparator used by this Table: may be null if this Table 041 * was not initialized with one. 042 * 043 * @return the key comparator or null if this Table was not created with 044 * one. 045 */ 046 Comparator<K> getKeyComparator(); 047 048 049 /** 050 * Gets the value comparator used by this Table: may be null if this Table 051 * was not initialized with one. 052 * 053 * @return the value comparator or null if this Table was not created with 054 * one. 055 */ 056 Comparator<V> getValueComparator(); 057 058 059 /** 060 * Gets the name of this Table. 061 * 062 * @return the name 063 */ 064 String getName(); 065 066 067 /** 068 * Checks to see if this Table has allows for duplicate keys (a.k.a. 069 * multiple values for the same key). 070 * 071 * @return true if duplicate keys are enabled, false otherwise 072 */ 073 boolean isDupsEnabled(); 074 075 076 // ------------------------------------------------------------------------ 077 // Simple Table Key/Value Assertions 078 // ------------------------------------------------------------------------ 079 080 /** 081 * Checks to see if this table has one or more tuples with a specific key: 082 * this is exactly the same as a get call with a check to see if the 083 * returned value is null or not. 084 * 085 * @param transaction The transaction we are running in 086 * @param key the Object of the key to check for 087 * @return true if the key exists, false otherwise 088 * @throws LdapException if there is a failure to read the underlying Db 089 */ 090 boolean has( PartitionTxn transaction, K key ) throws LdapException; 091 092 093 /** 094 * Checks to see if this table has a key with a specific value. 095 * 096 * @param transaction The transaction we are running in 097 * @param key the key to check for 098 * @param value the value to check for 099 * @return true if a record with the key and value exists, false otherwise 100 * @throws LdapException if there is a failure to read the underlying Db 101 */ 102 boolean has( PartitionTxn transaction, K key, V value ) throws LdapException; 103 104 105 /** 106 * Checks to see if this table has a record with a key greater than or 107 * equal to the key argument. The key argument need not exist for this 108 * call to return true. The underlying database must sort keys based on a 109 * key comparator because this method depends on key ordering. 110 * 111 * @param transaction The transaction we are running in 112 * @param key the key to compare keys to 113 * @return true if a Tuple with a key greater than or equal to the key 114 * argument exists, false otherwise 115 * @throws LdapException if there is a failure to read the underlying Db 116 */ 117 boolean hasGreaterOrEqual( PartitionTxn transaction, K key ) throws LdapException; 118 119 120 /** 121 * Checks to see if this table has a record with a key less than or 122 * equal to the key argument. The key argument need not exist for this 123 * call to return true. The underlying database must sort keys based on a 124 * key comparator because this method depends on key ordering. 125 * 126 * @param transaction The transaction we are running in 127 * @param key the key to compare keys to 128 * @return true if a Tuple with a key less than or equal to the key 129 * argument exists, false otherwise 130 * @throws LdapException if there is a failure to read the underlying Db 131 */ 132 boolean hasLessOrEqual( PartitionTxn transaction, K key ) throws LdapException; 133 134 135 /** 136 * Checks to see if this table has a Tuple with a key equal to the key 137 * argument, yet with a value greater than or equal to the value argument 138 * provided. The key argument <strong>MUST</strong> exist for this call 139 * to return true and the underlying Db must allow for values of duplicate 140 * keys to be sorted. The entire basis to this method depends on the fact 141 * that tuples of the same key have values sorted according to a valid 142 * value comparator. 143 * 144 * If the table does not support duplicates then an 145 * UnsupportedOperationException is thrown. 146 * 147 * @param transaction The transaction we are running in 148 * @param key the key 149 * @param val the value to compare values to 150 * @return true if a Tuple with a key equal to the key argument and a 151 * value greater than the value argument exists, false otherwise 152 * @throws LdapException if there is a failure to read the underlying Db 153 * or if the underlying Db is not of the Btree type that allows sorted 154 * duplicate values. 155 */ 156 boolean hasGreaterOrEqual( PartitionTxn transaction, K key, V val ) throws LdapException; 157 158 159 /** 160 * Checks to see if this table has a Tuple with a key equal to the key 161 * argument, yet with a value less than or equal to the value argument 162 * provided. The key argument <strong>MUST</strong> exist for this call 163 * to return true and the underlying Db must allow for values of duplicate 164 * keys to be sorted. The entire basis to this method depends on the fact 165 * that tuples of the same key have values sorted according to a valid 166 * value comparator. 167 * 168 * If the table does not support duplicates then an 169 * UnsupportedOperationException is thrown. 170 * 171 * @param transaction The transaction we are running in 172 * @param key the key 173 * @param val the value to compare values to 174 * @return true if a Tuple with a key equal to the key argument and a 175 * value less than the value argument exists, false otherwise 176 * @throws LdapException if there is a failure to read the underlying Db 177 * or if the underlying Db is not of the Btree type that allows sorted 178 * duplicate values. 179 */ 180 boolean hasLessOrEqual( PartitionTxn transaction, K key, V val ) throws LdapException; 181 182 183 // ------------------------------------------------------------------------ 184 // Table Value Accessors/Mutators 185 // ------------------------------------------------------------------------ 186 187 /** 188 * Gets the value of a record by key if the key exists. If this Table 189 * allows duplicate keys then the first key will be returned. If this 190 * Table sorts keys then the key will be the smallest key in the Table as 191 * specified by this Table's comparator or the default byte-wise lexical 192 * comparator. 193 * 194 * @param transaction The transaction we are running in 195 * @param key the key of the record 196 * @return the value of the record with the specified key if key exists or 197 * null if no such key exists. 198 * @throws LdapException if there is a failure to read the underlying Db 199 */ 200 V get( PartitionTxn transaction, K key ) throws LdapException; 201 202 203 /** 204 * Puts a record into this Table. Null is not allowed for keys or values 205 * and should result in an IllegalArgumentException. 206 * 207 * @param writeTransaction The transaction we are running in 208 * @param key the key of the record 209 * @param value the value of the record. 210 * @throws LdapException if there is a failure to read or write to the 211 * underlying Db 212 * @throws IllegalArgumentException if a null key or value is used 213 */ 214 void put( PartitionTxn writeTransaction, K key, V value ) throws LdapException; 215 216 217 /** 218 * Removes all records with a specified key from this Table. 219 * 220 * @param writeTransaction The transaction we are running in 221 * @param key the key of the records to remove 222 * @throws LdapException if there is a failure to read or write to 223 * the underlying Db 224 */ 225 void remove( PartitionTxn writeTransaction, K key ) throws LdapException; 226 227 228 /** 229 * Removes a single key value pair with a specified key and value from 230 * this Table. 231 * 232 * @param writeTransaction The transaction we are running in 233 * @param key the key of the record to remove 234 * @param value the value of the record to remove 235 * @throws LdapException if there is a failure to read or write to 236 * the underlying Db 237 */ 238 void remove( PartitionTxn writeTransaction, K key, V value ) throws LdapException; 239 240 241 /** 242 * Creates a Cursor that traverses Tuples in a Table. 243 * 244 * @return a Cursor over Tuples containing the key value pairs 245 */ 246 Cursor<Tuple<K, V>> cursor(); 247 248 249 /** 250 * Creates a Cursor that traverses Table Tuples for the same key. Only 251 * Tuples with the provided key will be returned if the key exists at 252 * all. If the key does not exist an empty Cursor is returned. The 253 * motivation behind this method is to minimize the need for callers to 254 * actively constrain Cursor operations based on the Tuples they return 255 * to a specific key. This Cursor is naturally limited to return only 256 * the tuples for the same key. 257 * 258 * @param partitionTxn The transaction we are running in 259 * @param key the duplicate key to return the Tuples of 260 * @return a Cursor over Tuples containing the same key 261 * @throws LdapException if there are failures accessing underlying stores 262 */ 263 Cursor<Tuple<K, V>> cursor( PartitionTxn partitionTxn, K key ) throws LdapException; 264 265 266 /** 267 * Creates a Cursor that traverses Table values for the same key. Only 268 * Tuples with the provided key will have their values returned if the key 269 * exists at all. If the key does not exist an empty Cursor is returned. 270 * The motivation behind this method is to minimize the need for callers 271 * to actively constrain Cursor operations to a specific key while 272 * removing overheads in creating new Tuples or population one that is 273 * reused to return key value pairs. This Cursor is naturally limited to 274 * return only the values for the same key. 275 * 276 * @param transaction The transaction we are running in 277 * @param key the duplicate key to return the values of 278 * @return a Cursor over values of a key 279 * @throws LdapException if there are failures accessing underlying stores 280 */ 281 Cursor<V> valueCursor( PartitionTxn transaction, K key ) throws LdapException; 282 283 284 // ------------------------------------------------------------------------ 285 // Table Record Count Methods 286 // ------------------------------------------------------------------------ 287 288 /** 289 * Gets the count of the number of Tuples in this Table. 290 * 291 * @param transaction The transaction we are running in 292 * @return the number of records 293 * @throws LdapException if there is a failure to read the underlying Db 294 */ 295 long count( PartitionTxn transaction ) throws LdapException; 296 297 298 /** 299 * Gets the count of the number of records in this Table with a specific 300 * key: returns the number of duplicates for a key. 301 * 302 * @param transaction The transaction we are running in 303 * @param key the Object key to count. 304 * @return the number of duplicate records for a key. 305 * @throws LdapException if there is a failure to read the underlying Db 306 */ 307 long count( PartitionTxn transaction, K key ) throws LdapException; 308 309 310 /** 311 * Gets the number of records greater than or equal to a key value. The 312 * specific key argument provided need not exist for this call to return 313 * a non-zero value. 314 * 315 * @param transaction The transaction we are running in 316 * @param key the key to use in comparisons 317 * @return the number of keys greater than or equal to the key 318 * @throws LdapException if there is a failure to read the underlying db 319 */ 320 long greaterThanCount( PartitionTxn transaction, K key ) throws LdapException; 321 322 323 /** 324 * Gets the number of records less than or equal to a key value. The 325 * specific key argument provided need not exist for this call to return 326 * a non-zero value. 327 * 328 * @param transaction The transaction we are running in 329 * @param key the key to use in comparisons 330 * @return the number of keys less than or equal to the key 331 * @throws LdapException if there is a failure to read the underlying db 332 */ 333 long lessThanCount( PartitionTxn transaction, K key ) throws LdapException; 334 335 336 /** 337 * Closes the underlying Db of this Table. 338 * 339 * @param transaction The transaction we are running in 340 * @throws LdapException on any failures 341 */ 342 void close( PartitionTxn transaction ) throws LdapException; 343}