1 5 package com.tc.objectserver.persistence.sleepycat; 6 7 import com.sleepycat.je.Database; 8 import com.sleepycat.je.DatabaseEntry; 9 import com.sleepycat.je.LockMode; 10 import com.sleepycat.je.OperationStatus; 11 import com.tc.logging.TCLogger; 12 import com.tc.objectserver.persistence.api.PersistenceTransaction; 13 import com.tc.objectserver.persistence.api.PersistenceTransactionProvider; 14 import com.tc.objectserver.persistence.api.PersistentSequence; 15 import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor.SleepycatPersistorBase; 16 import com.tc.util.Conversion; 17 import com.tc.util.UUID; 18 19 class SleepycatSequence extends SleepycatPersistorBase implements PersistentSequence { 20 private static final String UID_KEY = "UIDKEY-3475674589230"; 21 private final long startValue; 22 private final DatabaseEntry key; 23 private final Database sequenceDB; 24 private final PersistenceTransactionProvider ptxp; 25 private final String uid; 26 27 SleepycatSequence(PersistenceTransactionProvider ptxp, TCLogger logger, long sequenceID, long startValue, 28 Database sequenceDB) { 29 this.ptxp = ptxp; 30 this.startValue = startValue; 31 this.sequenceDB = sequenceDB; 32 key = new DatabaseEntry(); 33 key.setData(Conversion.long2Bytes(sequenceID)); 34 this.uid = getOrCreateUID(); 35 } 36 37 private String getOrCreateUID() { 38 PersistenceTransaction tx = ptxp.newTransaction(); 39 String newuid; 40 try { 41 DatabaseEntry ukey = new DatabaseEntry(); 42 ukey.setData(Conversion.string2Bytes(UID_KEY)); 43 DatabaseEntry value = new DatabaseEntry(); 44 OperationStatus status = this.sequenceDB.get(pt2nt(tx), ukey, value, LockMode.DEFAULT); 45 46 if (OperationStatus.SUCCESS.equals(status)) { 47 newuid = Conversion.bytes2String(value.getData()); 48 } else if (OperationStatus.NOTFOUND.equals(status)) { 49 newuid = createUID(); 50 value.setData(Conversion.string2Bytes(newuid)); 51 status = this.sequenceDB.put(pt2nt(tx), ukey, value); 52 if (!OperationStatus.SUCCESS.equals(status)) { throw new DBException( 53 "Unable to store UID for SleepycatSequence: " 54 + newuid + "): " + status); } 55 } else { 56 throw new DBException("Unable to retrieve UID for SleepycatSequence: " + status); 57 } 58 tx.commit(); 59 return newuid; 60 } catch (Exception t) { 61 abortOnError(tx); 62 t.printStackTrace(); 63 throw (t instanceof DBException ? (DBException) t : new DBException(t)); 64 } 65 } 66 67 private String createUID() { 68 UUID uuid = UUID.getUUID(); 69 return uuid.toString(); 70 } 71 72 public synchronized long next() { 73 return nextBatch(1); 74 } 75 76 public synchronized long nextBatch(int batchSize) { 77 if (batchSize < 1) throw new AssertionError ("Can't increment by a value less than 1."); 78 PersistenceTransaction tx = ptxp.newTransaction(); 79 try { 80 DatabaseEntry value = new DatabaseEntry(); 81 long currentValue = startValue; 82 OperationStatus status = this.sequenceDB.get(pt2nt(tx), key, value, LockMode.DEFAULT); 83 84 if (OperationStatus.SUCCESS.equals(status)) { 85 currentValue = Conversion.bytes2Long(value.getData()); 86 } else if (!OperationStatus.NOTFOUND.equals(status)) { 87 throw new DBException("Unable to retrieve current value: " + status); 89 } 90 91 value.setData(Conversion.long2Bytes(currentValue + batchSize)); 92 status = this.sequenceDB.put(pt2nt(tx), key, value); 93 if (!OperationStatus.SUCCESS.equals(status)) { throw new DBException("Unable to store current value: " 94 + (currentValue + batchSize) + "): " 95 + status); } 96 tx.commit(); 97 return currentValue; 98 } catch (Exception t) { 99 abortOnError(tx); 100 t.printStackTrace(); 101 throw (t instanceof DBException ? (DBException) t : new DBException(t)); 102 } 103 } 104 105 public String getUID() { 106 return uid; 107 } 108 109 public void setNext(long next) { 110 PersistenceTransaction tx = ptxp.newTransaction(); 111 try { 112 DatabaseEntry value = new DatabaseEntry(); 113 long currentValue = startValue; 114 OperationStatus status = this.sequenceDB.get(pt2nt(tx), key, value, LockMode.DEFAULT); 115 116 if (OperationStatus.SUCCESS.equals(status)) { 117 currentValue = Conversion.bytes2Long(value.getData()); 118 } else if (!OperationStatus.NOTFOUND.equals(status)) { 119 throw new DBException("Unable to retrieve current value: " + status); 121 } 122 123 if (currentValue > next) { 124 abortOnError(tx); 125 throw new AssertionError ("Cant setNext sequence to a value less than current: current = " + currentValue 126 + " next = " + next); 127 } 128 129 value.setData(Conversion.long2Bytes(next)); 130 status = this.sequenceDB.put(pt2nt(tx), key, value); 131 if (!OperationStatus.SUCCESS.equals(status)) { throw new DBException("Unable to store next value: " + (next) 132 + "): " + status); } 133 tx.commit(); 134 } catch (Exception t) { 135 abortOnError(tx); 136 t.printStackTrace(); 137 throw (t instanceof DBException ? (DBException) t : new DBException(t)); 138 } 139 } 140 } | Popular Tags |