1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 package org.apache.directory.mavibot.btree; 21 22 23 import java.util.Date; 24 import java.util.concurrent.ConcurrentLinkedQueue; 25 26 27 /** 28 * The Transaction is used to protect the BTree against concurrent modification, 29 * and insure that a read is always done against one single revision. It's also 30 * used to gather many modifications under one single revision, if needed. 31 * <p/> 32 * A Transaction should be closed when the user is done with it, otherwise the 33 * pages associated with the given revision, and all the referenced pages, will 34 * remain on the storage. 35 * <p/> 36 * A Transaction can be hold for quite a long time, for instance while doing 37 * a browse against a big BTree. At some point, transactions which are pending 38 * for too long will be closed by the transaction manager. 39 * 40 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 41 * 42 * @param <K> The type for the Key 43 * @param <V> The type for the stored value 44 */ 45 public class ReadTransaction<K, V> 46 { 47 /** The associated revision */ 48 private long revision; 49 50 /** The date of creation */ 51 private long creationDate; 52 53 /** The associated B-tree header */ 54 private BTreeHeader<K, V> btreeHeader; 55 56 /** A flag used to tell if a transaction is closed or not */ 57 private volatile boolean closed; 58 59 /** The list of read transactions being executed */ 60 private ConcurrentLinkedQueue<ReadTransaction<K, V>> readTransactions; 61 62 /** The reference to the recordManager, if any */ 63 private RecordManager recordManager; 64 65 /** 66 * Creates a new transaction instance 67 * 68 * @param btreeHeader The BtreeHeader we will use for this read transaction 69 */ 70 public ReadTransaction( RecordManager recordManager, BTreeHeader<K, V> btreeHeader, ConcurrentLinkedQueue<ReadTransaction<K, V>> readTransactions ) 71 { 72 if ( btreeHeader != null ) 73 { 74 this.revision = btreeHeader.getRevision(); 75 this.creationDate = System.currentTimeMillis(); 76 this.btreeHeader = btreeHeader; 77 this.recordManager = recordManager; 78 closed = false; 79 } 80 81 this.readTransactions = readTransactions; 82 } 83 84 85 /** 86 * Creates a new transaction instance 87 * 88 * @param btreeHeader The BtreeHeader we will use for this read transaction 89 */ 90 public ReadTransaction( BTreeHeader<K, V> btreeHeader, ConcurrentLinkedQueue<ReadTransaction<K, V>> readTransactions ) 91 { 92 if ( btreeHeader != null ) 93 { 94 this.revision = btreeHeader.getRevision(); 95 this.creationDate = System.currentTimeMillis(); 96 this.btreeHeader = btreeHeader; 97 closed = false; 98 } 99 100 this.readTransactions = readTransactions; 101 } 102 103 104 /** 105 * @return the associated revision 106 */ 107 public long getRevision() 108 { 109 return revision; 110 } 111 112 113 /** 114 * @return the creationDate 115 */ 116 public long getCreationDate() 117 { 118 return creationDate; 119 } 120 121 122 /** 123 * @return the btreeHeader 124 */ 125 public BTreeHeader<K, V> getBtreeHeader() 126 { 127 return btreeHeader; 128 } 129 130 131 /** 132 * Close the transaction, releasing the revision it was using. 133 */ 134 public void close() 135 { 136 closed = true; 137 138 // Remove the transaction from the list of opened transactions 139 readTransactions.remove( this ); 140 141 // and push the 142 if ( recordManager != null ) 143 { 144 recordManager.releaseTransaction( this ); 145 } 146 147 // Now, get back the copied pages 148 } 149 150 151 /** 152 * @return true if this transaction has been closed 153 */ 154 public boolean isClosed() 155 { 156 return closed; 157 } 158 159 160 /** 161 * @see Object#toString() 162 */ 163 public String toString() 164 { 165 return "Transaction[" + revision + ":" + new Date( creationDate ) + ", closed :" + closed + "]"; 166 } 167 }