View Javadoc

1   // BSD License (http://www.galagosearch.org/license)
2   package org.galagosearch.core.index;
3   
4   import java.io.IOException;
5   import java.io.OutputStream;
6   
7   /***
8    * Stores lists of integers in vbyte compressed form.  This
9    * is useful for buffering data that will be stored
10   * compressed on disk.
11   */
12  public class CompressedByteBuffer {
13      byte[] values;
14      int position;
15  
16      public CompressedByteBuffer() {
17          clear();
18      }
19  
20      /***
21       * Add a single byte to the buffer.  This byte is written
22       * directly to the buffer without compression.
23       *
24       * @param value The byte value to add.
25       */
26      public void addRaw(int value) {
27          if (position >= values.length) {
28              byte[] nValues = new byte[values.length * 2];
29              System.arraycopy(values, 0, nValues, 0, values.length);
30              values = nValues;
31          }
32  
33          values[position] = (byte) value;
34          position += 1;
35      }
36  
37      /*** 
38       * Adds a single number to the buffer.  This number is 
39       * converted to compressed form before it is stored.
40       */
41      public void add(long i) {
42          if (i < 1 << 7) {
43              addRaw((int) (i | 0x80));
44          } else if (i < 1 << 14) {
45              addRaw((int) (i >> 0) & 0x7f);
46              addRaw((int) ((i >> 7) & 0x7f) | 0x80);
47          } else if (i < 1 << 21) {
48              addRaw((int) (i >> 0) & 0x7f);
49              addRaw((int) (i >> 7) & 0x7f);
50              addRaw((int) ((i >> 14) & 0x7f) | 0x80);
51          } else {
52              while (i >= 1 << 7) {
53                  addRaw((int) (i & 0x7f));
54                  i >>= 7;
55              }
56  
57              addRaw((int) (i | 0x80));
58          }
59      }
60  
61      /***
62       * Adds a floating point value, (4 bytes) to the buffer.
63       * This is an uncompressed value.
64       */
65      public void addFloat(float value) {
66          int bits = Float.floatToIntBits(value);
67  
68          addRaw((bits >>> 24) & 0xFF);
69          addRaw((bits >>> 16) & 0xFF);
70          addRaw((bits >>> 8) & 0xFF);
71          addRaw(bits & 0xFF);
72      }
73  
74      /***
75       * Copies the entire contents of another compressed
76       * buffer to the end of this one.
77       *
78       * @param other The buffer to copy.
79       */
80      public void add(CompressedByteBuffer other) {
81          int totalLength = other.length() + length();
82          byte[] newValues = new byte[totalLength];
83  
84          System.arraycopy(values, 0, newValues, 0, position);
85          System.arraycopy(other.values, 0, newValues, position, other.position);
86          values = newValues;
87          position = totalLength;
88      }
89  
90      /*** 
91       * Erases the contents of this buffer and sets its
92       * length to zero.
93       */
94      public void clear() {
95          values = new byte[16];
96          position = 0;
97      }
98  
99      /***
100      * Returns a byte array containing the contents of this buffer.
101      * The array returned may be larger than the actual length of
102      * the stored data.  Use the length method to determine the 
103      * true data length.
104      */
105     public byte[] getBytes() {
106         return values;
107     }
108 
109     /*** 
110      * Returns the length of the data stored in this buffer.
111      */
112     public int length() {
113         return position;
114     }
115 
116     /***
117      * Writes the contents of this buffer to a stream.
118      */
119     public void write(OutputStream stream) throws IOException {
120         stream.write(values, 0, position);
121     }
122 }
123