Open jerrinsg opened 5 years ago
Simple program to verify the issue -
package main
import (
"github.com/vmware/go-pmem-transaction/pmem"
"github.com/vmware/go-pmem-transaction/transaction"
)
type data struct {
slc []int
}
var dptr *data
func main() {
pmem.Init("/mnt/ext4-pmem0/database")
tx := transaction.NewUndoTx()
dptr = pnew(data)
dptr.slc = pmake([]int, 10, 10)
tx.Begin()
tx.Log(&dptr.slc)
tx.End()
}
By adding debug prints in Log()
it is seen that the slice contents are getting flushed twice.
Actually, this code will be of use if the sliceheader itself changes. For example, in the program above if dptr.slc changes, we get a new slice header we need to flush the new slice contents too!
tx.Begin()
tx.Log(&dptr.slc)
dptr.slc = pmake([]int, 100, 100) // <-- dptr.slc sliceheader stores pointer to backing data & that pointer can be updated here
tx.End()
But you are right, if the sliceheader doesn't change there are two flushes for the slice contents.
It is seen that redundant flushes are issued when a pointer to a slice is passed to the undo
Log()
function.When
Log()
is passed a pointer to a slice, it logs the slice header as well as the contents of the slice. WhenEnd()
is called, the contents of the slice are flushed twice - first when the slice header data is flushed,End()
also flushes the contents of the slice becauset.log[i].sliceElemSize != 0
. Second - the contents of the slice were logged separately as well byLog()
. WhenEnd()
processes that entry, a redundant flush is issued.