github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/codec/spi/segmentCommitInfo.go (about)

     1  package spi
     2  
     3  import (
     4  	"fmt"
     5  	. "github.com/balzaczyy/golucene/core/index/model"
     6  	"github.com/balzaczyy/golucene/core/store"
     7  )
     8  
     9  // index/SegmentCommitInfo.java
    10  
    11  // Embeds a [read-only] SegmentInfo and adds per-commit fields.
    12  type SegmentCommitInfo struct {
    13  	// The SegmentInfo that we wrap.
    14  	Info *SegmentInfo
    15  	// How many deleted docs in the segment:
    16  	delCount int
    17  	// Generation number of the live docs file (-1 if there are no deletes yet)
    18  	delGen int64
    19  	// Normally 1+delGen, unless an exception was hit on last attempt to write:
    20  	nextWriteDelGen int64
    21  
    22  	fieldInfosGen int64
    23  
    24  	nextWriteFieldInfosGen int64
    25  
    26  	docValuesGen int64
    27  
    28  	nextWriteDocValuesGen int64
    29  
    30  	dvUpdatesFiles map[int]map[string]bool
    31  
    32  	fieldInfosFiles map[string]bool
    33  
    34  	genUpdatesFiles map[int64]map[string]bool
    35  
    36  	sizeInBytes int64 // volatile
    37  
    38  	// NOTE: only used by in-RAM by IW to track buffered deletes;
    39  	// this is never written to/read from the Directory
    40  	BufferedUpdatesGen int64
    41  }
    42  
    43  func NewSegmentCommitInfo(info *SegmentInfo,
    44  	delCount int, delGen, fieldInfosGen, docValuesGen int64) *SegmentCommitInfo {
    45  
    46  	ans := &SegmentCommitInfo{
    47  		Info:                   info,
    48  		delCount:               delCount,
    49  		delGen:                 delGen,
    50  		nextWriteDelGen:        1,
    51  		fieldInfosGen:          fieldInfosGen,
    52  		nextWriteFieldInfosGen: 1,
    53  		docValuesGen:           docValuesGen,
    54  		nextWriteDocValuesGen:  1,
    55  		dvUpdatesFiles:         make(map[int]map[string]bool),
    56  		fieldInfosFiles:        make(map[string]bool),
    57  		genUpdatesFiles:        make(map[int64]map[string]bool),
    58  		sizeInBytes:            -1,
    59  	}
    60  	if delGen != -1 {
    61  		ans.nextWriteDelGen = delGen + 1
    62  	}
    63  	if fieldInfosGen != -1 {
    64  		ans.nextWriteFieldInfosGen = fieldInfosGen + 1
    65  	}
    66  	if docValuesGen != -1 {
    67  		ans.nextWriteDocValuesGen = docValuesGen + 1
    68  	}
    69  	return ans
    70  }
    71  
    72  func (si *SegmentCommitInfo) DocValuesUpdatesFiles() map[int]map[string]bool {
    73  	return si.dvUpdatesFiles
    74  }
    75  
    76  func (si *SegmentCommitInfo) SetDocValuesUpdatesFiles(dvUpdatesFiles map[int]map[string]bool) {
    77  	si.dvUpdatesFiles = dvUpdatesFiles
    78  }
    79  
    80  func (si *SegmentCommitInfo) FieldInfosFiles() map[string]bool {
    81  	return si.fieldInfosFiles
    82  }
    83  
    84  func (si *SegmentCommitInfo) SetFieldInfosFiles(fieldInfosFiles map[string]bool) {
    85  	si.fieldInfosFiles = fieldInfosFiles
    86  }
    87  
    88  /* Called when we succeed in writing deletes */
    89  func (info *SegmentCommitInfo) AdvanceDelGen() {
    90  	info.delGen, info.nextWriteDelGen = info.nextWriteDelGen, info.delGen+1
    91  	info.sizeInBytes = -1
    92  }
    93  
    94  /*
    95  Called if there was an error while writing deletes, so that we don't
    96  try to write to the same file more than once.
    97  */
    98  func (info *SegmentCommitInfo) AdvanceNextWriteDelGen() {
    99  	info.nextWriteDelGen++
   100  }
   101  
   102  /*
   103  Returns total size in bytes of all files for this segment.
   104  
   105  NOTE: This value is not correct for 3.0 segments that have shared
   106  docstores. To get correct value, upgrade.
   107  */
   108  func (si *SegmentCommitInfo) SizeInBytes() (sum int64, err error) {
   109  	if si.sizeInBytes == -1 {
   110  		sum = 0
   111  		for _, fileName := range si.Files() {
   112  			d, err := si.Info.Dir.FileLength(fileName)
   113  			if err != nil {
   114  				return 0, err
   115  			}
   116  			sum += d
   117  		}
   118  		si.sizeInBytes = sum
   119  	}
   120  	return si.sizeInBytes, nil
   121  }
   122  
   123  // Returns all files in use by this segment.
   124  func (si *SegmentCommitInfo) Files() []string {
   125  	// Start from the wrapped info's files:
   126  	files := make(map[string]bool)
   127  	for name, _ := range si.Info.Files() {
   128  		files[name] = true
   129  	}
   130  
   131  	// Must separately add any live docs files
   132  	for _, name := range si.Info.Codec().(Codec).LiveDocsFormat().Files(si) {
   133  		files[name] = true
   134  	}
   135  
   136  	// Must separately add any per-gen updates files. This can go away
   137  	// when we get rid of genUpdatesFiles (6.0)
   138  	for _, names := range si.genUpdatesFiles {
   139  		for name, _ := range names {
   140  			files[name] = true
   141  		}
   142  	}
   143  
   144  	// must separately add any field updates files
   145  	for _, names := range si.dvUpdatesFiles {
   146  		for name, _ := range names {
   147  			files[name] = true
   148  		}
   149  	}
   150  
   151  	// must separately add fieldInfos files
   152  	for name, _ := range si.fieldInfosFiles {
   153  		files[name] = true
   154  	}
   155  
   156  	ans := make([]string, 0, len(files))
   157  	for s, _ := range files {
   158  		ans = append(ans, s)
   159  	}
   160  	return ans
   161  }
   162  
   163  func (si *SegmentCommitInfo) SetBufferedUpdatesGen(v int64) {
   164  	si.BufferedUpdatesGen = v
   165  	si.sizeInBytes = -1
   166  }
   167  
   168  // Returns true if there are any deletions for the segment at this
   169  // commit.
   170  func (si *SegmentCommitInfo) HasDeletions() bool {
   171  	return si.delGen != -1
   172  }
   173  
   174  func (si *SegmentCommitInfo) HasFieldUpdates() bool {
   175  	return si.fieldInfosGen != -1
   176  }
   177  
   178  func (si *SegmentCommitInfo) FieldInfosGen() int64 {
   179  	return si.fieldInfosGen
   180  }
   181  
   182  func (si *SegmentCommitInfo) DocValuesGen() int64 {
   183  	return si.docValuesGen
   184  }
   185  
   186  /* Returns the next available generation numbre of the live docs file. */
   187  func (si *SegmentCommitInfo) NextDelGen() int64 {
   188  	return si.nextWriteDelGen
   189  }
   190  
   191  /* Returns generation number of the live docs file or -1 if there are no deletes yet. */
   192  func (si *SegmentCommitInfo) DelGen() int64 {
   193  	return si.delGen
   194  }
   195  
   196  /* Returns the number of deleted docs in the segment. */
   197  func (si *SegmentCommitInfo) DelCount() int {
   198  	return si.delCount
   199  }
   200  
   201  func (si *SegmentCommitInfo) SetDelCount(delCount int) {
   202  	assert2(delCount >= 0 && delCount <= si.Info.DocCount(),
   203  		"invalid delCount=%v (docCount=%v)", delCount, si.Info.DocCount())
   204  	si.delCount = delCount
   205  }
   206  
   207  func (si *SegmentCommitInfo) StringOf(dir store.Directory, pendingDelCount int) string {
   208  	s := si.Info.StringOf(dir, si.delCount+pendingDelCount)
   209  	var sDelGen, sFieldInfosGen, sDocValuesGen string
   210  	if si.delGen != -1 {
   211  		sDelGen = fmt.Sprintf(":delGen=%v", si.delGen)
   212  	}
   213  	if si.fieldInfosGen != -1 {
   214  		sFieldInfosGen = fmt.Sprintf(":fieldInfosGen=%v", si.fieldInfosGen)
   215  	}
   216  	if si.docValuesGen != -1 {
   217  		sDocValuesGen = fmt.Sprintf(":dvGen=%v", si.docValuesGen)
   218  	}
   219  	return fmt.Sprintf("%v%v%v%v", s, sDelGen, sFieldInfosGen, sDocValuesGen)
   220  }
   221  
   222  func (si *SegmentCommitInfo) String() string {
   223  	panic("not implemented yet")
   224  	s := si.Info.StringOf(si.Info.Dir, si.delCount)
   225  	if si.delGen != -1 {
   226  		s = fmt.Sprintf("%v:delGen=%v", s, si.delGen)
   227  	}
   228  	return s
   229  }
   230  
   231  func (si *SegmentCommitInfo) Clone() *SegmentCommitInfo {
   232  	return si.CloneDeep(false)
   233  }
   234  
   235  func (si *SegmentCommitInfo) CloneDeep(cloneSegmentInfo bool) *SegmentCommitInfo {
   236  	otherInfo := si.Info
   237  	if cloneSegmentInfo {
   238  		otherInfo = si.Info.Clone()
   239  	}
   240  	clone := NewSegmentCommitInfo(otherInfo, si.delCount, si.delGen,
   241  		si.fieldInfosGen, si.docValuesGen)
   242  	// Not clear that we need ot carry over nextWriteDelGen (i.e. do we
   243  	// ever clone after a failed write and before the next successful
   244  	// write?), but just do it to be safe:
   245  	clone.nextWriteDelGen = si.nextWriteDelGen
   246  	clone.nextWriteFieldInfosGen = si.nextWriteFieldInfosGen
   247  	clone.nextWriteDocValuesGen = si.nextWriteDocValuesGen
   248  
   249  	// deep clone
   250  	for k, v := range si.genUpdatesFiles {
   251  		clone.genUpdatesFiles[k] = v
   252  	}
   253  	for k, v := range si.dvUpdatesFiles {
   254  		clone.dvUpdatesFiles[k] = v
   255  	}
   256  	for k, v := range si.fieldInfosFiles {
   257  		clone.fieldInfosFiles[k] = v
   258  	}
   259  
   260  	return clone
   261  }