github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libgit/shared_browser_cache.go (about)

     1  // Copyright 2018 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  package libgit
     6  
     7  import (
     8  	"os"
     9  
    10  	lru "github.com/hashicorp/golang-lru"
    11  	"gopkg.in/src-d/go-git.v4/plumbing"
    12  )
    13  
    14  type browserCacheEntryType int
    15  
    16  const (
    17  	_ browserCacheEntryType = iota
    18  	fileInfoBrowserCacheEntry
    19  	childrenPathsBrowserCacheEntry
    20  )
    21  
    22  type sharedInBrowserCache interface {
    23  	setFileInfo(
    24  		commitHash plumbing.Hash, entryPathRelativeToRepoRoot string,
    25  		fi os.FileInfo)
    26  	setChildrenPaths(
    27  		commitHash plumbing.Hash, entryPathRelativeToRepoRoot string,
    28  		childrenPathsRelativeToRepoRoot []string)
    29  	getFileInfo(
    30  		commitHash plumbing.Hash, entryPathRelativeToRepoRoot string) (
    31  		fi os.FileInfo, ok bool)
    32  	getChildrenFileInfos(
    33  		commitHash plumbing.Hash, entryPathRelativeToRepoRoot string) (
    34  		fis []os.FileInfo, ok bool)
    35  }
    36  
    37  type noopSharedInBrowserCache struct{}
    38  
    39  func (noopSharedInBrowserCache) setFileInfo(
    40  	plumbing.Hash, string, os.FileInfo) {
    41  }
    42  func (noopSharedInBrowserCache) setChildrenPaths(
    43  	plumbing.Hash, string, []string) {
    44  }
    45  func (noopSharedInBrowserCache) getFileInfo(
    46  	plumbing.Hash, string) (os.FileInfo, bool) {
    47  	return nil, false
    48  }
    49  func (noopSharedInBrowserCache) getChildrenFileInfos(
    50  	plumbing.Hash, string) ([]os.FileInfo, bool) {
    51  	return nil, false
    52  }
    53  
    54  type gitBrowserCacheKey struct {
    55  	commitHash   plumbing.Hash
    56  	relativePath string // relative path
    57  	entryType    browserCacheEntryType
    58  }
    59  
    60  type lruSharedInBrowserCache struct {
    61  	cache *lru.Cache
    62  }
    63  
    64  const lruSharedInBrowserCacheSize = 1 << 16 // ~ 64 thousand entries
    65  
    66  func newLRUSharedInBrowserCache() (lruSharedInBrowserCache, error) {
    67  	cache, err := lru.New(lruSharedInBrowserCacheSize)
    68  	if err != nil {
    69  		return lruSharedInBrowserCache{}, err
    70  	}
    71  	return lruSharedInBrowserCache{cache: cache}, nil
    72  }
    73  
    74  func (c lruSharedInBrowserCache) setFileInfo(
    75  	commitHash plumbing.Hash, entryPathRelativeToRepoRoot string,
    76  	fi os.FileInfo) {
    77  	c.cache.Add(
    78  		gitBrowserCacheKey{
    79  			commitHash:   commitHash,
    80  			relativePath: entryPathRelativeToRepoRoot,
    81  			entryType:    fileInfoBrowserCacheEntry,
    82  		},
    83  		fi,
    84  	)
    85  }
    86  
    87  func (c lruSharedInBrowserCache) setChildrenPaths(
    88  	commitHash plumbing.Hash, entryPathRelativeToRepoRoot string,
    89  	childrenPathsRelativeToRepoRoot []string) {
    90  	c.cache.Add(
    91  		gitBrowserCacheKey{
    92  			commitHash:   commitHash,
    93  			relativePath: entryPathRelativeToRepoRoot,
    94  			entryType:    childrenPathsBrowserCacheEntry,
    95  		},
    96  		childrenPathsRelativeToRepoRoot,
    97  	)
    98  }
    99  
   100  func (c lruSharedInBrowserCache) getFileInfo(
   101  	commitHash plumbing.Hash, entryPathRelativeToRepoRoot string) (
   102  	fi os.FileInfo, ok bool) {
   103  	entry, ok := c.cache.Get(
   104  		gitBrowserCacheKey{
   105  			commitHash:   commitHash,
   106  			relativePath: entryPathRelativeToRepoRoot,
   107  			entryType:    fileInfoBrowserCacheEntry,
   108  		},
   109  	)
   110  	if !ok {
   111  		return nil, false
   112  	}
   113  	if fi, ok = entry.(os.FileInfo); !ok {
   114  		panic("rogue entry in lruSharedInBrowserCache")
   115  	}
   116  	return fi, true
   117  }
   118  
   119  func (c lruSharedInBrowserCache) getChildrenFileInfos(
   120  	commitHash plumbing.Hash, entryPathRelativeToRepoRoot string) (
   121  	fis []os.FileInfo, ok bool) {
   122  	entry, ok := c.cache.Get(
   123  		gitBrowserCacheKey{
   124  			commitHash:   commitHash,
   125  			relativePath: entryPathRelativeToRepoRoot,
   126  			entryType:    childrenPathsBrowserCacheEntry,
   127  		},
   128  	)
   129  	if !ok {
   130  		return nil, false
   131  	}
   132  	var paths []string
   133  	if paths, ok = entry.([]string); !ok {
   134  		panic("rogue entry in lruSharedInBrowserCache")
   135  	}
   136  	for _, p := range paths {
   137  		fi, ok := c.getFileInfo(commitHash, p)
   138  		if !ok {
   139  			return nil, false
   140  		}
   141  		fis = append(fis, fi)
   142  	}
   143  	return fis, true
   144  }