github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/go-themis/oracle/oracles/local.go (about)

     1  package oracles
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/insionng/yougam/libraries/pingcap/go-themis/oracle"
     8  )
     9  
    10  const epochShiftBits = 18
    11  
    12  var _ oracle.Oracle = &localOracle{}
    13  
    14  type localOracle struct {
    15  	mu              sync.Mutex
    16  	lastTimeStampTs int64
    17  	n               int64
    18  }
    19  
    20  // NewLocalOracle creates an Oracle that use local time as data source.
    21  func NewLocalOracle() oracle.Oracle {
    22  	return &localOracle{}
    23  }
    24  
    25  func (l *localOracle) IsExpired(lockTs uint64, TTL uint64) bool {
    26  	beginMs := lockTs >> epochShiftBits
    27  	return uint64(time.Now().UnixNano()/int64(time.Millisecond)) >= (beginMs + TTL)
    28  }
    29  
    30  func (l *localOracle) GetTimestamp() (uint64, error) {
    31  	l.mu.Lock()
    32  	defer l.mu.Unlock()
    33  	ts := (time.Now().UnixNano() / int64(time.Millisecond)) << epochShiftBits
    34  	if l.lastTimeStampTs == ts {
    35  		l.n++
    36  		return uint64(ts + l.n), nil
    37  	} else {
    38  		l.lastTimeStampTs = ts
    39  		l.n = 0
    40  	}
    41  	return uint64(ts), nil
    42  }