github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/chunks/cs_metrics_wrapper.go (about) 1 // Copyright 2020 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package chunks 16 17 import ( 18 "context" 19 "fmt" 20 "sync/atomic" 21 22 "github.com/dolthub/dolt/go/store/hash" 23 ) 24 25 // CSMetrics contains the metrics aggregated by a CSMetricsWrapper 26 type CSMetrics struct { 27 TotalChunkGets int32 28 TotalChunkHasChecks int32 29 TotalChunkPuts int32 30 Delegate interface{} 31 DelegateSummary string 32 } 33 34 // NewCSMetrics creates a CSMetrics instance 35 func NewCSMetrics(csMW *CSMetricWrapper) CSMetrics { 36 return CSMetrics{ 37 TotalChunkGets: atomic.LoadInt32(&csMW.TotalChunkGets), 38 TotalChunkHasChecks: atomic.LoadInt32(&csMW.TotalChunkHasChecks), 39 TotalChunkPuts: atomic.LoadInt32(&csMW.TotalChunkPuts), 40 Delegate: csMW.cs.Stats(), 41 DelegateSummary: csMW.cs.StatsSummary(), 42 } 43 } 44 45 // String prints CSMetrics as JSON with indenting 46 func (csm CSMetrics) String() string { 47 return fmt.Sprintf(`{ 48 "TotalChunkGets": %d, 49 "TotalChunkHasChecks": %d, 50 "TotalChunkPuts": %d, 51 "DelegateSummary": "%s", 52 }`, csm.TotalChunkGets, csm.TotalChunkHasChecks, csm.TotalChunkPuts, csm.DelegateSummary) 53 } 54 55 // CSMetricWrapper is a ChunkStore implementation that wraps a ChunkStore, and collects metrics on the calls. 56 type CSMetricWrapper struct { 57 TotalChunkGets int32 58 TotalChunkHasChecks int32 59 TotalChunkPuts int32 60 cs ChunkStore 61 } 62 63 // NewCSMetricWrapper returns a new CSMetricWrapper 64 func NewCSMetricWrapper(cs ChunkStore) *CSMetricWrapper { 65 return &CSMetricWrapper{ 66 cs: cs, 67 } 68 } 69 70 // Get the Chunk for the value of the hash in the store. If the hash is 71 // absent from the store EmptyChunk is returned. 72 func (csMW *CSMetricWrapper) Get(ctx context.Context, h hash.Hash) (Chunk, error) { 73 atomic.AddInt32(&csMW.TotalChunkGets, 1) 74 return csMW.cs.Get(ctx, h) 75 } 76 77 // GetMany gets the Chunks with |hashes| from the store. On return, 78 // |foundChunks| will have been fully sent all chunks which have been 79 // found. Any non-present chunks will silently be ignored. 80 func (csMW *CSMetricWrapper) GetMany(ctx context.Context, hashes hash.HashSet, found func(*Chunk)) error { 81 atomic.AddInt32(&csMW.TotalChunkGets, int32(len(hashes))) 82 return csMW.cs.GetMany(ctx, hashes, found) 83 } 84 85 // Returns true iff the value at the address |h| is contained in the 86 // store 87 func (csMW *CSMetricWrapper) Has(ctx context.Context, h hash.Hash) (bool, error) { 88 atomic.AddInt32(&csMW.TotalChunkHasChecks, 1) 89 return csMW.cs.Has(ctx, h) 90 } 91 92 // Returns a new HashSet containing any members of |hashes| that are 93 // absent from the store. 94 func (csMW *CSMetricWrapper) HasMany(ctx context.Context, hashes hash.HashSet) (absent hash.HashSet, err error) { 95 atomic.AddInt32(&csMW.TotalChunkHasChecks, int32(len(hashes))) 96 return csMW.cs.HasMany(ctx, hashes) 97 } 98 99 // Put caches c in the ChunkSource. Upon return, c must be visible to 100 // subsequent Get and Has calls, but must not be persistent until a call 101 // to Flush(). Put may be called concurrently with other calls to Put(), 102 // Get(), GetMany(), Has() and HasMany(). 103 func (csMW *CSMetricWrapper) Put(ctx context.Context, c Chunk) error { 104 atomic.AddInt32(&csMW.TotalChunkPuts, 1) 105 return csMW.cs.Put(ctx, c) 106 } 107 108 // Returns the NomsVersion with which this ChunkSource is compatible. 109 func (csMW *CSMetricWrapper) Version() string { 110 return csMW.cs.Version() 111 } 112 113 // Rebase brings this ChunkStore into sync with the persistent storage's 114 // current root. 115 func (csMW *CSMetricWrapper) Rebase(ctx context.Context) error { 116 return csMW.cs.Rebase(ctx) 117 } 118 119 // Root returns the root of the database as of the time the ChunkStore 120 // was opened or the most recent call to Rebase. 121 func (csMW *CSMetricWrapper) Root(ctx context.Context) (hash.Hash, error) { 122 return csMW.cs.Root(ctx) 123 } 124 125 // Commit atomically attempts to persist all novel Chunks and update the 126 // persisted root hash from last to current (or keeps it the same). 127 // If last doesn't match the root in persistent storage, returns false. 128 func (csMW *CSMetricWrapper) Commit(ctx context.Context, current, last hash.Hash) (bool, error) { 129 return csMW.cs.Commit(ctx, current, last) 130 } 131 132 // Stats may return some kind of struct that reports statistics about the 133 // ChunkStore instance. The type is implementation-dependent, and impls 134 // may return nil 135 func (csMW *CSMetricWrapper) Stats() interface{} { 136 return NewCSMetrics(csMW) 137 } 138 139 // StatsSummary may return a string containing summarized statistics for 140 // this ChunkStore. It must return "Unsupported" if this operation is not 141 // supported. 142 func (csMW *CSMetricWrapper) StatsSummary() string { 143 return NewCSMetrics(csMW).String() 144 } 145 146 // Close tears down any resources in use by the implementation. After 147 // Close(), the ChunkStore may not be used again. It is NOT SAFE to call 148 // Close() concurrently with any other ChunkStore method; behavior is 149 // undefined and probably crashy. 150 func (csMW *CSMetricWrapper) Close() error { 151 return csMW.cs.Close() 152 }