github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/core/blockstm/txio.go (about)

     1  package blockstm
     2  
     3  const (
     4  	ReadKindMap     = 0
     5  	ReadKindStorage = 1
     6  )
     7  
     8  type ReadDescriptor struct {
     9  	Path Key
    10  	Kind int
    11  	V    Version
    12  }
    13  
    14  type WriteDescriptor struct {
    15  	Path Key
    16  	V    Version
    17  	Val  interface{}
    18  }
    19  
    20  type TxnInput []ReadDescriptor
    21  type TxnOutput []WriteDescriptor
    22  
    23  // hasNewWrite: returns true if the current set has a new write compared to the input
    24  func (txo TxnOutput) hasNewWrite(cmpSet []WriteDescriptor) bool {
    25  	if len(txo) == 0 {
    26  		return false
    27  	} else if len(cmpSet) == 0 || len(txo) > len(cmpSet) {
    28  		return true
    29  	}
    30  
    31  	cmpMap := map[Key]bool{cmpSet[0].Path: true}
    32  
    33  	for i := 1; i < len(cmpSet); i++ {
    34  		cmpMap[cmpSet[i].Path] = true
    35  	}
    36  
    37  	for _, v := range txo {
    38  		if !cmpMap[v.Path] {
    39  			return true
    40  		}
    41  	}
    42  
    43  	return false
    44  }
    45  
    46  type TxnInputOutput struct {
    47  	inputs     []TxnInput
    48  	outputs    []TxnOutput // write sets that should be checked during validation
    49  	outputsSet []map[Key]struct{}
    50  	allOutputs []TxnOutput // entire write sets in MVHashMap. allOutputs should always be a parent set of outputs
    51  }
    52  
    53  func (io *TxnInputOutput) ReadSet(txnIdx int) []ReadDescriptor {
    54  	return io.inputs[txnIdx]
    55  }
    56  
    57  func (io *TxnInputOutput) WriteSet(txnIdx int) []WriteDescriptor {
    58  	return io.outputs[txnIdx]
    59  }
    60  
    61  func (io *TxnInputOutput) AllWriteSet(txnIdx int) []WriteDescriptor {
    62  	return io.allOutputs[txnIdx]
    63  }
    64  
    65  func (io *TxnInputOutput) HasWritten(txnIdx int, k Key) bool {
    66  	_, ok := io.outputsSet[txnIdx][k]
    67  	return ok
    68  }
    69  
    70  func MakeTxnInputOutput(numTx int) *TxnInputOutput {
    71  	return &TxnInputOutput{
    72  		inputs:     make([]TxnInput, numTx),
    73  		outputs:    make([]TxnOutput, numTx),
    74  		outputsSet: make([]map[Key]struct{}, numTx),
    75  		allOutputs: make([]TxnOutput, numTx),
    76  	}
    77  }
    78  
    79  func (io *TxnInputOutput) recordRead(txId int, input []ReadDescriptor) {
    80  	io.inputs[txId] = input
    81  }
    82  
    83  func (io *TxnInputOutput) recordWrite(txId int, output []WriteDescriptor) {
    84  	io.outputs[txId] = output
    85  	io.outputsSet[txId] = make(map[Key]struct{}, len(output))
    86  
    87  	for _, v := range output {
    88  		io.outputsSet[txId][v.Path] = struct{}{}
    89  	}
    90  }
    91  
    92  func (io *TxnInputOutput) recordAllWrite(txId int, output []WriteDescriptor) {
    93  	io.allOutputs[txId] = output
    94  }
    95  
    96  func (io *TxnInputOutput) RecordReadAtOnce(inputs [][]ReadDescriptor) {
    97  	for ind, val := range inputs {
    98  		io.inputs[ind] = val
    99  	}
   100  }
   101  
   102  func (io *TxnInputOutput) RecordAllWriteAtOnce(outputs [][]WriteDescriptor) {
   103  	for ind, val := range outputs {
   104  		io.allOutputs[ind] = val
   105  	}
   106  }