pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / util / packed / PackedWriter.java
1 package org.apache.lucene.util.packed;
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 import org.apache.lucene.store.DataOutput;
21
22 import java.io.IOException;
23
24 // Packs high order byte first, to match
25 // IndexOutput.writeInt/Long/Short byte order
26
27 /**
28  * Generic writer for space-optimal packed values. The resulting bits can be
29  * used directly by Packed32, Packed64 and PackedDirect* and will always be
30  * long-aligned.
31  */
32
33 class PackedWriter extends PackedInts.Writer {
34   private long pending;
35   private int pendingBitPos;
36
37   // masks[n-1] masks for bottom n bits
38   private final long[] masks;
39   private int written = 0;
40
41   public PackedWriter(DataOutput out, int valueCount, int bitsPerValue)
42                                                             throws IOException {
43     super(out, valueCount, bitsPerValue);
44
45     pendingBitPos = 64;
46     masks = new long[bitsPerValue - 1];
47
48     long v = 1;
49     for (int i = 0; i < bitsPerValue - 1; i++) {
50       v *= 2;
51       masks[i] = v - 1;
52     }
53   }
54
55   /**
56    * Do not call this after finish
57    */
58   @Override
59   public void add(long v) throws IOException {
60     assert v <= PackedInts.maxValue(bitsPerValue) : "v=" + v
61             + " maxValue=" + PackedInts.maxValue(bitsPerValue);
62     assert v >= 0;
63     //System.out.println("    packedw add v=" + v + " pendingBitPos=" + pendingBitPos);
64
65     // TODO
66     if (pendingBitPos >= bitsPerValue) {
67       // not split
68
69       // write-once, so we can |= w/o first masking to 0s
70       pending |= v << (pendingBitPos - bitsPerValue);
71       if (pendingBitPos == bitsPerValue) {
72         // flush
73         out.writeLong(pending);
74         pending = 0;
75         pendingBitPos = 64;
76       } else {
77         pendingBitPos -= bitsPerValue;
78       }
79
80     } else {
81       // split
82
83       // write top pendingBitPos bits of value into bottom bits of pending
84       pending |= (v >> (bitsPerValue - pendingBitPos)) & masks[pendingBitPos - 1];
85       //System.out.println("      part1 (v >> " + (bitsPerValue - pendingBitPos) + ") & " + masks[pendingBitPos-1]);
86
87       // flush
88       out.writeLong(pending);
89
90       // write bottom (bitsPerValue - pendingBitPos) bits of value into top bits of pending
91       pendingBitPos = 64 - bitsPerValue + pendingBitPos;
92       //System.out.println("      part2 v << " + pendingBitPos);
93       pending = (v << pendingBitPos);
94     }
95     written++;
96   }
97
98   @Override
99   public void finish() throws IOException {
100     while (written < valueCount) {
101       add(0L); // Auto flush
102     }
103
104     if (pendingBitPos != 64) {
105       out.writeLong(pending);
106     }
107   }
108
109   @Override
110   public String toString() {
111     return "PackedWriter(written " + written + "/" + valueCount + " with "
112             + bitsPerValue + " bits/value)";
113   }
114 }