Coverage Report - com.healthmarketscience.jackcess.TempBufferHolder
 
Classes in this File Line Coverage Branch Coverage Complexity
TempBufferHolder
96%
22/23
90%
9/10
0
TempBufferHolder$1
100%
1/1
N/A
0
TempBufferHolder$HardTempBufferHolder
75%
6/8
N/A
0
TempBufferHolder$NoneTempBufferHolder
83%
5/6
N/A
0
TempBufferHolder$SoftTempBufferHolder
100%
10/10
N/A
0
TempBufferHolder$Type
100%
4/4
N/A
0
 
 1  
 /*
 2  
 Copyright (c) 2008 Health Market Science, Inc.
 3  
 
 4  
 This library is free software; you can redistribute it and/or
 5  
 modify it under the terms of the GNU Lesser General Public
 6  
 License as published by the Free Software Foundation; either
 7  
 version 2.1 of the License, or (at your option) any later version.
 8  
 
 9  
 This library is distributed in the hope that it will be useful,
 10  
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  
 Lesser General Public License for more details.
 13  
 
 14  
 You should have received a copy of the GNU Lesser General Public
 15  
 License along with this library; if not, write to the Free Software
 16  
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 17  
 USA
 18  
 
 19  
 You can contact Health Market Science at info@healthmarketscience.com
 20  
 or at the following address:
 21  
 
 22  
 Health Market Science
 23  
 2700 Horizon Drive
 24  
 Suite 200
 25  
 King of Prussia, PA 19406
 26  
 */
 27  
 
 28  
 package com.healthmarketscience.jackcess;
 29  
 
 30  
 import java.lang.ref.Reference;
 31  
 import java.lang.ref.SoftReference;
 32  
 import java.nio.ByteBuffer;
 33  
 import java.nio.ByteOrder;
 34  
 
 35  
 /**
 36  
  * Manages a reference to a ByteBuffer.
 37  
  *
 38  
  * @author James Ahlborn
 39  
  */
 40  3799
 public abstract class TempBufferHolder {
 41  
 
 42  1
   private static final Reference<ByteBuffer> EMPTY_BUFFER_REF =
 43  
     new SoftReference<ByteBuffer>(null);
 44  
 
 45  
   /**
 46  
    * The caching type for the buffer holder.
 47  
    */
 48  5
   public enum Type {
 49  
     /** a hard reference is maintained to the created buffer */
 50  1
     HARD,
 51  
     /** a soft reference is maintained to the created buffer (may be garbage
 52  
         collected if memory gets tight) */
 53  1
     SOFT,
 54  
     /** no reference is maintained to a created buffer (new buffer every
 55  
         time) */
 56  1
     NONE;
 57  
   }
 58  
   
 59  
   /** whether or not every get automatically rewinds the buffer */
 60  
   private final boolean _autoRewind;
 61  
   /** ByteOrder for all allocated buffers */
 62  
   private final ByteOrder _order;
 63  
   /** the mod count of the current buffer (changes on every realloc) */
 64  
   private int _modCount;
 65  
   
 66  6823
   protected TempBufferHolder(boolean autoRewind, ByteOrder order) {
 67  6823
     _autoRewind = autoRewind;
 68  6823
     _order = order;
 69  6823
   }
 70  
 
 71  
   /**
 72  
    * @return the modification count of the current buffer (this count is
 73  
    *         changed every time the buffer is reallocated)
 74  
    */
 75  
   public int getModCount() {
 76  128488
     return _modCount;
 77  
   }
 78  
   
 79  
   /**
 80  
    * Creates a new TempBufferHolder.
 81  
    * @param type the type of reference desired for any created buffer
 82  
    * @param autoRewind whether or not every get automatically rewinds the
 83  
    *                   buffer
 84  
    */
 85  
   public static TempBufferHolder newHolder(Type type, boolean autoRewind) {
 86  6394
     return newHolder(type, autoRewind, PageChannel.DEFAULT_BYTE_ORDER);
 87  
   }
 88  
   
 89  
   /**
 90  
    * Creates a new TempBufferHolder.
 91  
    * @param type the type of reference desired for any created buffer
 92  
    * @param autoRewind whether or not every get automatically rewinds the
 93  
    *                   buffer
 94  
    * @param order byte order for all allocated buffers
 95  
    */
 96  
   public static TempBufferHolder newHolder(Type type, boolean autoRewind,
 97  
                                            ByteOrder order)
 98  
   {
 99  1
     switch(type) {
 100  
     case HARD:
 101  2753
       return new HardTempBufferHolder(autoRewind, order);
 102  
     case SOFT:
 103  3799
       return new SoftTempBufferHolder(autoRewind, order);
 104  
     case NONE:
 105  271
       return new NoneTempBufferHolder(autoRewind, order);
 106  
     default:
 107  0
       throw new IllegalStateException("Unknown type " + type);
 108  
     }
 109  
   }
 110  
 
 111  
   /**
 112  
    * Returns a ByteBuffer of at least the defined page size, with the limit
 113  
    * set to the page size, and the predefined byteOrder.  Will be rewound iff
 114  
    * autoRewind is enabled for this buffer.
 115  
    */
 116  
   public final ByteBuffer getPageBuffer(PageChannel pageChannel) {
 117  147688
     return getBuffer(pageChannel, pageChannel.getFormat().PAGE_SIZE);
 118  
   }
 119  
 
 120  
   /**
 121  
    * Returns a ByteBuffer of at least the given size, with the limit set to
 122  
    * the given size, and the predefined byteOrder.  Will be rewound iff
 123  
    * autoRewind is enabled for this buffer.
 124  
    */
 125  
   public final ByteBuffer getBuffer(PageChannel pageChannel, int size) {
 126  149622
     ByteBuffer buffer = getExistingBuffer();
 127  149622
     if((buffer == null) || (buffer.capacity() < size)) {
 128  4980
       buffer = pageChannel.createBuffer(size, _order);
 129  4980
       ++_modCount;
 130  4980
       setNewBuffer(buffer);
 131  
     } else {
 132  144642
       buffer.limit(size);
 133  
     }
 134  149622
     if(_autoRewind) {
 135  25348
       buffer.rewind();
 136  
     }
 137  149622
     return buffer;
 138  
   }
 139  
 
 140  
   /**
 141  
    * @return the currently referenced buffer, {@code null} if none
 142  
    */
 143  
   public abstract ByteBuffer getExistingBuffer();
 144  
   
 145  
   /**
 146  
    * Releases any referenced memory.
 147  
    */
 148  
   public abstract void clear();
 149  
 
 150  
   /**
 151  
    * Sets a new buffer for this holder.
 152  
    */
 153  
   protected abstract void setNewBuffer(ByteBuffer newBuffer);
 154  
   
 155  
   /**
 156  
    * TempBufferHolder which has a hard reference to the buffer.
 157  
    */
 158  2753
   private static final class HardTempBufferHolder extends TempBufferHolder
 159  
   {
 160  
     private ByteBuffer _buffer;
 161  
 
 162  
     private HardTempBufferHolder(boolean autoRewind, ByteOrder order) {
 163  2753
       super(autoRewind, order);
 164  2753
     }
 165  
     
 166  
     @Override
 167  
     public ByteBuffer getExistingBuffer() {
 168  94210
       return _buffer;
 169  
     }
 170  
     
 171  
     @Override
 172  
     protected void setNewBuffer(ByteBuffer newBuffer) {
 173  2055
       _buffer = newBuffer;
 174  2055
     }
 175  
 
 176  
     @Override
 177  
     public void clear() {
 178  0
       _buffer = null;
 179  0
     }
 180  
   }
 181  
   
 182  
   /**
 183  
    * TempBufferHolder which has a soft reference to the buffer.
 184  
    */
 185  3799
   private static final class SoftTempBufferHolder extends TempBufferHolder
 186  
   {
 187  3799
     private Reference<ByteBuffer> _buffer = EMPTY_BUFFER_REF;
 188  
 
 189  
     private SoftTempBufferHolder(boolean autoRewind, ByteOrder order) {
 190  3799
       super(autoRewind, order);
 191  3799
     }
 192  
     
 193  
     @Override
 194  
     public ByteBuffer getExistingBuffer() {
 195  78073
       return _buffer.get();
 196  
     }
 197  
     
 198  
     @Override
 199  
     protected void setNewBuffer(ByteBuffer newBuffer) {
 200  1728
       _buffer.clear();
 201  1728
       _buffer = new SoftReference<ByteBuffer>(newBuffer);
 202  1728
     }
 203  
 
 204  
     @Override
 205  
     public void clear() {
 206  1440
       _buffer.clear();
 207  1440
     }
 208  
   }
 209  
   
 210  
   /**
 211  
    * TempBufferHolder which has a no reference to the buffer.
 212  
    */
 213  271
   private static final class NoneTempBufferHolder extends TempBufferHolder
 214  
   {
 215  
     private NoneTempBufferHolder(boolean autoRewind, ByteOrder order) {
 216  271
       super(autoRewind, order);
 217  271
     }
 218  
     
 219  
     @Override
 220  
     public ByteBuffer getExistingBuffer() {
 221  1197
       return null;
 222  
     }
 223  
     
 224  
     @Override
 225  
     protected void setNewBuffer(ByteBuffer newBuffer) {
 226  
       // nothing to do
 227  1197
     }
 228  
 
 229  
     @Override
 230  
     public void clear() {
 231  
       // nothing to do
 232  0
     }
 233  
   }
 234  
   
 235  
 }