1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: SequenceConfig.java,v 12.7 2008/01/17 05:04:53 mjc Exp $ 7 */ 8 9package com.sleepycat.db; 10 11import com.sleepycat.db.internal.Db; 12import com.sleepycat.db.internal.DbConstants; 13import com.sleepycat.db.internal.DbSequence; 14import com.sleepycat.db.internal.DbTxn; 15 16/** 17Specify the attributes of a sequence. 18*/ 19public class SequenceConfig implements Cloneable { 20 /* 21 * For internal use, final to allow null as a valid value for 22 * the config parameter. 23 */ 24 /** 25 Default configuration used if null is passed to methods that create a 26 cursor. 27 */ 28 public static final SequenceConfig DEFAULT = new SequenceConfig(); 29 30 /* package */ 31 static SequenceConfig checkNull(SequenceConfig config) { 32 return (config == null) ? DEFAULT : config; 33 } 34 35 /* Parameters */ 36 private int cacheSize = 0; 37 private long rangeMin = Long.MIN_VALUE; 38 private long rangeMax = Long.MAX_VALUE; 39 private long initialValue = 0L; 40 41 /* Flags */ 42 private boolean allowCreate = false; 43 private boolean decrement = false; 44 private boolean exclusiveCreate = false; 45 private boolean autoCommitNoSync = false; 46 private boolean wrap = false; 47 48 /** 49 An instance created using the default constructor is initialized with 50 the system's default settings. 51 */ 52 public SequenceConfig() { 53 } 54 55 /** 56Configure the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method to 57 create the sequence if it does not already exist. 58<p> 59This method may be called at any time during the life of the application. 60<p> 61@param allowCreate 62If true, 63configure the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method to 64 create the sequence if it does not already exist. 65 */ 66 public void setAllowCreate(final boolean allowCreate) { 67 this.allowCreate = allowCreate; 68 } 69 70 /** 71Return true if the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method is configured 72 to create the sequence if it does not already exist. 73<p> 74This method may be called at any time during the life of the application. 75<p> 76@return 77True if the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method is configured 78 to create the sequence if it does not already exist. 79 */ 80 public boolean getAllowCreate() { 81 return allowCreate; 82 } 83 84 /** 85Set the 86Configure the number of elements cached by a sequence handle. 87<p> 88This method may be called at any time during the life of the application. 89<p> 90@param cacheSize 91The Configure the number of elements cached by a sequence handle. 92 */ 93 public void setCacheSize(final int cacheSize) { 94 this.cacheSize = cacheSize; 95 } 96 97 /** 98Return the number of elements cached by a sequence handle.. 99<p> 100This method may be called at any time during the life of the application. 101<p> 102@return 103The number of elements cached by a sequence handle.. 104 */ 105 public int getCacheSize() { 106 return cacheSize; 107 } 108 109 /** 110Specify that the sequence should be decremented. 111<p> 112This method may be called at any time during the life of the application. 113<p> 114@param decrement 115If true, 116specify that the sequence should be decremented. 117 */ 118 public void setDecrement(boolean decrement) { 119 this.decrement = decrement; 120 } 121 122 /** 123Return true if the sequence is configured to decrement. 124<p> 125This method may be called at any time during the life of the application. 126<p> 127@return 128True if the sequence is configured to decrement. 129 */ 130 public boolean getDecrement() { 131 return decrement; 132 } 133 134 /** 135Configure the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method to 136 fail if the database already exists. 137<p> 138This method may be called at any time during the life of the application. 139<p> 140@param exclusiveCreate 141If true, 142configure the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method to 143 fail if the database already exists. 144 */ 145 public void setExclusiveCreate(final boolean exclusiveCreate) { 146 this.exclusiveCreate = exclusiveCreate; 147 } 148 149 /** 150Return true if the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method is configured to 151 fail if the database already exists. 152<p> 153This method may be called at any time during the life of the application. 154<p> 155@return 156True if the {@link com.sleepycat.db.Database#openSequence Database.openSequence} method is configured to 157 fail if the database already exists. 158 */ 159 public boolean getExclusiveCreate() { 160 return exclusiveCreate; 161 } 162 163 /** 164Set the 165Set the initial value for a sequence. 166<p>This call is only 167 effective when the sequence is being created. 168<p> 169This method may be called at any time during the life of the application. 170<p> 171@param initialValue 172The Set the initial value for a sequence. 173 */ 174 public void setInitialValue(long initialValue) { 175 this.initialValue = initialValue; 176 } 177 178 /** 179Return the initial value for a sequence.. 180<p> 181This method may be called at any time during the life of the application. 182<p> 183@return 184The initial value for a sequence.. 185 */ 186 public long getInitialValue() { 187 return initialValue; 188 } 189 190 /** 191Configure auto-commit operations on the sequence to not flush 192 the transaction log. 193<p> 194This method may be called at any time during the life of the application. 195<p> 196@param autoCommitNoSync 197If true, 198configure auto-commit operations on the sequence to not flush 199 the transaction log. 200 */ 201 public void setAutoCommitNoSync(final boolean autoCommitNoSync) { 202 this.autoCommitNoSync = autoCommitNoSync; 203 } 204 205 /** 206Return true if the auto-commit operations on the sequence are configure to not 207 flush the transaction log.. 208<p> 209This method may be called at any time during the life of the application. 210<p> 211@return 212True if the auto-commit operations on the sequence are configure to not 213 flush the transaction log.. 214 */ 215 public boolean getAutoCommitNoSync() { 216 return autoCommitNoSync; 217 } 218 219 /** 220 Configure a sequence range. This call is only effective when the 221 sequence is being created. 222 <p> 223 @param min 224 The minimum value for the sequence. 225 @param max 226 The maximum value for the sequence. 227 */ 228 public void setRange(final long min, final long max) { 229 this.rangeMin = min; 230 this.rangeMax = max; 231 } 232 233 /** 234Return the minimum value for the sequence. 235<p> 236This method may be called at any time during the life of the application. 237<p> 238@return 239The minimum value for the sequence. 240 */ 241 public long getRangeMin() { 242 return rangeMin; 243 } 244 245 /** 246Return the maximum value for the sequence. 247<p> 248This method may be called at any time during the life of the application. 249<p> 250@return 251The maximum value for the sequence. 252 */ 253 public long getRangeMax() { 254 return rangeMax; 255 } 256 257 /** 258Specify that the sequence should wrap around when it is 259 incremented (decremented) past the specified maximum (minimum) value. 260<p> 261This method may be called at any time during the life of the application. 262<p> 263@param wrap 264If true, 265specify that the sequence should wrap around when it is 266 incremented (decremented) past the specified maximum (minimum) value. 267 */ 268 public void setWrap(final boolean wrap) { 269 this.wrap = wrap; 270 } 271 272 /** 273Return true if the sequence will wrap around when it is incremented 274 (decremented) past the specified maximum (minimum) value. 275<p> 276This method may be called at any time during the life of the application. 277<p> 278@return 279True if the sequence will wrap around when it is incremented 280 (decremented) past the specified maximum (minimum) value. 281 */ 282 public boolean getWrap() { 283 return wrap; 284 } 285 286 /* package */ 287 DbSequence createSequence(final Db db) 288 throws DatabaseException { 289 290 int createFlags = 0; 291 292 return new DbSequence(db, createFlags); 293 } 294 295 /* package */ 296 DbSequence openSequence(final Db db, 297 final DbTxn txn, 298 final DatabaseEntry key) 299 throws DatabaseException { 300 301 final DbSequence seq = createSequence(db); 302 // The DB_THREAD flag is inherited from the database 303 boolean threaded = ((db.get_open_flags() & DbConstants.DB_THREAD) != 0); 304 305 int openFlags = 0; 306 openFlags |= allowCreate ? DbConstants.DB_CREATE : 0; 307 openFlags |= exclusiveCreate ? DbConstants.DB_EXCL : 0; 308 openFlags |= threaded ? DbConstants.DB_THREAD : 0; 309 310 if (db.get_transactional() && txn == null) 311 openFlags |= DbConstants.DB_AUTO_COMMIT; 312 313 configureSequence(seq, DEFAULT); 314 boolean succeeded = false; 315 try { 316 seq.open(txn, key, openFlags); 317 succeeded = true; 318 return seq; 319 } finally { 320 if (!succeeded) 321 try { 322 seq.close(0); 323 } catch (Throwable t) { 324 // Ignore it -- an exception is already in flight. 325 } 326 } 327 } 328 329 /* package */ 330 void configureSequence(final DbSequence seq, final SequenceConfig oldConfig) 331 throws DatabaseException { 332 333 int seqFlags = 0; 334 seqFlags |= decrement ? DbConstants.DB_SEQ_DEC : DbConstants.DB_SEQ_INC; 335 seqFlags |= wrap ? DbConstants.DB_SEQ_WRAP : 0; 336 337 if (seqFlags != 0) 338 seq.set_flags(seqFlags); 339 340 if (rangeMin != oldConfig.rangeMin || rangeMax != oldConfig.rangeMax) 341 seq.set_range(rangeMin, rangeMax); 342 343 if (initialValue != oldConfig.initialValue) 344 seq.initial_value(initialValue); 345 346 if (cacheSize != oldConfig.cacheSize) 347 seq.set_cachesize(cacheSize); 348 } 349 350 /* package */ 351 SequenceConfig(final DbSequence seq) 352 throws DatabaseException { 353 354 // XXX: can't get open flags 355 final int openFlags = 0; 356 allowCreate = (openFlags & DbConstants.DB_CREATE) != 0; 357 exclusiveCreate = (openFlags & DbConstants.DB_EXCL) != 0; 358 359 final int seqFlags = seq.get_flags(); 360 decrement = (seqFlags & DbConstants.DB_SEQ_DEC) != 0; 361 wrap = (seqFlags & DbConstants.DB_SEQ_WRAP) != 0; 362 363 // XXX: can't get initial value 364 final long initialValue = 0; 365 366 cacheSize = seq.get_cachesize(); 367 368 rangeMin = seq.get_range_min(); 369 rangeMax = seq.get_range_max(); 370 } 371} 372