github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/file_block_map_disk.go (about) 1 // Copyright 2019 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/data" 11 "github.com/keybase/client/go/kbfs/kbfsblock" 12 "github.com/keybase/client/go/kbfs/libkey" 13 "github.com/pkg/errors" 14 ) 15 16 type fileBlockMapDiskInfo struct { 17 pps data.PathPartString 18 ptr data.BlockPointer 19 } 20 21 // fileBlockMapDisk tracks block info while making a revision, by 22 // using a disk-based block cache. 23 type fileBlockMapDisk struct { 24 dirtyBcache *DirtyBlockCacheDisk 25 kmd libkey.KeyMetadata 26 ptrs map[data.BlockPointer]map[string]fileBlockMapDiskInfo 27 } 28 29 var _ fileBlockMap = (*fileBlockMapDisk)(nil) 30 31 func newFileBlockMapDisk( 32 dirtyBcache *DirtyBlockCacheDisk, kmd libkey.KeyMetadata) *fileBlockMapDisk { 33 return &fileBlockMapDisk{ 34 dirtyBcache: dirtyBcache, 35 kmd: kmd, 36 ptrs: make(map[data.BlockPointer]map[string]fileBlockMapDiskInfo), 37 } 38 } 39 40 func (fbmd *fileBlockMapDisk) putTopBlock( 41 ctx context.Context, parentPtr data.BlockPointer, 42 childName data.PathPartString, topBlock *data.FileBlock) error { 43 // To reuse the DirtyBlockCacheDisk code, we need to assign a 44 // random BlockPointer to this block. 45 id, err := kbfsblock.MakeTemporaryID() 46 if err != nil { 47 return err 48 } 49 ptr := data.BlockPointer{ID: id} 50 51 err = fbmd.dirtyBcache.Put( 52 ctx, fbmd.kmd.TlfID(), ptr, data.MasterBranch, topBlock) 53 if err != nil { 54 return err 55 } 56 57 ptrMap, ok := fbmd.ptrs[parentPtr] 58 if !ok { 59 ptrMap = make(map[string]fileBlockMapDiskInfo) 60 fbmd.ptrs[parentPtr] = ptrMap 61 } 62 63 ptrMap[childName.Plaintext()] = fileBlockMapDiskInfo{childName, ptr} 64 return nil 65 } 66 67 func (fbmd *fileBlockMapDisk) GetTopBlock( 68 ctx context.Context, parentPtr data.BlockPointer, 69 childName data.PathPartString) (*data.FileBlock, error) { 70 ptrMap, ok := fbmd.ptrs[parentPtr] 71 if !ok { 72 return nil, errors.Errorf("No such parent %s", parentPtr) 73 } 74 info, ok := ptrMap[childName.Plaintext()] 75 if !ok { 76 return nil, errors.Errorf( 77 "No such name %s in parent %s", childName, parentPtr) 78 } 79 block, err := fbmd.dirtyBcache.Get( 80 ctx, fbmd.kmd.TlfID(), info.ptr, data.MasterBranch) 81 if err != nil { 82 return nil, err 83 } 84 fblock, ok := block.(*data.FileBlock) 85 if !ok { 86 return nil, errors.Errorf( 87 "Unexpected block type for file block: %T", block) 88 } 89 return fblock, nil 90 } 91 92 func (fbmd *fileBlockMapDisk) getFilenames( 93 _ context.Context, parentPtr data.BlockPointer) ( 94 names []data.PathPartString, err error) { 95 ptrMap, ok := fbmd.ptrs[parentPtr] 96 if !ok { 97 return nil, nil 98 } 99 names = make([]data.PathPartString, 0, len(ptrMap)) 100 for _, info := range ptrMap { 101 names = append(names, info.pps) 102 } 103 return names, nil 104 }