kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/platform/kcd/locked/locked.go (about)

     1  /*
     2   * Copyright 2016 The Kythe Authors. All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *   http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  // Package locked implements a delegating wrapper that protects each method of
    18  // the resulting kcd.Reader or kcd.ReadWriter with a mutex, so that the result
    19  // is safe for concurrent use by multiple goroutines.
    20  package locked // import "kythe.io/kythe/go/platform/kcd/locked"
    21  
    22  import (
    23  	"context"
    24  	"errors"
    25  	"io"
    26  	"sync"
    27  
    28  	"kythe.io/kythe/go/platform/kcd"
    29  )
    30  
    31  type locker struct {
    32  	μ   sync.Mutex
    33  	rd  kcd.Reader
    34  	wr  kcd.Writer
    35  	del kcd.Deleter
    36  }
    37  
    38  // Reader returns a kcd.Reader that delegates to r with method calls protected
    39  // by a mutex.
    40  func Reader(r kcd.Reader) kcd.Reader { return &locker{rd: r} }
    41  
    42  // ReadWriter returns a kcd.ReadWriter that delegates to rw with method calls
    43  // protected by a mutex.
    44  func ReadWriter(rw kcd.ReadWriter) kcd.ReadWriter { return &locker{rd: rw, wr: rw} }
    45  
    46  // ReadWriteDeleter returns a kcd.ReadWriteDeleter that delegates to rwd with
    47  // method calls protected by a mutex.
    48  func ReadWriteDeleter(rwd kcd.ReadWriteDeleter) kcd.ReadWriteDeleter {
    49  	return &locker{rd: rwd, wr: rwd, del: rwd}
    50  }
    51  
    52  // ErrNotSupported is returned by the write methods if no Writer is available.
    53  var ErrNotSupported = errors.New("write operation not supported")
    54  
    55  // Revisions implements a method of kcd.Reader.
    56  func (db *locker) Revisions(ctx context.Context, want *kcd.RevisionsFilter, f func(kcd.Revision) error) error {
    57  	db.μ.Lock()
    58  	defer db.μ.Unlock()
    59  	return db.rd.Revisions(ctx, want, f)
    60  }
    61  
    62  // Find implements a method of kcd.Reader.
    63  func (db *locker) Find(ctx context.Context, filter *kcd.FindFilter, f func(string) error) error {
    64  	db.μ.Lock()
    65  	defer db.μ.Unlock()
    66  	return db.rd.Find(ctx, filter, f)
    67  }
    68  
    69  // Units implements a method of kcd.Reader.
    70  func (db *locker) Units(ctx context.Context, unitDigests []string, f func(digest, key string, data []byte) error) error {
    71  	db.μ.Lock()
    72  	defer db.μ.Unlock()
    73  	return db.rd.Units(ctx, unitDigests, f)
    74  }
    75  
    76  // Files implements a method of kcd.Reader.
    77  func (db *locker) Files(ctx context.Context, fileDigests []string, f func(string, []byte) error) error {
    78  	db.μ.Lock()
    79  	defer db.μ.Unlock()
    80  	return db.rd.Files(ctx, fileDigests, f)
    81  }
    82  
    83  // FilesExist implements a method of kcd.Reader.
    84  func (db *locker) FilesExist(ctx context.Context, fileDigests []string, f func(string) error) error {
    85  	db.μ.Lock()
    86  	defer db.μ.Unlock()
    87  	return db.rd.FilesExist(ctx, fileDigests, f)
    88  }
    89  
    90  // WriteRevision implements a method of kcd.Writer.
    91  func (db *locker) WriteRevision(ctx context.Context, rev kcd.Revision, replace bool) error {
    92  	if db.wr == nil {
    93  		return ErrNotSupported
    94  	}
    95  	db.μ.Lock()
    96  	defer db.μ.Unlock()
    97  	return db.wr.WriteRevision(ctx, rev, replace)
    98  }
    99  
   100  // WriteUnit implements a method of kcd.Writer.
   101  func (db *locker) WriteUnit(ctx context.Context, rev kcd.Revision, formatKey string, unit kcd.Unit) (string, error) {
   102  	if db.wr == nil {
   103  		return "", ErrNotSupported
   104  	}
   105  	db.μ.Lock()
   106  	defer db.μ.Unlock()
   107  	return db.wr.WriteUnit(ctx, rev, formatKey, unit)
   108  }
   109  
   110  // WriteFile implements a method of kcd.Writer.
   111  func (db *locker) WriteFile(ctx context.Context, r io.Reader) (string, error) {
   112  	if db.wr == nil {
   113  		return "", ErrNotSupported
   114  	}
   115  	db.μ.Lock()
   116  	defer db.μ.Unlock()
   117  	return db.wr.WriteFile(ctx, r)
   118  }
   119  
   120  // DeleteUnit implements a method of kcd.Deleter.
   121  func (db *locker) DeleteUnit(ctx context.Context, unitDigest string) error {
   122  	if db.del == nil {
   123  		return ErrNotSupported
   124  	}
   125  	db.μ.Lock()
   126  	defer db.μ.Unlock()
   127  	return db.del.DeleteUnit(ctx, unitDigest)
   128  }
   129  
   130  // DeleteFile implements a method of kcd.Deleter.
   131  func (db *locker) DeleteFile(ctx context.Context, fileDigest string) error {
   132  	if db.del == nil {
   133  		return ErrNotSupported
   134  	}
   135  	db.μ.Lock()
   136  	defer db.μ.Unlock()
   137  	return db.del.DeleteFile(ctx, fileDigest)
   138  }
   139  
   140  // DeleteRevision implements a method of kcd.Deleter.
   141  func (db *locker) DeleteRevision(ctx context.Context, revision, corpus string) error {
   142  	if db.del == nil {
   143  		return ErrNotSupported
   144  	}
   145  	db.μ.Lock()
   146  	defer db.μ.Unlock()
   147  	return db.del.DeleteRevision(ctx, revision, corpus)
   148  }