1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 package com.sleepycat.collections; 9 10 import java.util.Set; 11 12 import com.sleepycat.bind.EntityBinding; 13 import com.sleepycat.bind.EntryBinding; 14 import com.sleepycat.je.Database; 15 import com.sleepycat.je.DatabaseEntry; 16 /* <!-- begin JE only --> */ 17 import com.sleepycat.je.EnvironmentFailureException; // for javadoc 18 import com.sleepycat.je.OperationFailureException; // for javadoc 19 /* <!-- end JE only --> */ 20 import com.sleepycat.je.OperationStatus; 21 import com.sleepycat.util.RuntimeExceptionWrapper; 22 23 /** 24 * The Set returned by Map.values() and Map.duplicates(), and which can also be 25 * constructed directly if a Map is not needed. 26 * Although this collection is a set it may contain duplicate values. Only if 27 * an entity value binding is used are all elements guaranteed to be unique. 28 * 29 * @author Mark Hayes 30 */ 31 public class StoredValueSet<E> extends StoredCollection<E> implements Set<E> { 32 33 /* 34 * This class is also used internally for the set returned by duplicates(). 35 */ 36 37 /** 38 * Creates a value set view of a {@link Database}. 39 * 40 * @param database is the Database underlying the new collection. 41 * 42 * @param valueBinding is the binding used to translate between value 43 * buffers and value objects. 44 * 45 * @param writeAllowed is true to create a read-write collection or false 46 * to create a read-only collection. 47 * 48 * @throws IllegalArgumentException if formats are not consistently 49 * defined or a parameter is invalid. 50 * 51 * @throws RuntimeExceptionWrapper if a checked exception is thrown, 52 * including a {@code DatabaseException} on BDB (C Edition). 53 */ StoredValueSet(Database database, EntryBinding<E> valueBinding, boolean writeAllowed)54 public StoredValueSet(Database database, 55 EntryBinding<E> valueBinding, 56 boolean writeAllowed) { 57 58 super(new DataView(database, null, valueBinding, null, 59 writeAllowed, null)); 60 } 61 62 /** 63 * Creates a value set entity view of a {@link Database}. 64 * 65 * @param database is the Database underlying the new collection. 66 * 67 * @param valueEntityBinding is the binding used to translate between 68 * key/value buffers and entity value objects. 69 * 70 * @param writeAllowed is true to create a read-write collection or false 71 * to create a read-only collection. 72 * 73 * @throws IllegalArgumentException if formats are not consistently 74 * defined or a parameter is invalid. 75 * 76 * @throws RuntimeExceptionWrapper if a checked exception is thrown, 77 * including a {@code DatabaseException} on BDB (C Edition). 78 */ StoredValueSet(Database database, EntityBinding<E> valueEntityBinding, boolean writeAllowed)79 public StoredValueSet(Database database, 80 EntityBinding<E> valueEntityBinding, 81 boolean writeAllowed) { 82 83 super(new DataView(database, null, null, valueEntityBinding, 84 writeAllowed, null)); 85 } 86 StoredValueSet(DataView valueSetView)87 StoredValueSet(DataView valueSetView) { 88 89 super(valueSetView); 90 } 91 92 /** 93 * Adds the specified entity to this set if it is not already present 94 * (optional operation). 95 * This method conforms to the {@link Set#add} interface. 96 * 97 * @param entity is the entity to be added. 98 * 99 * @return true if the entity was added, that is the key-value pair 100 * represented by the entity was not previously present in the collection. 101 * 102 * <!-- begin JE only --> 103 * @throws OperationFailureException if one of the <a 104 * href="../je/OperationFailureException.html#writeFailures">Write 105 * Operation Failures</a> occurs. 106 * 107 * @throws EnvironmentFailureException if an unexpected, internal or 108 * environment-wide failure occurs. 109 * <!-- end JE only --> 110 * 111 * @throws UnsupportedOperationException if the collection is read-only, 112 * if the collection is indexed, or if an entity binding is not used. 113 * 114 * @throws RuntimeExceptionWrapper if a checked exception is thrown, 115 * including a {@code DatabaseException} on BDB (C Edition). 116 */ add(E entity)117 public boolean add(E entity) { 118 119 if (view.isSecondary()) { 120 throw new UnsupportedOperationException 121 ("Add not allowed with index"); 122 } else if (view.range.isSingleKey()) { 123 /* entity is actually just a value in this case */ 124 if (!view.dupsAllowed) { 125 throw new UnsupportedOperationException("Duplicates required"); 126 } 127 DataCursor cursor = null; 128 boolean doAutoCommit = beginAutoCommit(); 129 try { 130 cursor = new DataCursor(view, true); 131 cursor.useRangeKey(); 132 OperationStatus status = 133 cursor.putNoDupData(null, entity, null, true); 134 closeCursor(cursor); 135 commitAutoCommit(doAutoCommit); 136 return (status == OperationStatus.SUCCESS); 137 } catch (Exception e) { 138 closeCursor(cursor); 139 throw handleException(e, doAutoCommit); 140 } 141 } else if (view.entityBinding == null) { 142 throw new UnsupportedOperationException 143 ("Add requires entity binding"); 144 } else { 145 return add(null, entity); 146 } 147 } 148 149 /** 150 * Returns true if this set contains the specified element. 151 * This method conforms to the {@link java.util.Set#contains} 152 * interface. 153 * 154 * @param value the value to check. 155 * 156 * @return whether the set contains the given value. 157 * 158 * <!-- begin JE only --> 159 * @throws OperationFailureException if one of the <a 160 * href="../je/OperationFailureException.html#readFailures">Read Operation 161 * Failures</a> occurs. 162 * 163 * @throws EnvironmentFailureException if an unexpected, internal or 164 * environment-wide failure occurs. 165 * <!-- end JE only --> 166 * 167 * @throws RuntimeExceptionWrapper if a checked exception is thrown, 168 * including a {@code DatabaseException} on BDB (C Edition). 169 */ contains(Object value)170 public boolean contains(Object value) { 171 172 return containsValue(value); 173 } 174 175 /** 176 * Removes the specified value from this set if it is present (optional 177 * operation). 178 * If an entity binding is used, the key-value pair represented by the 179 * given entity is removed. If an entity binding is used, the first 180 * occurrence of a key-value pair with the given value is removed. 181 * This method conforms to the {@link Set#remove} interface. 182 * 183 * <!-- begin JE only --> 184 * @throws OperationFailureException if one of the <a 185 * href="../je/OperationFailureException.html#writeFailures">Write 186 * Operation Failures</a> occurs. 187 * 188 * @throws EnvironmentFailureException if an unexpected, internal or 189 * environment-wide failure occurs. 190 * <!-- end JE only --> 191 * 192 * @throws UnsupportedOperationException if the collection is read-only. 193 * 194 * @throws RuntimeExceptionWrapper if a checked exception is thrown, 195 * including a {@code DatabaseException} on BDB (C Edition). 196 */ remove(Object value)197 public boolean remove(Object value) { 198 199 return removeValue(value); 200 } 201 makeIteratorData(BaseIterator iterator, DatabaseEntry keyEntry, DatabaseEntry priKeyEntry, DatabaseEntry valueEntry)202 E makeIteratorData(BaseIterator iterator, 203 DatabaseEntry keyEntry, 204 DatabaseEntry priKeyEntry, 205 DatabaseEntry valueEntry) { 206 207 return (E) view.makeValue(priKeyEntry, valueEntry); 208 } 209 hasValues()210 boolean hasValues() { 211 212 return true; 213 } 214 } 215