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 }