github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/disk_block_cache_service.go (about) 1 // Copyright 2017 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 libkbfs 6 7 import ( 8 "context" 9 10 "github.com/keybase/client/go/kbfs/kbfsblock" 11 "github.com/keybase/client/go/kbfs/kbfscrypto" 12 "github.com/keybase/client/go/kbfs/tlf" 13 kbgitkbfs "github.com/keybase/client/go/protocol/kbgitkbfs1" 14 ) 15 16 type diskBlockCacheServiceConfig interface { 17 diskBlockCacheGetter 18 syncedTlfGetterSetter 19 } 20 21 // DiskBlockCacheService delegates requests for blocks to this KBFS 22 // instance's disk cache. 23 type DiskBlockCacheService struct { 24 config diskBlockCacheServiceConfig 25 } 26 27 var _ kbgitkbfs.DiskBlockCacheInterface = (*DiskBlockCacheService)(nil) 28 29 // NewDiskBlockCacheService creates a new DiskBlockCacheService. 30 func NewDiskBlockCacheService(config diskBlockCacheServiceConfig) *DiskBlockCacheService { 31 return &DiskBlockCacheService{ 32 config: config, 33 } 34 } 35 36 // GetBlock implements the DiskBlockCacheInterface interface for 37 // DiskBlockCacheService. 38 func (cache *DiskBlockCacheService) GetBlock(ctx context.Context, 39 arg kbgitkbfs.GetBlockArg) (kbgitkbfs.GetBlockRes, error) { 40 // TODO: make sure this isn't remote. 41 dbc := cache.config.DiskBlockCache() 42 if dbc == nil { 43 return kbgitkbfs.GetBlockRes{}, 44 DiskBlockCacheError{"Disk cache is nil"} 45 } 46 tlfID := tlf.ID{} 47 err := tlfID.UnmarshalBinary(arg.TlfID) 48 if err != nil { 49 return kbgitkbfs.GetBlockRes{}, newDiskBlockCacheError(err) 50 } 51 blockID := kbfsblock.ID{} 52 err = blockID.UnmarshalBinary(arg.BlockID) 53 if err != nil { 54 return kbgitkbfs.GetBlockRes{}, newDiskBlockCacheError(err) 55 } 56 buf, serverHalf, prefetchStatus, err := dbc.Get( 57 ctx, tlfID, blockID, DiskBlockAnyCache) 58 if err != nil { 59 return kbgitkbfs.GetBlockRes{}, newDiskBlockCacheError(err) 60 } 61 protocolPrefetchStatus := prefetchStatus.ToProtocol() 62 63 return kbgitkbfs.GetBlockRes{ 64 Buf: buf, 65 ServerHalf: serverHalf.Bytes(), 66 PrefetchStatus: protocolPrefetchStatus, 67 }, nil 68 } 69 70 // GetPrefetchStatus implements the DiskBlockCacheInterface interface 71 // for DiskBlockCacheService. 72 func (cache *DiskBlockCacheService) GetPrefetchStatus( 73 ctx context.Context, arg kbgitkbfs.GetPrefetchStatusArg) ( 74 prefetchStatus kbgitkbfs.PrefetchStatus, err error) { 75 dbc := cache.config.DiskBlockCache() 76 if dbc == nil { 77 return NoPrefetch.ToProtocol(), DiskBlockCacheError{"Disk cache is nil"} 78 } 79 tlfID := tlf.ID{} 80 err = tlfID.UnmarshalBinary(arg.TlfID) 81 if err != nil { 82 return NoPrefetch.ToProtocol(), newDiskBlockCacheError(err) 83 } 84 blockID := kbfsblock.ID{} 85 err = blockID.UnmarshalBinary(arg.BlockID) 86 if err != nil { 87 return NoPrefetch.ToProtocol(), newDiskBlockCacheError(err) 88 } 89 90 cacheType := DiskBlockAnyCache 91 if cache.config.IsSyncedTlf(tlfID) { 92 cacheType = DiskBlockSyncCache 93 } 94 95 dbStatus, err := dbc.GetPrefetchStatus(ctx, tlfID, blockID, cacheType) 96 if err != nil { 97 return NoPrefetch.ToProtocol(), newDiskBlockCacheError(err) 98 } 99 return dbStatus.ToProtocol(), nil 100 } 101 102 // PutBlock implements the DiskBlockCacheInterface interface for 103 // DiskBlockCacheService. 104 func (cache *DiskBlockCacheService) PutBlock(ctx context.Context, 105 arg kbgitkbfs.PutBlockArg) error { 106 dbc := cache.config.DiskBlockCache() 107 if dbc == nil { 108 return DiskBlockCacheError{"Disk cache is nil"} 109 } 110 tlfID := tlf.ID{} 111 err := tlfID.UnmarshalBinary(arg.TlfID) 112 if err != nil { 113 return newDiskBlockCacheError(err) 114 } 115 blockID := kbfsblock.ID{} 116 err = blockID.UnmarshalBinary(arg.BlockID) 117 if err != nil { 118 return newDiskBlockCacheError(err) 119 } 120 serverHalf := kbfscrypto.BlockCryptKeyServerHalf{} 121 err = serverHalf.UnmarshalBinary(arg.ServerHalf) 122 if err != nil { 123 return newDiskBlockCacheError(err) 124 } 125 cacheType := DiskBlockAnyCache 126 if cache.config.IsSyncedTlf(tlfID) { 127 cacheType = DiskBlockSyncCache 128 } 129 err = dbc.Put(ctx, tlfID, blockID, arg.Buf, serverHalf, cacheType) 130 if err != nil { 131 return newDiskBlockCacheError(err) 132 } 133 return nil 134 } 135 136 // DeleteBlocks implements the DiskBlockCacheInterface interface for 137 // DiskBlockCacheService. 138 func (cache *DiskBlockCacheService) DeleteBlocks(ctx context.Context, 139 blockIDs [][]byte) (kbgitkbfs.DeleteBlocksRes, error) { 140 dbc := cache.config.DiskBlockCache() 141 if dbc == nil { 142 return kbgitkbfs.DeleteBlocksRes{}, 143 DiskBlockCacheError{"Disk cache is nil"} 144 } 145 blocks := make([]kbfsblock.ID, 0, len(blockIDs)) 146 for _, b := range blockIDs { 147 blockID := kbfsblock.ID{} 148 err := blockID.UnmarshalBinary(b) 149 if err != nil { 150 return kbgitkbfs.DeleteBlocksRes{}, newDiskBlockCacheError(err) 151 } 152 blocks = append(blocks, blockID) 153 } 154 numRemoved, sizeRemoved, err := dbc.Delete(ctx, blocks, DiskBlockAnyCache) 155 if err != nil { 156 return kbgitkbfs.DeleteBlocksRes{}, newDiskBlockCacheError(err) 157 } 158 return kbgitkbfs.DeleteBlocksRes{ 159 NumRemoved: numRemoved, 160 SizeRemoved: sizeRemoved, 161 }, nil 162 } 163 164 // UpdateBlockMetadata implements the DiskBlockCacheInterface interface for 165 // DiskBlockCacheService. 166 func (cache *DiskBlockCacheService) UpdateBlockMetadata(ctx context.Context, 167 arg kbgitkbfs.UpdateBlockMetadataArg) error { 168 dbc := cache.config.DiskBlockCache() 169 if dbc == nil { 170 return DiskBlockCacheError{"Disk cache is nil"} 171 } 172 tlfID := tlf.ID{} 173 err := tlfID.UnmarshalBinary(arg.TlfID) 174 if err != nil { 175 return newDiskBlockCacheError(err) 176 } 177 blockID := kbfsblock.ID{} 178 err = blockID.UnmarshalBinary(arg.BlockID) 179 if err != nil { 180 return newDiskBlockCacheError(err) 181 } 182 err = dbc.UpdateMetadata( 183 ctx, tlfID, blockID, PrefetchStatus(arg.PrefetchStatus), 184 DiskBlockAnyCache) 185 if err != nil { 186 return newDiskBlockCacheError(err) 187 } 188 return nil 189 }