github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/chunks/remote_requests.go (about) 1 // Copyright 2019 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 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package chunks 23 24 import ( 25 "sync" 26 27 "github.com/dolthub/dolt/go/store/hash" 28 ) 29 30 type ReadRequest interface { 31 Hashes() hash.HashSet 32 Outstanding() OutstandingRequest 33 } 34 35 func NewGetRequest(r hash.Hash, ch chan<- *Chunk) GetRequest { 36 return GetRequest{hash.HashSet{r: struct{}{}}, ch} 37 } 38 39 type GetRequest struct { 40 hashes hash.HashSet 41 ch chan<- *Chunk 42 } 43 44 func NewGetManyRequest(hashes hash.HashSet, wg *sync.WaitGroup, ch chan<- *Chunk) GetManyRequest { 45 return GetManyRequest{hashes, wg, ch} 46 } 47 48 type GetManyRequest struct { 49 hashes hash.HashSet 50 wg *sync.WaitGroup 51 ch chan<- *Chunk 52 } 53 54 func NewAbsentRequest(r hash.Hash, ch chan<- bool) AbsentRequest { 55 return AbsentRequest{hash.HashSet{r: struct{}{}}, ch} 56 } 57 58 type AbsentRequest struct { 59 hashes hash.HashSet 60 ch chan<- bool 61 } 62 63 func NewAbsentManyRequest(hashes hash.HashSet, wg *sync.WaitGroup, ch chan<- hash.Hash) AbsentManyRequest { 64 return AbsentManyRequest{hashes, wg, ch} 65 } 66 67 type AbsentManyRequest struct { 68 hashes hash.HashSet 69 wg *sync.WaitGroup 70 ch chan<- hash.Hash 71 } 72 73 func (g GetRequest) Hashes() hash.HashSet { 74 return g.hashes 75 } 76 77 func (g GetRequest) Outstanding() OutstandingRequest { 78 return OutstandingGet(g.ch) 79 } 80 81 func (g GetManyRequest) Hashes() hash.HashSet { 82 return g.hashes 83 } 84 85 func (g GetManyRequest) Outstanding() OutstandingRequest { 86 return OutstandingGetMany{g.wg, g.ch} 87 } 88 89 func (h AbsentRequest) Hashes() hash.HashSet { 90 return h.hashes 91 } 92 93 func (h AbsentRequest) Outstanding() OutstandingRequest { 94 return OutstandingAbsent(h.ch) 95 } 96 97 func (h AbsentManyRequest) Hashes() hash.HashSet { 98 return h.hashes 99 } 100 101 func (h AbsentManyRequest) Outstanding() OutstandingRequest { 102 return OutstandingAbsentMany{h.wg, h.ch} 103 } 104 105 type OutstandingRequest interface { 106 Satisfy(h hash.Hash, c *Chunk) 107 Fail() 108 } 109 110 type OutstandingGet chan<- *Chunk 111 type OutstandingGetMany struct { 112 wg *sync.WaitGroup 113 ch chan<- *Chunk 114 } 115 type OutstandingAbsent chan<- bool 116 type OutstandingAbsentMany struct { 117 wg *sync.WaitGroup 118 ch chan<- hash.Hash 119 } 120 121 func (r OutstandingGet) Satisfy(h hash.Hash, c *Chunk) { 122 r <- c 123 } 124 125 func (r OutstandingGet) Fail() { 126 r <- &EmptyChunk 127 } 128 129 func (ogm OutstandingGetMany) Satisfy(h hash.Hash, c *Chunk) { 130 ogm.ch <- c 131 ogm.wg.Done() 132 } 133 134 func (ogm OutstandingGetMany) Fail() { 135 ogm.wg.Done() 136 } 137 138 func (oh OutstandingAbsent) Satisfy(h hash.Hash, c *Chunk) { 139 oh <- false 140 } 141 142 func (oh OutstandingAbsent) Fail() { 143 oh <- true 144 } 145 146 func (ohm OutstandingAbsentMany) Satisfy(h hash.Hash, c *Chunk) { 147 ohm.ch <- h 148 ohm.wg.Done() 149 } 150 151 func (ohm OutstandingAbsentMany) Fail() { 152 ohm.wg.Done() 153 } 154 155 // ReadBatch represents a set of queued Get/Has requests, each of which are blocking on a receive channel for a response. 156 type ReadBatch map[hash.Hash][]OutstandingRequest 157 158 // Close ensures that callers to Get() and Has() are failed correctly if the corresponding chunk wasn't in the response from the server (i.e. it wasn't found). 159 func (rb *ReadBatch) Close() error { 160 for _, reqs := range *rb { 161 for _, req := range reqs { 162 req.Fail() 163 } 164 } 165 return nil 166 }