/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.blur.filter;
import java.io.Closeable;
import java.io.IOException;
import org.apache.blur.log.Log;
import org.apache.blur.log.LogFactory;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
public class IndexFileBitSet extends DocIdSet implements Closeable {
private static final Log LOG = LogFactory.getLog(IndexFileBitSet.class);
public static final String EXTENSION = ".filter";
private final String _id;
private final String _segmentName;
private final Directory _directory;
private final int _numBits;
private IndexInput _indexInput;
public IndexFileBitSet(int numBits, String id, String segmentName, Directory directory) {
_id = id;
_segmentName = segmentName;
_directory = directory;
_numBits = numBits;
}
@Override
public DocIdSetIterator iterator() throws IOException {
return new IndexFileBitSetIterator(_indexInput.clone());
}
public boolean exists() throws IOException {
boolean fileExists = _directory.fileExists(getFileName());
if (fileExists) {
int words = (_numBits / 64) + 1;
int correctLength = words * 8;
long length = _indexInput.length();
if (correctLength == length) {
return true;
}
}
return false;
}
private String getFileName() {
return _segmentName + "_" + _id + EXTENSION;
}
public void load() throws IOException {
String fileName = getFileName();
_indexInput = _directory.openInput(fileName, IOContext.READ);
int words = (_numBits / 64) + 1;
int correctLength = words * 8;
long length = _indexInput.length();
if (correctLength != length) {
throw new IOException("File [" + fileName + "] with length [" + length + "] does not match correct length of ["
+ correctLength + "]");
}
}
public void create(DocIdSetIterator it) throws IOException {
String fileName = getFileName();
if (_directory.fileExists(getFileName())) {
LOG.warn("Filter [{0}] in directory [{1}] being recreated due to incorrect size.", fileName, _directory);
_directory.deleteFile(fileName);
}
IndexOutput output = _directory.createOutput(fileName, IOContext.READ);
int index;
int currentWordNum = 0;
long wordValue = 0;
while ((index = it.nextDoc()) < _numBits) {
int wordNum = index >> 6; // div 64
if (currentWordNum > wordNum) {
throw new IOException("We got a problem here!");
}
while (currentWordNum < wordNum) {
output.writeLong(wordValue);
currentWordNum++;
wordValue = 0;
}
int bit = index & 0x3f; // mod 64
long bitmask = 1L << bit;
wordValue |= bitmask;
}
if (_numBits > 0) {
int totalWords = (_numBits / 64) + 1;
while (currentWordNum < totalWords) {
output.writeLong(wordValue);
currentWordNum++;
wordValue = 0;
}
}
output.close();
}
@Override
public void close() throws IOException {
_indexInput.close();
}
}