github.com/aychain/blockbook@v0.1.1-0.20181121092459-6d1fc7e07c5b/common/internalstate.go (about)

     1  package common
     2  
     3  import (
     4  	"encoding/json"
     5  	"sync"
     6  	"time"
     7  )
     8  
     9  const (
    10  	// DbStateClosed means db was closed gracefully
    11  	DbStateClosed = uint32(iota)
    12  	// DbStateOpen means db is open or application died without closing the db
    13  	DbStateOpen
    14  	// DbStateInconsistent means db is in inconsistent state and cannot be used
    15  	DbStateInconsistent
    16  )
    17  
    18  // InternalStateColumn contains the data of a db column
    19  type InternalStateColumn struct {
    20  	Name       string    `json:"name"`
    21  	Version    uint32    `json:"version"`
    22  	Rows       int64     `json:"rows"`
    23  	KeyBytes   int64     `json:"keyBytes"`
    24  	ValueBytes int64     `json:"valueBytes"`
    25  	Updated    time.Time `json:"updated"`
    26  }
    27  
    28  // InternalState contains the data of the internal state
    29  type InternalState struct {
    30  	mux sync.Mutex
    31  
    32  	Coin         string `json:"coin"`
    33  	CoinShortcut string `json:"coinShortcut"`
    34  	CoinLabel    string `json:"coinLabel"`
    35  	Host         string `json:"host"`
    36  
    37  	DbState uint32 `json:"dbState"`
    38  
    39  	LastStore time.Time `json:"lastStore"`
    40  
    41  	// true if application is with flag --sync
    42  	SyncMode bool `json:"syncMode"`
    43  
    44  	InitialSync    bool      `json:"initialSync"`
    45  	IsSynchronized bool      `json:"isSynchronized"`
    46  	BestHeight     uint32    `json:"bestHeight"`
    47  	LastSync       time.Time `json:"lastSync"`
    48  
    49  	IsMempoolSynchronized bool      `json:"isMempoolSynchronized"`
    50  	MempoolSize           int       `json:"mempoolSize"`
    51  	LastMempoolSync       time.Time `json:"lastMempoolSync"`
    52  
    53  	DbColumns []InternalStateColumn `json:"dbColumns"`
    54  }
    55  
    56  // StartedSync signals start of synchronization
    57  func (is *InternalState) StartedSync() {
    58  	is.mux.Lock()
    59  	defer is.mux.Unlock()
    60  	is.IsSynchronized = false
    61  }
    62  
    63  // FinishedSync marks end of synchronization, bestHeight specifies new best block height
    64  func (is *InternalState) FinishedSync(bestHeight uint32) {
    65  	is.mux.Lock()
    66  	defer is.mux.Unlock()
    67  	is.IsSynchronized = true
    68  	is.BestHeight = bestHeight
    69  	is.LastSync = time.Now()
    70  }
    71  
    72  // UpdateBestHeight sets new best height, without changing IsSynchronized flag
    73  func (is *InternalState) UpdateBestHeight(bestHeight uint32) {
    74  	is.mux.Lock()
    75  	defer is.mux.Unlock()
    76  	is.BestHeight = bestHeight
    77  	is.LastSync = time.Now()
    78  }
    79  
    80  // FinishedSyncNoChange marks end of synchronization in case no index update was necessary, it does not update lastSync time
    81  func (is *InternalState) FinishedSyncNoChange() {
    82  	is.mux.Lock()
    83  	defer is.mux.Unlock()
    84  	is.IsSynchronized = true
    85  }
    86  
    87  // GetSyncState gets the state of synchronization
    88  func (is *InternalState) GetSyncState() (bool, uint32, time.Time) {
    89  	is.mux.Lock()
    90  	defer is.mux.Unlock()
    91  	return is.IsSynchronized, is.BestHeight, is.LastSync
    92  }
    93  
    94  // StartedMempoolSync signals start of mempool synchronization
    95  func (is *InternalState) StartedMempoolSync() {
    96  	is.mux.Lock()
    97  	defer is.mux.Unlock()
    98  	is.IsMempoolSynchronized = false
    99  }
   100  
   101  // FinishedMempoolSync marks end of mempool synchronization
   102  func (is *InternalState) FinishedMempoolSync(mempoolSize int) {
   103  	is.mux.Lock()
   104  	defer is.mux.Unlock()
   105  	is.IsMempoolSynchronized = true
   106  	is.MempoolSize = mempoolSize
   107  	is.LastMempoolSync = time.Now()
   108  }
   109  
   110  // GetMempoolSyncState gets the state of mempool synchronization
   111  func (is *InternalState) GetMempoolSyncState() (bool, time.Time, int) {
   112  	is.mux.Lock()
   113  	defer is.mux.Unlock()
   114  	return is.IsMempoolSynchronized, is.LastMempoolSync, is.MempoolSize
   115  }
   116  
   117  // AddDBColumnStats adds differences in column statistics to column stats
   118  func (is *InternalState) AddDBColumnStats(c int, rowsDiff int64, keyBytesDiff int64, valueBytesDiff int64) {
   119  	is.mux.Lock()
   120  	defer is.mux.Unlock()
   121  	dc := &is.DbColumns[c]
   122  	dc.Rows += rowsDiff
   123  	dc.KeyBytes += keyBytesDiff
   124  	dc.ValueBytes += valueBytesDiff
   125  	dc.Updated = time.Now()
   126  }
   127  
   128  // SetDBColumnStats sets new values of column stats
   129  func (is *InternalState) SetDBColumnStats(c int, rows int64, keyBytes int64, valueBytes int64) {
   130  	is.mux.Lock()
   131  	defer is.mux.Unlock()
   132  	dc := &is.DbColumns[c]
   133  	dc.Rows = rows
   134  	dc.KeyBytes = keyBytes
   135  	dc.ValueBytes = valueBytes
   136  	dc.Updated = time.Now()
   137  }
   138  
   139  // GetDBColumnStatValues gets stat values for given column
   140  func (is *InternalState) GetDBColumnStatValues(c int) (int64, int64, int64) {
   141  	is.mux.Lock()
   142  	defer is.mux.Unlock()
   143  	if c < len(is.DbColumns) {
   144  		return is.DbColumns[c].Rows, is.DbColumns[c].KeyBytes, is.DbColumns[c].ValueBytes
   145  	}
   146  	return 0, 0, 0
   147  }
   148  
   149  // GetAllDBColumnStats returns stats for all columns
   150  func (is *InternalState) GetAllDBColumnStats() []InternalStateColumn {
   151  	is.mux.Lock()
   152  	defer is.mux.Unlock()
   153  	rv := make([]InternalStateColumn, len(is.DbColumns))
   154  	copy(rv, is.DbColumns)
   155  	return rv
   156  }
   157  
   158  // DBSizeTotal sums the computed sizes of all columns
   159  func (is *InternalState) DBSizeTotal() int64 {
   160  	is.mux.Lock()
   161  	defer is.mux.Unlock()
   162  	total := int64(0)
   163  	for _, c := range is.DbColumns {
   164  		total += c.KeyBytes + c.ValueBytes
   165  	}
   166  	return total
   167  }
   168  
   169  // Pack marshals internal state to json
   170  func (is *InternalState) Pack() ([]byte, error) {
   171  	is.mux.Lock()
   172  	defer is.mux.Unlock()
   173  	is.LastStore = time.Now()
   174  	return json.Marshal(is)
   175  }
   176  
   177  // UnpackInternalState unmarshals internal state from json
   178  func UnpackInternalState(buf []byte) (*InternalState, error) {
   179  	var is InternalState
   180  	if err := json.Unmarshal(buf, &is); err != nil {
   181  		return nil, err
   182  	}
   183  	return &is, nil
   184  }