Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/derby/impl/store/access/btree/BranchRow.java


1   /*
2   
3      Derby - Class org.apache.derby.impl.store.access.btree.BranchRow
4   
5      Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6   
7      Licensed under the Apache License, Version 2.0 (the "License");
8      you may not use this file except in compliance with the License.
9      You may obtain a copy of the License at
10  
11        http://www.apache.org/licenses/LICENSE-2.0
12  
13     Unless required by applicable law or agreed to in writing, software
14     distributed under the License is distributed on an "AS IS" BASIS,
15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16     See the License for the specific language governing permissions and
17     limitations under the License.
18  
19   */
20  
21  package org.apache.derby.impl.store.access.btree;
22  
23  import org.apache.derby.iapi.services.sanity.SanityManager;
24  import org.apache.derby.iapi.services.io.Storable;
25  
26  import org.apache.derby.iapi.error.StandardException;
27  
28  import org.apache.derby.iapi.store.access.RowUtil;
29  
30  import org.apache.derby.iapi.store.raw.ContainerHandle;
31  
32  import org.apache.derby.iapi.types.DataValueDescriptor;
33  
34  import org.apache.derby.iapi.types.SQLLongint;
35  import org.apache.derby.iapi.services.io.FormatableBitSet;
36  
37  
38  /**
39   * Implements row which is stored in the branch pages of a btree.  A non-suffix
40   * compressed branch row contains all of the columns of the leaf rows of a btree
41   * and contains an additional field at the end.  The extra field of a branch row
42   * in a branch page at level N, is the child page field pointing the page at 
43   * level N-1 which has keys which follow or equal the branch row entry.
44   *
45   * There are 3 ways to use this class to produce a branch row:
46   *   createEmptyTemplate() 
47   *      creates a empty row template
48   *   createBranchRowFromOldBranchRow() 
49   *      creates a new row with reference to an old branch row.
50   *   createBranchRowFromOldLeafRow()
51   *      creates a new row with reference to an old leaf row.
52   */
53  
54  public class BranchRow
55  {
56      /* a dummy page number value (should not be compressable) */
57      public static final long DUMMY_PAGE_NUMBER = 0xffffffffffffffffL;
58  
59      /**
60       * The branch child page pointer.  All keys that Follow or equal the
61       * key in this row can be found by following the child page pointer.
62       * A reference to this object will be placed in the last slot of branchrow,
63       * and this class expects that no-one will replace that reference.
64       */
65      // private SQLLongint      child_page = null;
66  
67      /**
68       * The array of object to be used as the row.
69       */
70      private DataValueDescriptor[]    branchrow    = null;
71  
72    /*
73    ** Constructors of BranchRow
74    */
75  
76      /**
77      Constuctor for creating an "empty" BranchRow template, suitable for reading
78      in a branchRow from disk.
79      **/
80    private BranchRow()
81    {
82    }
83  
84    private BranchRow(BTree btree)
85          throws StandardException
86    {
87          SQLLongint child_page  = 
88              new SQLLongint(ContainerHandle.INVALID_PAGE_NUMBER);
89  
90          branchrow   = btree.createBranchTemplate(child_page);
91  
92          if (SanityManager.DEBUG)
93          {
94              SanityManager.ASSERT(
95                  child_page == ((SQLLongint) branchrow[branchrow.length - 1]));
96          }
97    }
98  
99      /*
100     ** The following methods implement the BranchRow Private interface.
101     */
102 
103     /**
104      * Accessor for the child page field of the branch row.
105      *
106    * @return The child page object.
107      **/
108     private SQLLongint getChildPage()
109     {
110         // last column of branch row should be the child page pointer.
111         if (SanityManager.DEBUG)
112         {
113             SanityManager.ASSERT(branchrow != null);
114             SanityManager.ASSERT(
115                 branchrow[branchrow.length - 1] instanceof SQLLongint);
116         }
117 
118         return((SQLLongint) branchrow[branchrow.length - 1]);
119     }
120 
121     /*
122     ** The following methods implement the BranchRow Public interface.
123     */
124 
125     /**
126      * Create an empty branch row template suitable for reading branch rows in
127      * from disk. This routine will create newly allocated "empty" objects for
128      * every column in the template row.
129      *
130      * @exception StandardException Standard exception policy.
131      */
132     public static BranchRow createEmptyTemplate(BTree   btree)
133         throws StandardException
134     {
135         BranchRow  newbranch   = new BranchRow(btree);
136 
137         return(new BranchRow(btree));
138     }
139 
140     /**
141      * Create a new branch row, given a old branch row and a new child page.
142      * Used by BranchControlRow to manufacture new branch rows when splitting
143      * or growing the tree.
144      *
145      * There is no way to "copy" values of a template row, so this class just
146      * stores a reference to each of the columns of the Indexable row passed 
147      * in.  This is ok as all
148      * usages of this class when instantiated this way, have an old branch row
149      * from which they are creating a new branch row with the same key values,
150      * and a different child page number.
151      *
152      * WARNING - this branch row is only valid while the old branch row is
153      * valid, as it contains references to the columns of the old branch row.
154      * So use of the row should only provide read-only access to the objects
155      * of the old branch row which are referenced.
156      */
157     public BranchRow createBranchRowFromOldBranchRow(long childpageno)
158     {
159         BranchRow newbranch = new BranchRow();
160 
161         /* create new object array, and shallow copy all object references 
162          * from old branch row to new branch row.
163          */
164 
165         newbranch.branchrow = new DataValueDescriptor[this.branchrow.length]; 
166         System.arraycopy(
167             this.branchrow, 0, newbranch.branchrow, 0, 
168             newbranch.branchrow.length - 1);
169 
170         /* now create a different child page pointer object and place it as
171          * last column in the new branch row.
172          */
173         newbranch.branchrow[newbranch.branchrow.length - 1] = 
174             new SQLLongint(childpageno);
175 
176         return(newbranch);
177     }
178 
179     /**
180      * Create a new branch row, given a old leaf row and a new child page.
181      * Used by LeafControlRow to manufacture new branch rows when splitting
182      * or growing the tree.
183      *
184      * There is no way to "copy" values of a template row, so this class just
185      * stores a referece to the Indexable row passed in.  This is ok as all
186      * usages of this class when instantiated this way, have an old leaf row
187      * from which they are creating a new branch row with the same key values,
188      * and a different child page number.
189      *
190      * WARNING - this branch row is only valid while the old leaf row is
191      * valid, as it contains references to the columns of the old leaf row.
192      * So use of the row should only provide read-only access to the objects
193      * of the old leaf row which are referenced.
194      */
195     public static BranchRow createBranchRowFromOldLeafRow(
196     DataValueDescriptor[]   leafrow, 
197     long                    childpageno)
198     {
199         BranchRow newbranch = new BranchRow();
200 
201         /* create new object array for the row, and copy all object references 
202          * from old leaf row to new branch row.
203          */
204         newbranch.branchrow = new DataValueDescriptor[leafrow.length + 1];
205 
206         System.arraycopy(leafrow, 0, newbranch.branchrow, 0, leafrow.length);
207 
208         /* now create a different child page pointer object and place it as
209          * last column in the new branch row.
210          */
211         newbranch.branchrow[newbranch.branchrow.length - 1] = 
212             new SQLLongint(childpageno);
213 
214         return(newbranch);
215     }
216 
217     /**
218      * Return the branch row.
219      * <p>
220      * Return the DataValueDescriptor array that represents the branch row, 
221      * for use in raw store calls to fetch, insert, and update.
222      * <p>
223      *
224    * @return The branch row object array.
225      **/
226     protected DataValueDescriptor[] getRow()
227     {
228         return(this.branchrow);
229     }
230 
231     /**
232      * Set the page number field of the branch row to a new value.
233      *
234      * @param page_number the new page number.
235      **/
236     protected void setPageNumber(long page_number)
237     {
238         getChildPage().setValue(page_number);
239     }
240 
241 
242   public String toString()
243   {
244         if (SanityManager.DEBUG)
245         {
246             return(
247                 RowUtil.toString(branchrow) + 
248                 "child page: (" + getChildPage() + ")");
249         }
250         else
251         {
252             return(null);
253         }
254   }
255 }