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