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 }