~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/src/java/org/apache/lucene/index/ByteBlockPool.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.index;
2
 
 
3
 
/**
4
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
5
 
 * contributor license agreements.  See the NOTICE file distributed with
6
 
 * this work for additional information regarding copyright ownership.
7
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
8
 
 * (the "License"); you may not use this file except in compliance with
9
 
 * the License.  You may obtain a copy of the License at
10
 
 *
11
 
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 
 *
13
 
 * Unless required by applicable law or agreed to in writing, software
14
 
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
 * See the License for the specific language governing permissions and
17
 
 * limitations under the License.
18
 
 */
19
 
 
20
 
/* Class that Posting and PostingVector use to write byte
21
 
 * streams into shared fixed-size byte[] arrays.  The idea
22
 
 * is to allocate slices of increasing lengths For
23
 
 * example, the first slice is 5 bytes, the next slice is
24
 
 * 14, etc.  We start by writing our bytes into the first
25
 
 * 5 bytes.  When we hit the end of the slice, we allocate
26
 
 * the next slice and then write the address of the new
27
 
 * slice into the last 4 bytes of the previous slice (the
28
 
 * "forwarding address").
29
 
 *
30
 
 * Each slice is filled with 0's initially, and we mark
31
 
 * the end with a non-zero byte.  This way the methods
32
 
 * that are writing into the slice don't need to record
33
 
 * its length and instead allocate a new slice once they
34
 
 * hit a non-zero byte. */
35
 
 
36
 
import java.util.Arrays;
37
 
import java.util.List;
38
 
import static org.apache.lucene.util.RamUsageEstimator.NUM_BYTES_OBJECT_REF;
39
 
import org.apache.lucene.util.ArrayUtil;
40
 
 
41
 
 
42
 
final class ByteBlockPool {
43
 
 
44
 
  abstract static class Allocator {
45
 
    abstract void recycleByteBlocks(byte[][] blocks, int start, int end);
46
 
    abstract void recycleByteBlocks(List<byte[]> blocks);
47
 
    abstract byte[] getByteBlock();
48
 
  }
49
 
 
50
 
  public byte[][] buffers = new byte[10][];
51
 
 
52
 
  int bufferUpto = -1;                        // Which buffer we are upto
53
 
  public int byteUpto = DocumentsWriter.BYTE_BLOCK_SIZE;             // Where we are in head buffer
54
 
 
55
 
  public byte[] buffer;                              // Current head buffer
56
 
  public int byteOffset = -DocumentsWriter.BYTE_BLOCK_SIZE;          // Current head offset
57
 
 
58
 
  private final Allocator allocator;
59
 
 
60
 
  public ByteBlockPool(Allocator allocator) {
61
 
    this.allocator = allocator;
62
 
  }
63
 
 
64
 
  public void reset() {
65
 
    if (bufferUpto != -1) {
66
 
      // We allocated at least one buffer
67
 
 
68
 
      for(int i=0;i<bufferUpto;i++)
69
 
        // Fully zero fill buffers that we fully used
70
 
        Arrays.fill(buffers[i], (byte) 0);
71
 
 
72
 
      // Partial zero fill the final buffer
73
 
      Arrays.fill(buffers[bufferUpto], 0, byteUpto, (byte) 0);
74
 
          
75
 
      if (bufferUpto > 0)
76
 
        // Recycle all but the first buffer
77
 
        allocator.recycleByteBlocks(buffers, 1, 1+bufferUpto);
78
 
 
79
 
      // Re-use the first buffer
80
 
      bufferUpto = 0;
81
 
      byteUpto = 0;
82
 
      byteOffset = 0;
83
 
      buffer = buffers[0];
84
 
    }
85
 
  }
86
 
 
87
 
  public void nextBuffer() {
88
 
    if (1+bufferUpto == buffers.length) {
89
 
      byte[][] newBuffers = new byte[ArrayUtil.oversize(buffers.length+1,
90
 
                                                        NUM_BYTES_OBJECT_REF)][];
91
 
      System.arraycopy(buffers, 0, newBuffers, 0, buffers.length);
92
 
      buffers = newBuffers;
93
 
    }
94
 
    buffer = buffers[1+bufferUpto] = allocator.getByteBlock();
95
 
    bufferUpto++;
96
 
 
97
 
    byteUpto = 0;
98
 
    byteOffset += DocumentsWriter.BYTE_BLOCK_SIZE;
99
 
  }
100
 
 
101
 
  public int newSlice(final int size) {
102
 
    if (byteUpto > DocumentsWriter.BYTE_BLOCK_SIZE-size)
103
 
      nextBuffer();
104
 
    final int upto = byteUpto;
105
 
    byteUpto += size;
106
 
    buffer[byteUpto-1] = 16;
107
 
    return upto;
108
 
  }
109
 
 
110
 
  // Size of each slice.  These arrays should be at most 16
111
 
  // elements (index is encoded with 4 bits).  First array
112
 
  // is just a compact way to encode X+1 with a max.  Second
113
 
  // array is the length of each slice, ie first slice is 5
114
 
  // bytes, next slice is 14 bytes, etc.
115
 
  final static int[] nextLevelArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9};
116
 
  final static int[] levelSizeArray = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200};
117
 
  final static int FIRST_LEVEL_SIZE = levelSizeArray[0];
118
 
 
119
 
  public int allocSlice(final byte[] slice, final int upto) {
120
 
 
121
 
    final int level = slice[upto] & 15;
122
 
    final int newLevel = nextLevelArray[level];
123
 
    final int newSize = levelSizeArray[newLevel];
124
 
 
125
 
    // Maybe allocate another block
126
 
    if (byteUpto > DocumentsWriter.BYTE_BLOCK_SIZE-newSize)
127
 
      nextBuffer();
128
 
 
129
 
    final int newUpto = byteUpto;
130
 
    final int offset = newUpto + byteOffset;
131
 
    byteUpto += newSize;
132
 
 
133
 
    // Copy forward the past 3 bytes (which we are about
134
 
    // to overwrite with the forwarding address):
135
 
    buffer[newUpto] = slice[upto-3];
136
 
    buffer[newUpto+1] = slice[upto-2];
137
 
    buffer[newUpto+2] = slice[upto-1];
138
 
 
139
 
    // Write forwarding address at end of last slice:
140
 
    slice[upto-3] = (byte) (offset >>> 24);
141
 
    slice[upto-2] = (byte) (offset >>> 16);
142
 
    slice[upto-1] = (byte) (offset >>> 8);
143
 
    slice[upto] = (byte) offset;
144
 
        
145
 
    // Write new level:
146
 
    buffer[byteUpto-1] = (byte) (16|newLevel);
147
 
 
148
 
    return newUpto+3;
149
 
  }
150
 
}
151