| /* |
| * 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.lucene.codecs.simpletext; |
| |
| import java.io.IOException; |
| import java.util.BitSet; |
| import java.util.Collection; |
| import org.apache.lucene.codecs.LiveDocsFormat; |
| import org.apache.lucene.index.IndexFileNames; |
| import org.apache.lucene.index.SegmentCommitInfo; |
| import org.apache.lucene.store.ChecksumIndexInput; |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.store.IOContext; |
| import org.apache.lucene.store.IndexOutput; |
| import org.apache.lucene.util.ArrayUtil; |
| import org.apache.lucene.util.Bits; |
| import org.apache.lucene.util.BytesRef; |
| import org.apache.lucene.util.BytesRefBuilder; |
| import org.apache.lucene.util.CharsRefBuilder; |
| import org.apache.lucene.util.IOUtils; |
| import org.apache.lucene.util.StringHelper; |
| |
| /** |
| * reads/writes plaintext live docs |
| * |
| * <p><b>FOR RECREATIONAL USE ONLY</b> |
| * |
| * @lucene.experimental |
| */ |
| public class SimpleTextLiveDocsFormat extends LiveDocsFormat { |
| |
| static final String LIVEDOCS_EXTENSION = "liv"; |
| |
| static final BytesRef SIZE = new BytesRef("size "); |
| static final BytesRef DOC = new BytesRef(" doc "); |
| static final BytesRef END = new BytesRef("END"); |
| |
| @Override |
| public Bits readLiveDocs(Directory dir, SegmentCommitInfo info, IOContext context) |
| throws IOException { |
| assert info.hasDeletions(); |
| BytesRefBuilder scratch = new BytesRefBuilder(); |
| CharsRefBuilder scratchUTF16 = new CharsRefBuilder(); |
| |
| String fileName = |
| IndexFileNames.fileNameFromGeneration(info.info.name, LIVEDOCS_EXTENSION, info.getDelGen()); |
| ChecksumIndexInput in = null; |
| boolean success = false; |
| try { |
| in = dir.openChecksumInput(fileName, context); |
| |
| SimpleTextUtil.readLine(in, scratch); |
| assert StringHelper.startsWith(scratch.get(), SIZE); |
| int size = parseIntAt(scratch.get(), SIZE.length, scratchUTF16); |
| |
| BitSet bits = new BitSet(size); |
| |
| SimpleTextUtil.readLine(in, scratch); |
| while (!scratch.get().equals(END)) { |
| assert StringHelper.startsWith(scratch.get(), DOC); |
| int docid = parseIntAt(scratch.get(), DOC.length, scratchUTF16); |
| bits.set(docid); |
| SimpleTextUtil.readLine(in, scratch); |
| } |
| |
| SimpleTextUtil.checkFooter(in); |
| |
| success = true; |
| return new SimpleTextBits(bits, size); |
| } finally { |
| if (success) { |
| IOUtils.close(in); |
| } else { |
| IOUtils.closeWhileHandlingException(in); |
| } |
| } |
| } |
| |
| private int parseIntAt(BytesRef bytes, int offset, CharsRefBuilder scratch) { |
| scratch.copyUTF8Bytes(bytes.bytes, bytes.offset + offset, bytes.length - offset); |
| return ArrayUtil.parseInt(scratch.chars(), 0, scratch.length()); |
| } |
| |
| @Override |
| public void writeLiveDocs( |
| Bits bits, Directory dir, SegmentCommitInfo info, int newDelCount, IOContext context) |
| throws IOException { |
| int size = bits.length(); |
| BytesRefBuilder scratch = new BytesRefBuilder(); |
| |
| String fileName = |
| IndexFileNames.fileNameFromGeneration( |
| info.info.name, LIVEDOCS_EXTENSION, info.getNextDelGen()); |
| IndexOutput out = null; |
| boolean success = false; |
| try { |
| out = dir.createOutput(fileName, context); |
| SimpleTextUtil.write(out, SIZE); |
| SimpleTextUtil.write(out, Integer.toString(size), scratch); |
| SimpleTextUtil.writeNewline(out); |
| |
| for (int i = 0; i < size; ++i) { |
| if (bits.get(i)) { |
| SimpleTextUtil.write(out, DOC); |
| SimpleTextUtil.write(out, Integer.toString(i), scratch); |
| SimpleTextUtil.writeNewline(out); |
| } |
| } |
| |
| SimpleTextUtil.write(out, END); |
| SimpleTextUtil.writeNewline(out); |
| SimpleTextUtil.writeChecksum(out, scratch); |
| success = true; |
| } finally { |
| if (success) { |
| IOUtils.close(out); |
| } else { |
| IOUtils.closeWhileHandlingException(out); |
| } |
| } |
| } |
| |
| @Override |
| public void files(SegmentCommitInfo info, Collection<String> files) throws IOException { |
| if (info.hasDeletions()) { |
| files.add( |
| IndexFileNames.fileNameFromGeneration( |
| info.info.name, LIVEDOCS_EXTENSION, info.getDelGen())); |
| } |
| } |
| |
| // read-only |
| static class SimpleTextBits implements Bits { |
| final BitSet bits; |
| final int size; |
| |
| SimpleTextBits(BitSet bits, int size) { |
| this.bits = bits; |
| this.size = size; |
| } |
| |
| @Override |
| public boolean get(int index) { |
| return bits.get(index); |
| } |
| |
| @Override |
| public int length() { |
| return size; |
| } |
| } |
| } |