github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/fst/enum.go (about) 1 package fst 2 3 import ( 4 // "fmt" 5 "github.com/balzaczyy/golucene/core/util" 6 ) 7 8 type FSTEnumSPI interface { 9 setCurrentLabel(int) 10 grow() 11 } 12 13 type FSTEnum struct { 14 spi FSTEnumSPI 15 16 fst *FST 17 arcs []*Arc 18 output []interface{} 19 20 NO_OUTPUT interface{} 21 fstReader BytesReader 22 scratchArc *Arc 23 24 upto int 25 targetLength int 26 } 27 28 func newFSTEnum(spi FSTEnumSPI, fst *FST) *FSTEnum { 29 arcs := make([]*Arc, 10) 30 arcs[0] = new(Arc) 31 fst.FirstArc(arcs[0]) 32 outputs := make([]interface{}, 10) 33 outputs[0] = fst.outputs.NoOutput() 34 35 return &FSTEnum{ 36 spi: spi, 37 fst: fst, 38 arcs: arcs, 39 output: outputs, 40 fstReader: fst.BytesReader(), 41 NO_OUTPUT: outputs[0], 42 } 43 } 44 45 func (e *FSTEnum) doNext() (err error) { 46 // fmt.Printf("FE: next upto=%v\n", e.upto) 47 if e.upto == 0 { 48 // fmt.Println(" init") 49 e.upto = 1 50 if _, err = e.fst.readFirstTargetArc(e.Arc(0), e.Arc(1), e.fstReader); err != nil { 51 return 52 } 53 } else { 54 // pop 55 // fmt.Printf(" check pop curArc target=%v label=%v isLast?=", 56 // e.arcs[e.upto].target, e.arcs[e.upto].Label, e.arcs[e.upto].isLast()) 57 for e.arcs[e.upto].isLast() { 58 if e.upto--; e.upto == 0 { 59 // fmt.Println(" eof") 60 return nil 61 } 62 } 63 if _, err = e.fst.readNextArc(e.arcs[e.upto], e.fstReader); err != nil { 64 return 65 } 66 } 67 return e.pushFirst() 68 } 69 70 func (e *FSTEnum) incr() { 71 e.upto++ 72 e.spi.grow() 73 if len(e.arcs) <= e.upto { 74 newArcs := make([]*Arc, util.Oversize(e.upto+1, util.NUM_BYTES_OBJECT_REF)) 75 copy(newArcs, e.arcs) 76 e.arcs = newArcs 77 } 78 if len(e.output) < e.upto { 79 newOutput := make([]interface{}, util.Oversize(e.upto+1, util.NUM_BYTES_OBJECT_REF)) 80 copy(newOutput, e.output) 81 e.output = newOutput 82 } 83 } 84 85 /* 86 Appends current arc, and then recuses from its target, appending 87 first arc all the way to the final node. 88 */ 89 func (e *FSTEnum) pushFirst() (err error) { 90 arc := e.arcs[e.upto] 91 assert(arc != nil) 92 93 for { 94 e.output[e.upto] = e.fst.outputs.Add(e.output[e.upto-1], arc.Output) 95 if arc.Label == FST_END_LABEL { 96 // final node 97 break 98 } 99 // fmt.Printf(" pushFirst label=%c upto=%v output=%v\n", 100 // rune(arc.Label), e.upto, e.fst.outputs.outputToString(e.output[e.upto])) 101 e.spi.setCurrentLabel(arc.Label) 102 e.incr() 103 104 nextArc := e.Arc(e.upto) 105 if _, err = e.fst.readFirstTargetArc(arc, nextArc, e.fstReader); err != nil { 106 return 107 } 108 arc = nextArc 109 } 110 return nil 111 } 112 113 func (e *FSTEnum) Arc(idx int) *Arc { 114 if e.arcs[idx] == nil { 115 e.arcs[idx] = new(Arc) 116 } 117 return e.arcs[idx] 118 }