github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/orderer/sbft/simplebft/calendarqueue_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package simplebft
    18  
    19  import (
    20  	"sort"
    21  	"time"
    22  )
    23  
    24  type calendarQueue struct {
    25  	dayLength  time.Duration
    26  	yearLength time.Duration
    27  	today      time.Duration
    28  	nextYear   time.Duration
    29  	slots      [][]testElem
    30  	maxLen     int
    31  }
    32  
    33  func newCalendarQueue(dayLength time.Duration, days int) *calendarQueue {
    34  	return &calendarQueue{
    35  		dayLength:  dayLength,
    36  		yearLength: dayLength * time.Duration(days),
    37  		nextYear:   dayLength * time.Duration(days),
    38  		slots:      make([][]testElem, days),
    39  	}
    40  }
    41  
    42  func (t *calendarQueue) slot(d time.Duration) int {
    43  	return int(d/t.dayLength) % len(t.slots)
    44  }
    45  
    46  func (t *calendarQueue) Add(e testElem) {
    47  	sl := t.slot(e.at)
    48  	t.slots[sl] = append(t.slots[sl], e)
    49  	l := len(t.slots[sl])
    50  	if l > t.maxLen {
    51  		t.maxLen = l
    52  	}
    53  	sort.Sort(testElemQueue(t.slots[sl]))
    54  }
    55  
    56  func (t *calendarQueue) Pop() (testElem, bool) {
    57  	var lowest *time.Duration
    58  	sl := t.slot(t.today)
    59  	start := sl
    60  	today := t.today
    61  	for ; today < t.nextYear; today, sl = today+t.dayLength, sl+1 {
    62  		if len(t.slots[sl]) == 0 {
    63  			continue
    64  		}
    65  		e := t.slots[sl][0]
    66  		if e.at >= t.nextYear {
    67  			if lowest == nil || *lowest > e.at {
    68  				lowest = &e.at
    69  			}
    70  			continue
    71  		}
    72  		t.slots[sl] = t.slots[sl][1:]
    73  		t.today = today
    74  		return e, true
    75  	}
    76  
    77  	// next deadline is after this year, but we only
    78  	// searched part of the calendar so far.  Search the
    79  	// remaining prefix.
    80  	for i := 0; i < start; i++ {
    81  		if len(t.slots[i]) == 0 {
    82  			continue
    83  		}
    84  		e := t.slots[i][0]
    85  		if e.at >= t.nextYear {
    86  			if lowest == nil || *lowest > e.at {
    87  				lowest = &e.at
    88  			}
    89  		}
    90  	}
    91  
    92  	if lowest == nil {
    93  		return testElem{}, false
    94  	}
    95  
    96  	t.today = *lowest / t.dayLength * t.dayLength
    97  	t.nextYear = (t.today/t.yearLength + 1) * t.yearLength
    98  	return t.Pop() // retry!
    99  }
   100  
   101  func (t *calendarQueue) filter(fn func(testElem) bool) {
   102  	for sli, sl := range t.slots {
   103  		var del []int
   104  		for i, e := range sl {
   105  			if !fn(e) {
   106  				del = append(del, i)
   107  			}
   108  		}
   109  
   110  		// now delete
   111  		for i, e := range del {
   112  			correctedPos := e - i
   113  			// in-place remove
   114  			sl = sl[:correctedPos+copy(sl[correctedPos:], sl[correctedPos+1:])]
   115  		}
   116  		t.slots[sli] = sl
   117  	}
   118  }
   119  
   120  /////////////////////////////////////////
   121  
   122  type testElemQueue []testElem
   123  
   124  func (q testElemQueue) Len() int {
   125  	return len(q)
   126  }
   127  
   128  func (q testElemQueue) Less(i, j int) bool {
   129  	return q[i].at < q[j].at
   130  }
   131  
   132  func (q testElemQueue) Swap(i, j int) {
   133  	q[i], q[j] = q[j], q[i]
   134  }