func (w *IndexWriter) Directory() store.Directory {
	return w.directory
}
Retuns the Directory used by this index.
package index
import (
	"container/list"
	"errors"
	"fmt"
	"github.com/balzaczyy/golucene/core/analysis"
	. "github.com/balzaczyy/golucene/core/codec/spi"
	. "github.com/balzaczyy/golucene/core/index/model"
	"github.com/balzaczyy/golucene/core/store"
	"github.com/balzaczyy/golucene/core/util"
	"log"
	"math"
	"os"
	"runtime"
	"sort"
	"strconv"
	"sync"
	"sync/atomic"
	"time"
)
type IndexCommit interface {
	SegmentsFileName() string
	FileNames() []string
	Directory() store.Directory
	Delete()
	IsDeleted() bool
	SegmentCount() int
	Generation() int64
	UserData() map[string]string
}
type IndexCommits []IndexCommit
func (s IndexCommits) Len() int      { return len(s) }
func (s IndexCommits) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s IndexCommits) Less(i, j int) bool {
	if s[i].Directory() != s[j].Directory() {
		panic("cannot compare IndexCommits from different Directory instances")
	}
	return s[i].Generation() < s[j].Generation()
}
var DefaultSimilarity func() Similarity
type ClosingControl struct {
	_closed  bool  
	_closing bool  
	closer   chan func() (bool, error)
	done     chan error
}
func newClosingControl() *ClosingControl {
	ans := &ClosingControl{
		closer: make(chan func() (bool, error)),
		done:   make(chan error),
	}
	go ans.daemon()
	return ans
}
func (cc *ClosingControl) daemon() {
	var err error
	for !cc._closed {
		err = nil
		select {
		case f := <-cc.closer:
			log.Println("...closing...")
			if !cc._closed {
				cc._closing = true
				cc._closed, err = f()
				cc._closing = false
			}
			cc.done <- err
		}
	}
	log.Println("IW CC daemon is stopped.")
}
func (cc *ClosingControl) ensureOpen(failIfClosing bool) {
	assert2(!cc._closed && (!failIfClosing || !cc._closing), "this IndexWriter is closed")
}
func (cc *ClosingControl) close(f func() (ok bool, err error)) error {
	if cc._closed {
		return nil  
	}
	cc.closer <- f
	log.Println("Closing IW...")
	return <-cc.done
}
const MAX_DOCS = math.MaxInt32 - 128
var actualMaxDocs = MAX_DOCS
const UNBOUNDED_MAX_MERGE_SEGMENTS = -1
const WRITE_LOCK_NAME = "write.lock"
const SOURCE_FLUSH = "flush"
const MAX_TERM_LENGTH = MAX_TERM_LENGTH_UTF8
type IndexWriter struct {
	sync.Locker
	*ClosingControl
	*MergeControl
	tragedy error  
	directory store.Directory    
	analyzer  analysis.Analyzer  
	changeCount           int64  
	lastCommitChangeCount int64  
	rollbackSegments []*SegmentCommitInfo  
	pendingCommit            *SegmentInfos  
	pendingCommitChangeCount int64          
	filesToCommit []string
	segmentInfos         *SegmentInfos  
	globalFieldNumberMap *FieldNumbers
	docWriter  *DocumentsWriter
	eventQueue *list.List
	deleter    *IndexFileDeleter
	segmentsToMerge map[*SegmentCommitInfo]bool
	writeLock store.Lock
	mergeScheduler  MergeScheduler
	mergeExceptions []*OneMerge
	didMessageState bool
	flushCount        int32  
	flushDeletesCount int32  
	readerPool            *ReaderPool
	bufferedUpdatesStream *BufferedUpdatesStream
	bufferedUpdatesStreamLock sync.Locker
	poolReaders bool
	config LiveIndexWriterConfig
	startCommitTime time.Time
	pendingNumDocs int64
	codec Codec  
	infoStream util.InfoStream
	doAfterFlush func() error
	doBeforeFlush func() error
	commitLock sync.Locker
	fullFlushLock sync.Locker
	keepFullyDeletedSegments bool  
}
func (w *IndexWriter) ensureOpen() {
	w.ClosingControl.ensureOpen(true)
}
func NewIndexWriter(d store.Directory, conf *IndexWriterConfig) (w *IndexWriter, err error) {
	ans := &IndexWriter{
		Locker:         &sync.Mutex{},
		ClosingControl: newClosingControl(),
		segmentsToMerge: make(map[*SegmentCommitInfo]bool),
		mergeExceptions: make([]*OneMerge, 0),
		doAfterFlush:    func() error { return nil },
		doBeforeFlush:   func() error { return nil },
		commitLock:      &sync.Mutex{},
		fullFlushLock:   &sync.Mutex{},
		config:         conf,
		directory:      d,
		analyzer:       conf.analyzer,
		infoStream:     conf.infoStream,
		mergeScheduler: conf.mergeScheduler,
		codec:          conf.codec,
		bufferedUpdatesStream: newBufferedUpdatesStream(conf.infoStream),
		poolReaders:           conf.readerPooling,
		bufferedUpdatesStreamLock: &sync.Mutex{},
		writeLock: d.MakeLock(WRITE_LOCK_NAME),
	}
	ans.readerPool = newReaderPool(ans)
	ans.MergeControl = newMergeControl(conf.infoStream, ans.readerPool)
	conf.setIndexWriter(ans)
	if ok, err := ans.writeLock.ObtainWithin(conf.writeLockTimeout); !ok || err != nil {
		if err != nil {
			return nil, err
		}
		return nil, errors.New(fmt.Sprintf("Index locked for write: %v", ans.writeLock))
	}
	var success bool = false
	defer func() {
		if !success {
			if ans.infoStream.IsEnabled("IW") {
				ans.infoStream.Message("IW", "init: hit exception on init; releasing write lock")
			}
			util.CloseWhileSuppressingError(ans.writeLock)  
			ans.writeLock = nil
		}
	}()
	var create bool
	switch conf.openMode {
	case OPEN_MODE_CREATE:
		create = true
	case OPEN_MODE_APPEND:
		create = false
	default:
		ok, err := IsIndexExists(d)
		if err != nil {
			return nil, err
		}
		create = !ok
	}
	ans.segmentInfos = &SegmentInfos{}
	var initialIndexExists bool = true
	if create {
		err = ans.segmentInfos.ReadAll(d)
		if err == nil {
			ans.segmentInfos.Clear()
		} else {
			initialIndexExists = false
			err = nil
		}
		ans.changed()
	} else {
		err = ans.segmentInfos.ReadAll(d)
		if err != nil {
			return
		}
		if commit := conf.commit; commit != nil {
			assert2(commit.Directory() == d,
				"IndexCommit's directory doesn't match my directory")
			oldInfos := &SegmentInfos{}
			ans.segmentInfos.replace(oldInfos)
			ans.changed()
			ans.infoStream.Message("IW", "init: loaded commit '%v'",
				commit.SegmentsFileName())
		}
	}
	ans.rollbackSegments = ans.segmentInfos.createBackupSegmentInfos()
	ans.globalFieldNumberMap, err = ans.fieldNumberMap()
	if err != nil {
		return
	}
	ans.config.flushPolicy().init(ans.config)
	ans.docWriter = newDocumentsWriter(ans, ans.config, d)
	ans.eventQueue = ans.docWriter.events
	ans.deleter, err = newIndexFileDeleter(d, conf.delPolicy,
		ans.segmentInfos, ans.infoStream, ans, initialIndexExists)
	if err != nil {
		return
	}
	if ans.deleter.startingCommitDeleted {
		ans.changed()
	}
	if ans.infoStream.IsEnabled("IW") {
		ans.infoStream.Message("IW", "init: create=%v", create)
		ans.messageState()
	}
	success = true
	return ans, nil
}
func (w *IndexWriter) fieldNumberMap() (m *FieldNumbers, err error) {
	m = NewFieldNumbers()
	for _, info := range w.segmentInfos.Segments {
		fis, err := ReadFieldInfos(info)
		if err != nil {
			return nil, err
		}
		for _, fi := range fis.Values {
			m.AddOrGet(fi)
		}
	}
	return m, nil
}
func (w *IndexWriter) messageState() {
	if w.infoStream.IsEnabled("IW") && !w.didMessageState {
		w.didMessageState = true
		w.infoStream.Message("IW", "\ndir=%v\nindex=%v\nversion=%v\n%v",
			w.directory, w.segString(), util.VERSION_LATEST, w.config)
	}
}
func (w *IndexWriter) Close() error {
	assert2(w.pendingCommit == nil,
		"cannot close: prepareCommit was already called with no corresponding call to commit")
	w.commitLock.Lock()
	defer w.commitLock.Unlock()
	return w.close(func() (ok bool, err error) {
		defer func() {
			if !ok {  
				defer recover()  
				w.rollbackInternal()
			}
		}()
		if w.infoStream.IsEnabled("IW") {
			w.infoStream.Message("IW", "now flush at close")
		}
		if err = w.flush(true, true); err != nil {
			return
		}
		w.waitForMerges()
		if err = w.commitInternal(w.config.MergePolicy()); err != nil {
			return
		}
		return w.rollbackInternal()  
	})
}