1 package org.apache.lucene.index;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import java.io.IOException;
21 import org.apache.lucene.store.RAMOutputStream;
22 import org.apache.lucene.util.ArrayUtil;
23 import org.apache.lucene.util.RamUsageEstimator;
25 /** This is a DocFieldConsumer that writes stored fields. */
26 final class StoredFieldsWriter {
28 FieldsWriter fieldsWriter;
29 final DocumentsWriter docWriter;
30 final FieldInfos fieldInfos;
33 PerDoc[] docFreeList = new PerDoc[1];
36 public StoredFieldsWriter(DocumentsWriter docWriter, FieldInfos fieldInfos) {
37 this.docWriter = docWriter;
38 this.fieldInfos = fieldInfos;
41 public StoredFieldsWriterPerThread addThread(DocumentsWriter.DocState docState) throws IOException {
42 return new StoredFieldsWriterPerThread(docState, this);
45 synchronized public void flush(SegmentWriteState state) throws IOException {
46 if (state.numDocs > lastDocID) {
51 if (fieldsWriter != null) {
56 String fieldsIdxName = IndexFileNames.segmentFileName(state.segmentName, IndexFileNames.FIELDS_INDEX_EXTENSION);
57 if (4 + ((long) state.numDocs) * 8 != state.directory.fileLength(fieldsIdxName)) {
58 throw new RuntimeException("after flush: fdx size mismatch: " + state.numDocs + " docs vs " + state.directory.fileLength(fieldsIdxName) + " length in bytes of " + fieldsIdxName + " file exists?=" + state.directory.fileExists(fieldsIdxName));
63 private synchronized void initFieldsWriter() throws IOException {
64 if (fieldsWriter == null) {
65 fieldsWriter = new FieldsWriter(docWriter.directory, docWriter.getSegment(), fieldInfos);
72 synchronized PerDoc getPerDoc() {
75 if (allocCount > docFreeList.length) {
76 // Grow our free list up front to make sure we have
77 // enough space to recycle all outstanding PerDoc
79 assert allocCount == 1+docFreeList.length;
80 docFreeList = new PerDoc[ArrayUtil.oversize(allocCount, RamUsageEstimator.NUM_BYTES_OBJECT_REF)];
84 return docFreeList[--freeCount];
88 synchronized void abort() {
89 if (fieldsWriter != null) {
96 /** Fills in any hole in the docIDs */
97 void fill(int docID) throws IOException {
98 // We must "catch up" for all docs before us
99 // that had no stored fields:
100 while(lastDocID < docID) {
101 fieldsWriter.skipDocument();
106 synchronized void finishDocument(PerDoc perDoc) throws IOException {
107 assert docWriter.writer.testPoint("StoredFieldsWriter.finishDocument start");
112 // Append stored fields to the real FieldsWriter:
113 fieldsWriter.flushDocument(perDoc.numStoredFields, perDoc.fdt);
117 assert docWriter.writer.testPoint("StoredFieldsWriter.finishDocument end");
120 synchronized void free(PerDoc perDoc) {
121 assert freeCount < docFreeList.length;
122 assert 0 == perDoc.numStoredFields;
123 assert 0 == perDoc.fdt.length();
124 assert 0 == perDoc.fdt.getFilePointer();
125 docFreeList[freeCount++] = perDoc;
128 class PerDoc extends DocumentsWriter.DocWriter {
129 final DocumentsWriter.PerDocBuffer buffer = docWriter.newPerDocBuffer();
130 RAMOutputStream fdt = new RAMOutputStream(buffer);
146 public long sizeInBytes() {
147 return buffer.getSizeInBytes();
151 public void finish() throws IOException {
152 finishDocument(this);