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 }