func (w *CompoundFileWriter) writeEntryTable(entries map[string]*FileEntry, entryOut IndexOutput) (err error) { if err = codec.WriteHeader(entryOut, CFD_ENTRY_CODEC, CFD_VERSION_CURRENT); err == nil { if err = entryOut.WriteVInt(int32(len(entries))); err == nil { var names []string for name, _ := range entries { names = append(names, name) } sort.Strings(names) for _, name := range names { // for _, fe := range entries { fe := entries[name] if err = Stream(entryOut). WriteString(util.StripSegmentName(fe.file)). WriteLong(fe.offset). WriteLong(fe.length). Close(); err != nil { break } } } } if err == nil { err = codec.WriteFooter(entryOut) } return err }
func (d *CompoundFileDirectory) FileExists(name string) bool { d.EnsureOpen() // if d.writer != nil { // return d.writer.FileExists(name) // } _, ok := d.entries[util.StripSegmentName(name)] return ok }
func (d *CompoundFileDirectory) OpenInput(name string, context IOContext) (in IndexInput, err error) { d.Lock() // synchronized defer d.Unlock() d.EnsureOpen() assert(!d.openForWrite) id := util.StripSegmentName(name) if entry, ok := d.entries[id]; ok { return d.handle.Slice(name, entry.offset, entry.length) } keys := make([]string, 0) for k := range d.entries { keys = append(keys, k) } panic(fmt.Sprintf("No sub-file with id %v found (fileName=%v files: %v)", id, name, keys)) }
func (w *CompoundFileWriter) createOutput(name string, context IOContext) (IndexOutput, error) { w.ensureOpen() var success = false var outputLocked = false defer func() { if !success { delete(w.entries, name) if outputLocked { // release the output lock if not successful assert(w.outputTaken.Get()) w.releaseOutputLock() } } }() assert2(name != "", "name must not be empty") _, ok := w.entries[name] assert2(!ok, "File %v already exists", name) entry := &FileEntry{} entry.file = name w.entries[name] = entry id := util.StripSegmentName(name) _, ok = w.seenIDs[id] assert2(!ok, "file='%v' maps to id='%v', which was already written", name, id) w.seenIDs[id] = true var out *DirectCFSIndexOutput if outputLocked := w.outputTaken.CompareAndSet(false, true); outputLocked { o, err := w.output(context) if err != nil { return nil, err } out = newDirectCFSIndexOutput(w, o, entry, false) } else { entry.dir = w.directory o, err := w.directory.CreateOutput(name, context) if err != nil { return nil, err } out = newDirectCFSIndexOutput(w, o, entry, true) } success = true return out, nil }