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}