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.io.IOException; 24 import java.lang.ref.SoftReference; 25 26 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException; 27 28 29 /** 30 * A Value holder. As we may not store all the values in memory (except for an in-memory 31 * BTree), we will use a SoftReference to keep a reference to a Value, and if it's null, 32 * then we will load the Value from the underlying physical support, using the offset. 33 * 34 * @param <E> The type for the stored element (either a value or a page) 35 * @param <K> The type of the BTree key 36 * @param <V> The type of the BTree value 37 * 38 * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a> 39 */ 40 public class ReferenceHolder<E, K, V> implements ElementHolder<E, K, V> 41 { 42 /** The BTree */ 43 private BTree<K, V> btree; 44 45 /** The offset of the first {@link PageIO} storing the page on disk */ 46 private long offset; 47 48 /** The offset of the last {@link PageIO} storing the page on disk */ 49 private long lastOffset; 50 51 /** The reference to the element instance, or null if it's not present */ 52 private SoftReference<E> reference; 53 54 55 /** 56 * Create a new holder storing an offset and a SoftReference containing the element. 57 * 58 * @param offset The offset in disk for this value 59 * @param element The element to store into a SoftReference 60 */ 61 public ReferenceHolder( BTree<K, V> btree, E element, long offset, long lastOffset ) 62 { 63 this.btree = btree; 64 this.offset = offset; 65 this.lastOffset = lastOffset; 66 this.reference = new SoftReference<E>( element ); 67 } 68 69 70 /** 71 * {@inheritDoc} 72 * @throws IOException 73 * @throws EndOfFileExceededException 74 */ 75 @Override 76 public E getValue( BTree<K, V> btree ) throws EndOfFileExceededException, IOException 77 { 78 E element = reference.get(); 79 80 if ( element == null ) 81 { 82 // We have to fetch the element from disk, using the offset now 83 element = fetchElement( btree ); 84 reference = new SoftReference( element ); 85 } 86 87 return element; 88 } 89 90 91 /** 92 * Retrieve the value from the disk, using the BTree and offset 93 * @return The deserialized element ( 94 * @throws IOException 95 * @throws EndOfFileExceededException 96 */ 97 private E fetchElement( BTree<K, V> btree ) throws EndOfFileExceededException, IOException 98 { 99 E element = ( E ) btree.getRecordManager().deserialize( btree, offset ); 100 101 return element; 102 } 103 104 105 /** 106 * @return The offset of the first {@link PageIO} storing the data on disk 107 */ 108 /* No qualifier */long getOffset() 109 { 110 return offset; 111 } 112 113 114 /** 115 * @return The offset of the last {@link PageIO} storing the data on disk 116 */ 117 /* No qualifier */long getLastOffset() 118 { 119 return lastOffset; 120 } 121 122 123 /** 124 * @see Object#toString() 125 */ 126 public String toString() 127 { 128 StringBuilder sb = new StringBuilder(); 129 130 E element = reference.get(); 131 132 if ( element != null ) 133 { 134 sb.append( btree.getName() ).append( "[" ).append( offset ).append( "]:" ).append( element ); 135 } 136 else 137 { 138 sb.append( btree.getName() ).append( "[" ).append( offset ).append( "]" ); 139 } 140 141 return sb.toString(); 142 } 143 }