/** * Copyright 2014 National University of Ireland, Galway. * * This file is part of the SIREn project. Project and contact information: * * https://github.com/rdelbru/SIREn * * 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. */ package org.sindice.siren.index.codecs.siren10; import java.io.IOException; import java.util.Arrays; import org.apache.lucene.codecs.MultiLevelSkipListWriter; import org.apache.lucene.index.FieldInfo.IndexOptions; import org.apache.lucene.store.IndexOutput; import org.sindice.siren.index.codecs.block.BlockIndexOutput; /** * Implementation of the {@link MultiLevelSkipListWriter} for the default * block-based posting list format of SIREn 1.0. * * <p> * * Compared to the original Lucene format, this skip list is only storing the * document identifiers and the file pointer of the block within the .doc file. * * <p> * * The {@link MultiLevelSkipListWriter} implementation is based on document * count, but it is used here with block count instead of document count. * In order to make it compatible with block, this class is converting * document count into block count. */ public class Siren10SkipListWriter extends MultiLevelSkipListWriter { private final int[] lastSkipDoc; private final BlockIndexOutput.Index[] docIndex; private int curDoc; Siren10SkipListWriter(final int blockSkipInterval, final int maxSkipLevels, final int blockCount, final BlockIndexOutput docOutput) throws IOException { super(blockSkipInterval, maxSkipLevels, blockCount); lastSkipDoc = new int[numberOfSkipLevels]; docIndex = new BlockIndexOutput.Index[numberOfSkipLevels]; for(int i = 0; i < numberOfSkipLevels; i++) { docIndex[i] = docOutput.index(); } } IndexOptions indexOptions; void setIndexOptions(final IndexOptions v) { indexOptions = v; } /** * Sets the values for the current skip data. * <p> * Called at every index interval (every block by default) */ void setSkipData(final int doc) { this.curDoc = doc; } /** * Called at start of new term */ protected void resetSkip(final BlockIndexOutput.Index topDocIndex) throws IOException { super.resetSkip(); Arrays.fill(lastSkipDoc, 0); for(int i = 0; i < numberOfSkipLevels; i++) { docIndex[i].copyFrom(topDocIndex, true); } } @Override protected void writeSkipData(final int level, final IndexOutput skipBuffer) throws IOException { skipBuffer.writeVInt(curDoc - lastSkipDoc[level]); docIndex[level].mark(); docIndex[level].write(skipBuffer, false); lastSkipDoc[level] = curDoc; } }