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  }