github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/common/forward_tree.go (about)

     1  package common
     2  
     3  type ForwardTree struct {
     4  	spans    []*Span
     5  	idx      int
     6  	offset   uint64
     7  	eof      bool
     8  	width    uint64
     9  	key      uint64
    10  	original bool
    11  	val      interface{}
    12  }
    13  
    14  type Span struct {
    15  	L   uint64
    16  	R   uint64
    17  	Val interface{}
    18  }
    19  
    20  type FTreer interface {
    21  	GetHeight() uint64
    22  	GetVal() interface{}
    23  }
    24  
    25  func NewForwardTree(width, start, end uint64, ftrees []FTreer) *ForwardTree {
    26  	//ass
    27  	ft := &ForwardTree{
    28  		width:    width,
    29  		spans:    make([]*Span, 0, 20),
    30  		key:      start,
    31  		original: true,
    32  	}
    33  	if start == 0 {
    34  		ft.original = false
    35  	}
    36  	sp := &Span{}
    37  	ref := start
    38  	ending := false
    39  	for k, v := range ftrees {
    40  		h := v.GetHeight()
    41  		val := v.GetVal()
    42  		if k == 0 {
    43  			sp.L = start
    44  			sp.R = h
    45  			if h < start {
    46  				sp.R = start
    47  			}
    48  			sp.Val = val
    49  			ending = true
    50  		} else {
    51  			if h > ref {
    52  				//last ending
    53  				for h > ref {
    54  					sp.R = ref
    55  					ref = ref + width
    56  				}
    57  				l := ref - width
    58  				//if k != 1 {
    59  				spTmp := &Span{}
    60  				DeepCopy(&spTmp, sp)
    61  				ft.spans = append(ft.spans, spTmp)
    62  				//}
    63  				sp.L = l
    64  				sp.Val = val
    65  				ending = true
    66  
    67  			} else {
    68  				sp.R = h
    69  				sp.Val = val
    70  				ending = true
    71  			}
    72  		}
    73  	}
    74  	if ending {
    75  		for ref <= end {
    76  			sp.R = ref
    77  			ref = ref + width
    78  		}
    79  		ft.spans = append(ft.spans, sp)
    80  	}
    81  	return ft
    82  }
    83  
    84  func (this *ForwardTree) Next() (eof bool) {
    85  	if this.eof {
    86  		return this.eof
    87  	}
    88  	f := true
    89  Loop:
    90  	lt := this.spans[this.idx]
    91  	if f {
    92  		if this.original {
    93  			this.original = false
    94  		} else {
    95  			this.offset = this.offset + this.width
    96  			this.key += this.width
    97  			f = false
    98  		}
    99  	}
   100  	lTmp := lt.L + this.offset
   101  	if lTmp > lt.R {
   102  		interval := lTmp - lt.R
   103  		this.offset = interval
   104  		this.idx++
   105  		if this.idx+1 > len(this.spans) {
   106  			this.eof = true
   107  			return this.eof
   108  		}
   109  		goto Loop
   110  	}
   111  	this.val = this.spans[this.idx].Val
   112  	return false
   113  }
   114  
   115  func (this *ForwardTree) Val() interface{} {
   116  	return this.val
   117  }
   118  func (this *ForwardTree) Key() uint64 {
   119  	return this.key
   120  }