1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000,2008 Oracle.  All rights reserved.
5 *
6 * $Id: StoredKeySet.java,v 12.7 2008/01/08 20:58:36 bostic Exp $
7 */
8
9package com.sleepycat.collections;
10
11import java.util.Set;
12
13import com.sleepycat.bind.EntryBinding;
14import com.sleepycat.db.Database;
15import com.sleepycat.db.DatabaseEntry;
16import com.sleepycat.db.DatabaseException;
17import com.sleepycat.db.OperationStatus;
18
19/**
20 * The Set returned by Map.keySet() and which can also be constructed directly
21 * if a Map is not needed.
22 * Since this collection is a set it only contains one element for each key,
23 * even when duplicates are allowed.  Key set iterators are therefore
24 * particularly useful for enumerating the unique keys of a store or index that
25 * allows duplicates.
26 *
27 * @author Mark Hayes
28 */
29public class StoredKeySet extends StoredCollection implements Set {
30
31    /**
32     * Creates a key set view of a {@link Database}.
33     *
34     * @param database is the Database underlying the new collection.
35     *
36     * @param keyBinding is the binding used to translate between key buffers
37     * and key objects.
38     *
39     * @param writeAllowed is true to create a read-write collection or false
40     * to create a read-only collection.
41     *
42     * @throws IllegalArgumentException if formats are not consistently
43     * defined or a parameter is invalid.
44     *
45     * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is
46     * thrown.
47     */
48    public StoredKeySet(Database database, EntryBinding keyBinding,
49                        boolean writeAllowed) {
50
51        super(new DataView(database, keyBinding, null, null,
52                           writeAllowed, null));
53    }
54
55    StoredKeySet(DataView keySetView) {
56
57        super(keySetView);
58    }
59
60    /**
61     * Adds the specified key to this set if it is not already present
62     * (optional operation).
63     * When a key is added the value in the underlying data store will be
64     * empty.
65     * This method conforms to the {@link Set#add} interface.
66     *
67     * @throws UnsupportedOperationException if the collection is indexed, or
68     * if the collection is read-only.
69     *
70     * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is
71     * thrown.
72     */
73    public boolean add(Object key) {
74
75        DataCursor cursor = null;
76        boolean doAutoCommit = beginAutoCommit();
77        try {
78            cursor = new DataCursor(view, true);
79            OperationStatus status = cursor.putNoOverwrite(key, null, false);
80            closeCursor(cursor);
81            commitAutoCommit(doAutoCommit);
82            return (status == OperationStatus.SUCCESS);
83        } catch (Exception e) {
84            closeCursor(cursor);
85            throw handleException(e, doAutoCommit);
86        }
87    }
88
89    /**
90     * Removes the specified key from this set if it is present (optional
91     * operation).
92     * If duplicates are allowed, this method removes all duplicates for the
93     * given key.
94     * This method conforms to the {@link Set#remove} interface.
95     *
96     * @throws UnsupportedOperationException if the collection is read-only.
97     *
98     * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is
99     * thrown.
100     */
101    public boolean remove(Object key) {
102
103        return removeKey(key, null);
104    }
105
106    /**
107     * Returns true if this set contains the specified key.
108     * This method conforms to the {@link Set#contains} interface.
109     *
110     * @throws RuntimeExceptionWrapper if a {@link DatabaseException} is
111     * thrown.
112     */
113    public boolean contains(Object key) {
114
115        return containsKey(key);
116    }
117
118    boolean hasValues() {
119
120        return false;
121    }
122
123    Object makeIteratorData(BaseIterator iterator,
124                            DatabaseEntry keyEntry,
125                            DatabaseEntry priKeyEntry,
126                            DatabaseEntry valueEntry) {
127
128        return view.makeKey(keyEntry, priKeyEntry);
129    }
130
131    boolean iterateDuplicates() {
132
133        return false;
134    }
135}
136