/* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using Directory = Lucene.Net.Store.Directory; using InputStream = Lucene.Net.Store.InputStream; using OutputStream = Lucene.Net.Store.OutputStream; namespace Lucene.Net.Util { /// Optimized implementation of a vector of bits. This is more-or-less like /// java.util.BitSet, but also includes the following: /// /// /// Doug Cutting /// /// $Id: BitVector.java,v 1.4 2004/03/29 22:48:05 cutting Exp $ /// public sealed class BitVector { private byte[] bits; private int size; private int count = - 1; /// Constructs a vector capable of holding n bits. public BitVector(int n) { size = n; bits = new byte[(size >> 3) + 1]; } /// Sets the value of bit to one. public void Set(int bit) { bits[bit >> 3] |= (byte) (1 << (bit & 7)); count = - 1; } /// Sets the value of bit to zero. public void Clear(int bit) { bits[bit >> 3] &= (byte) ~ (1 << (bit & 7)); count = - 1; } /// Returns true if bit is one and /// false if it is zero. /// public bool Get(int bit) { return (bits[bit >> 3] & (1 << (bit & 7))) != 0; } /// Returns the number of bits in this vector. This is also one greater than /// the number of the largest valid bit number. /// public int Size() { return size; } /// Returns the total number of one bits in this vector. This is efficiently /// computed and cached, so that, if the vector is not changed, no /// recomputation is done for repeated calls. /// public int Count() { // if the vector has been modified if (count == - 1) { int c = 0; int end = bits.Length; for (int i = 0; i < end; i++) c += BYTE_COUNTS[bits[i] & 0xFF]; // sum bits per byte count = c; } return count; } private static readonly byte[] BYTE_COUNTS = new byte[]{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; /// Writes this vector to the file name in Directory /// d, in a format that can be read by the constructor {@link /// #BitVector(Directory, String)}. /// public void Write(Directory d, System.String name) { OutputStream output = d.CreateFile(name); try { output.WriteInt(Size()); // write size output.WriteInt(Count()); // write count output.WriteBytes(bits, bits.Length); // write bits } finally { output.Close(); } } /// Constructs a bit vector from the file name in Directory /// d, as written by the {@link #write} method. /// public BitVector(Directory d, System.String name) { InputStream input = d.OpenFile(name); try { size = input.ReadInt(); // read size count = input.ReadInt(); // read count bits = new byte[(size >> 3) + 1]; // allocate bits input.ReadBytes(bits, 0, bits.Length); // read bits } finally { input.Close(); } } } }