github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/block_put_state_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/libkey"
    12  )
    13  
    14  type blockPutStateDiskConfig interface {
    15  	codecGetter
    16  	cryptoPureGetter
    17  	keyGetterGetter
    18  }
    19  
    20  // blockPutStateDisk tracks block info while making a revision, by
    21  // using a disk-based block cache.
    22  type blockPutStateDisk struct {
    23  	*blockPutStateMemory // won't store actual block data
    24  
    25  	config    blockPutStateDiskConfig
    26  	diskCache *DiskBlockCacheLocal
    27  	kmd       libkey.KeyMetadata
    28  	isDir     map[data.BlockPointer]bool
    29  }
    30  
    31  var _ blockPutState = (*blockPutStateDisk)(nil)
    32  
    33  func newBlockPutStateDisk(
    34  	length int, config blockPutStateDiskConfig,
    35  	diskCache *DiskBlockCacheLocal, kmd libkey.KeyMetadata) *blockPutStateDisk {
    36  	return &blockPutStateDisk{
    37  		blockPutStateMemory: newBlockPutStateMemory(length),
    38  		config:              config,
    39  		diskCache:           diskCache,
    40  		kmd:                 kmd,
    41  		isDir:               make(map[data.BlockPointer]bool),
    42  	}
    43  }
    44  
    45  // AddNewBlock implements the blockPutState interface for blockPutStateDisk.
    46  func (bps *blockPutStateDisk) AddNewBlock(
    47  	ctx context.Context, blockPtr data.BlockPointer, block data.Block,
    48  	readyBlockData data.ReadyBlockData, syncedCb func() error) error {
    49  	// Add the pointer and the cb to the memory-based put state, and
    50  	// put the ready data directly into the disk cache.
    51  	err := bps.diskCache.Put(
    52  		ctx, bps.kmd.TlfID(), blockPtr.ID, readyBlockData.Buf,
    53  		readyBlockData.ServerHalf)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	if _, isDir := block.(*data.DirBlock); isDir {
    59  		bps.isDir[blockPtr] = true
    60  	}
    61  
    62  	return bps.blockPutStateMemory.AddNewBlock(
    63  		ctx, blockPtr, nil, data.ReadyBlockData{}, syncedCb)
    64  }
    65  
    66  func (bps *blockPutStateDisk) GetBlock(
    67  	ctx context.Context, blockPtr data.BlockPointer) (data.Block, error) {
    68  	blockData, serverHalf, _, err := bps.diskCache.Get(
    69  		ctx, bps.kmd.TlfID(), blockPtr.ID)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	var block data.Block
    75  	if bps.isDir[blockPtr] {
    76  		block = data.NewDirBlock()
    77  	} else {
    78  		block = data.NewFileBlock()
    79  	}
    80  	err = assembleBlockLocal(
    81  		ctx, bps.config.keyGetter(), bps.config.Codec(),
    82  		bps.config.cryptoPure(), bps.kmd, blockPtr, block, blockData,
    83  		serverHalf)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	return block, nil
    88  }
    89  
    90  func (bps *blockPutStateDisk) getReadyBlockData(
    91  	ctx context.Context, blockPtr data.BlockPointer) (data.ReadyBlockData, error) {
    92  	blockData, serverHalf, _, err := bps.diskCache.Get(
    93  		ctx, bps.kmd.TlfID(), blockPtr.ID)
    94  	if err != nil {
    95  		return data.ReadyBlockData{}, err
    96  	}
    97  	return data.ReadyBlockData{
    98  		Buf:        blockData,
    99  		ServerHalf: serverHalf,
   100  	}, nil
   101  }