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.nio.ByteBuffer;
24  
25  import org.apache.directory.mavibot.btree.util.Strings;
26  
27  
28  /**
29   * A structure containing a Page on disk. It's a byte[PageSize] plus a few more details like
30   * the page offset on disk and a link to the next page.</br>
31   * As we may need more than one Page to store some data, the PageIO are linked so that
32   * the list of all the PageIO contain the full data.</br>
33   * The first PageIO contains the size of the data.</br>
34   * Here is the logical structure of a PageIO :
35   * <pre>
36   * For a first page :
37   *
38   * +----------+------+----------------------+
39   * | nextPage | size | XXXXXXXXXXXXXXXXXXXX |
40   * +----------+------+----------------------+
41   *
42   * for any page but the first :
43   *
44   * +----------+-----------------------------+
45   * | nextPage | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
46   * +----------+-----------------------------+
47   *
48   * for the last page :
49   * +----------+-----------------------------+
50   * |    -1    | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
51   * +----------+-----------------------------+
52   *
53   * In any case, the page length is always PageSize.
54   * </pre>
55   *
56   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
57   */
58  /* No qualifier*/class PageIO
59  {
60      /** The contain data */
61      private ByteBuffer data;
62  
63      /** A pointer to the next pageIO */
64      private long nextPage;
65  
66      /** The offset on disk */
67      private int size;
68  
69      /** The position of the page on disk */
70      private long offset;
71  
72  
73      /**
74       * A default constructor for a PageIO
75       */
76      /* no qualifier */PageIO()
77      {
78          nextPage = -2L;
79          size = -1;
80          offset = -1L;
81      }
82  
83  
84      /**
85       * A constructor for a PageIO when we know the offset of this page on disk
86       */
87      /* no qualifier */PageIO( long offset )
88      {
89          nextPage = -2L;
90          size = -1;
91          this.offset = offset;
92      }
93  
94  
95      /**
96       * @return the data
97       */
98      /* no qualifier */ByteBuffer getData()
99      {
100         return data;
101     }
102 
103 
104     /**
105      * @param data the data to set
106      */
107     /* no qualifier */void setData( ByteBuffer data )
108     {
109         this.data = data;
110         nextPage = data.getLong( 0 );
111     }
112 
113 
114     /**
115      * Get the NextPage value from the PageIO. If it's -1, there is no next page<br/>
116      * @return the nextPage
117      */
118     /* no qualifier */long getNextPage()
119     {
120         return nextPage;
121     }
122 
123 
124     /**
125      * @param nextPage the nextPage to set
126      */
127     /* no qualifier */void setNextPage( long nextPage )
128     {
129         this.nextPage = nextPage;
130 
131         data.putLong( 0, nextPage );
132     }
133 
134 
135     /**
136      * @return the size
137      */
138     /* no qualifier */long getSize()
139     {
140         return size;
141     }
142 
143 
144     /**
145      * @param size the size to set
146      */
147     /* no qualifier */void setSize( int size )
148     {
149         data.putInt( 8, size );
150 
151         this.size = size;
152     }
153 
154 
155     /**
156      * @param size the size to set
157      */
158     /* no qualifier */void setSize()
159     {
160         size = data.getInt( 8 );
161     }
162 
163 
164     /**
165      * @return the offset
166      */
167     /* no qualifier */long getOffset()
168     {
169         return offset;
170     }
171 
172 
173     /**
174      * @param offset the offset to set
175      */
176     /* no qualifier */void setOffset( long offset )
177     {
178         this.offset = offset;
179     }
180 
181 
182     /* no qualifier */PageIO copy( PageIO copy )
183     {
184         // The data
185         if ( data.isDirect() )
186         {
187             copy.data = ByteBuffer.allocateDirect( data.capacity() );
188         }
189         else
190         {
191             copy.data = ByteBuffer.allocate( data.capacity() );
192         }
193 
194         // Save the original buffer position and limit
195         int start = data.position();
196         int limit = data.limit();
197 
198         // The data is extended to get all the bytes in it
199         data.position( 0 );
200         data.limit( data.capacity() );
201 
202         // Copy the data
203         copy.data.put( data );
204 
205         // Restore the original buffer to the initial position and limit
206         data.position( start );
207         data.limit( limit );
208 
209         // Set those position and limit in the copied buffer
210         copy.data.position( start );
211         copy.data.limit( limit );
212 
213         // The size
214         copy.size = size;
215 
216         // The offset and next page pointers are not copied.
217         return copy;
218     }
219 
220 
221     /**
222      * @see Object#toString()
223      */
224     public String toString()
225     {
226         StringBuilder sb = new StringBuilder();
227 
228         sb.append( "PageIO[offset:0x" ).append( Long.toHexString( offset ) );
229 
230         if ( size != -1 )
231         {
232             sb.append( ", size:" ).append( size );
233         }
234 
235         if ( nextPage != -1L )
236         {
237             sb.append( ", next:0x" ).append( Long.toHexString( nextPage ) );
238         }
239 
240         sb.append( "]" );
241 
242         int start = 0;
243 
244         byte[] array = null;
245 
246         data.mark();
247         data.position( 0 );
248 
249         if ( data.isDirect() )
250         {
251             array = new byte[data.capacity()];
252             data.get( array );
253         }
254         else
255         {
256             array = data.array();
257         }
258 
259         data.reset();
260 
261         for ( int i = start; i < array.length; i++ )
262         {
263             if ( ( ( i - start ) % 16 ) == 0 )
264             {
265                 sb.append( "\n    " );
266             }
267 
268             sb.append( Strings.dumpByte( array[i] ) ).append( " " );
269         }
270 
271         return sb.toString();
272     }
273 }