summaryrefslogtreecommitdiff
path: root/lang/java/src/com/sleepycat/collections/StoredValueSet.java
blob: 99a93b715b81f93e33477f4f66c815a78443993e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 2000, 2015 Oracle and/or its affiliates.  All rights reserved.
 *
 */

package com.sleepycat.collections;

import java.util.Set;

import com.sleepycat.bind.EntityBinding;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.OperationStatus;
import com.sleepycat.util.RuntimeExceptionWrapper;

/**
 * The Set returned by Map.values() and Map.duplicates(), and which can also be
 * constructed directly if a Map is not needed.
 * Although this collection is a set it may contain duplicate values.  Only if
 * an entity value binding is used are all elements guaranteed to be unique.
 *
 * @author Mark Hayes
 */
public class StoredValueSet<E> extends StoredCollection<E> implements Set<E> {

    /*
     * This class is also used internally for the set returned by duplicates().
     */

    /**
     * Creates a value set view of a {@link Database}.
     *
     * @param database is the Database underlying the new collection.
     *
     * @param valueBinding is the binding used to translate between value
     * buffers and value objects.
     *
     * @param writeAllowed is true to create a read-write collection or false
     * to create a read-only collection.
     *
     * @throws IllegalArgumentException if formats are not consistently
     * defined or a parameter is invalid.
     *
     * @throws RuntimeExceptionWrapper if a checked exception is thrown,
     * including a {@code DatabaseException} on BDB (C Edition).
     */
    public StoredValueSet(Database database,
                          EntryBinding<E> valueBinding,
                          boolean writeAllowed) {

        super(new DataView(database, null, valueBinding, null,
                           writeAllowed, null));
    }

    /**
     * Creates a value set entity view of a {@link Database}.
     *
     * @param database is the Database underlying the new collection.
     *
     * @param valueEntityBinding is the binding used to translate between
     * key/value buffers and entity value objects.
     *
     * @param writeAllowed is true to create a read-write collection or false
     * to create a read-only collection.
     *
     * @throws IllegalArgumentException if formats are not consistently
     * defined or a parameter is invalid.
     *
     * @throws RuntimeExceptionWrapper if a checked exception is thrown,
     * including a {@code DatabaseException} on BDB (C Edition).
     */
    public StoredValueSet(Database database,
                          EntityBinding<E> valueEntityBinding,
                          boolean writeAllowed) {

        super(new DataView(database, null, null, valueEntityBinding,
                           writeAllowed, null));
    }

    StoredValueSet(DataView valueSetView) {

        super(valueSetView);
    }

    /**
     * Adds the specified entity to this set if it is not already present
     * (optional operation).
     * This method conforms to the {@link Set#add} interface.
     *
     * @param entity is the entity to be added.
     *
     * @return true if the entity was added, that is the key-value pair
     * represented by the entity was not previously present in the collection.
     *
     *
     * @throws UnsupportedOperationException if the collection is read-only,
     * if the collection is indexed, or if an entity binding is not used.
     *
     * @throws RuntimeExceptionWrapper if a checked exception is thrown,
     * including a {@code DatabaseException} on BDB (C Edition).
     */
    public boolean add(E entity) {

        if (view.isSecondary()) {
            throw new UnsupportedOperationException
                ("Add not allowed with index");
        } else if (view.range.isSingleKey()) {
            /* entity is actually just a value in this case */
            if (!view.dupsAllowed) {
                throw new UnsupportedOperationException("Duplicates required");
            }
            DataCursor cursor = null;
            boolean doAutoCommit = beginAutoCommit();
            try {
                cursor = new DataCursor(view, true);
                cursor.useRangeKey();
                OperationStatus status =
                    cursor.putNoDupData(null, entity, null, true);
                closeCursor(cursor);
                commitAutoCommit(doAutoCommit);
                return (status == OperationStatus.SUCCESS);
            } catch (Exception e) {
                closeCursor(cursor);
                throw handleException(e, doAutoCommit);
            }
        } else if (view.entityBinding == null) {
            throw new UnsupportedOperationException
                ("Add requires entity binding");
        } else {
            return add(null, entity);
        }
    }

    /**
     * Returns true if this set contains the specified element.
     * This method conforms to the {@link java.util.Set#contains}
     * interface.
     *
     * @param value the value to check.
     *
     * @return whether the set contains the given value.
     *
     *
     * @throws RuntimeExceptionWrapper if a checked exception is thrown,
     * including a {@code DatabaseException} on BDB (C Edition).
     */
    public boolean contains(Object value) {

        return containsValue(value);
    }

    /**
     * Removes the specified value from this set if it is present (optional
     * operation).
     * If an entity binding is used, the key-value pair represented by the
     * given entity is removed.  If an entity binding is used, the first
     * occurrence of a key-value pair with the given value is removed.
     * This method conforms to the {@link Set#remove} interface.
     *
     *
     * @throws UnsupportedOperationException if the collection is read-only.
     *
     * @throws RuntimeExceptionWrapper if a checked exception is thrown,
     * including a {@code DatabaseException} on BDB (C Edition).
     */
    public boolean remove(Object value) {

        return removeValue(value);
    }

    E makeIteratorData(BaseIterator iterator,
                       DatabaseEntry keyEntry,
                       DatabaseEntry priKeyEntry,
                       DatabaseEntry valueEntry) {

        return (E) view.makeValue(priKeyEntry, valueEntry);
    }

    boolean hasValues() {

        return true;
    }
}