View Javadoc
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 }