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 }