func (sis *SegmentInfos) write(directory store.Directory) (err error) { segmentsFilename := sis.nextSegmentFilename() // Always advance the generation on write: if sis.generation == -1 { sis.generation = 1 } else { sis.generation++ } var segnOutput store.IndexOutput var success = false // var upgradedSIFiles = make(map[string]bool) defer func() { if !success { // We hit an error above; try to close the file but suppress // any errors util.CloseWhileSuppressingError(segnOutput) // for filename, _ := range upgradedSIFiles { // directory.DeleteFile(filename) // ignore error // } // Try not to leave a truncated segments_N fle in the index: directory.DeleteFile(segmentsFilename) // ignore error } }() if segnOutput, err = directory.CreateOutput(segmentsFilename, store.IO_CONTEXT_DEFAULT); err != nil { return } if err = codec.WriteHeader(segnOutput, "segments", VERSION_49); err != nil { return } if err = segnOutput.WriteLong(sis.version); err == nil { if err = segnOutput.WriteInt(int32(sis.counter)); err == nil { err = segnOutput.WriteInt(int32(len(sis.Segments))) } } if err != nil { return } for _, siPerCommit := range sis.Segments { si := siPerCommit.Info if err = segnOutput.WriteString(si.Name); err == nil { if err = segnOutput.WriteString(si.Codec().(Codec).Name()); err == nil { if err = segnOutput.WriteLong(siPerCommit.DelGen()); err == nil { assert2(siPerCommit.DelCount() >= 0 && siPerCommit.DelCount() <= si.DocCount(), "cannot write segment: invalid docCount segment=%v docCount=%v delCount=%v", si.Name, si.DocCount(), siPerCommit.DelCount()) if err = segnOutput.WriteInt(int32(siPerCommit.DelCount())); err == nil { if err = segnOutput.WriteLong(siPerCommit.FieldInfosGen()); err == nil { if err = segnOutput.WriteLong(siPerCommit.DocValuesGen()); err == nil { if err = segnOutput.WriteStringSet(siPerCommit.FieldInfosFiles()); err == nil { dvUpdatesFiles := siPerCommit.DocValuesUpdatesFiles() if err = segnOutput.WriteInt(int32(len(dvUpdatesFiles))); err == nil { for k, v := range dvUpdatesFiles { if err = segnOutput.WriteInt(int32(k)); err != nil { break } if err = segnOutput.WriteStringSet(v); err != nil { break } } } } } } } } } } if err != nil { return } assert(si.Dir == directory) // If this segment is pre-4.x, perform a one-time "upgrade" to // write the .si file for it: if version := si.Version(); len(version) == 0 || !version.OnOrAfter(util.VERSION_4_0) { panic("not implemented yet") } } if err = segnOutput.WriteStringStringMap(sis.userData); err != nil { return } sis.pendingSegnOutput = segnOutput success = true return nil }
if fi.HasPayloads() { bits |= FI_STORE_PAYLOADS } if fi.IsIndexed() { bits |= FI_IS_INDEXED assert(indexOptions >= INDEX_OPT_DOCS_AND_FREQS_AND_POSITIONS || !fi.HasPayloads()) switch indexOptions { case INDEX_OPT_DOCS_ONLY: bits |= FI_OMIT_TERM_FREQ_AND_POSITIONS case INDEX_OPT_DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS: bits |= FI_STORE_OFFSETS_IN_POSTINGS case INDEX_OPT_DOCS_AND_FREQS: bits |= FI_OMIT_POSITIONS } } if err = output.WriteString(fi.Name); err == nil { if err = output.WriteVInt(fi.Number); err == nil { err = output.WriteByte(bits) } } if err != nil { return } // pack the DV types in one byte dv := byte(fi.DocValuesType()) nrm := byte(fi.NormType()) assert((dv&(^byte(0xF))) == 0 && (nrm&(^byte(0x0F))) == 0) val := (0xff & ((nrm << 4) | dv)) if err = output.WriteByte(val); err == nil { if err = output.WriteLong(fi.DocValuesGen()); err == nil {