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  }