// listpos allows us to use this routine for copying elements between lists
listpos allows us to use this routine for copying elements between lists
// listpos allows us to use this routine for copying elements between lists
func copyStructHandlingVersionSkew(dest Object, src Object, copies *rbtree.Tree, depth int, destListPos int, srcListPos int) error {
	if dest.Segment == nil {
		return nil
	}
	destElemSz := dest.datasz + dest.ptrs*8
	srcElemSz := src.datasz + src.ptrs*8
	destListInc := destElemSz * destListPos
	srcListInc := srcElemSz * srcListPos
	toData := dest.Segment.Data[dest.off+destListInc : dest.off+destListInc+dest.datasz]
	 A: Newer fields only come *after* old fields. Note that
	    copy only copies min(len(src), len(dst)) size,
	    and then we manually zero the rest in the for loop
	    that writes toData[j] = 0.
	 data section:
	fmt.Printf("\n\n  debug: len(src.Segment.Data) = %d, src.off(%d)+srcListInc(%d) = %d\n", len(src.Segment.Data), src.off, srcListInc, src.off+srcListInc)
	from := src.Segment.Data[src.off+srcListInc : src.off+srcListInc+src.datasz]
	fmt.Printf("\n\n  debug: len(src.Segment.Data) = %d, src.off(%d)+srcListInc(%d) = %d,  len(from)=%d\n", len(src.Segment.Data), src.off, srcListInc, src.off+srcListInc, len(from))
	copyCount := copy(toData, from)
	fmt.Printf("\n\n  debug: copyCount = %d\n", copyCount)
	toData = toData[copyCount:]
	for j := range toData {
		toData[j] = 0
	}
	 ptrs section:
	 version handling: we ignore any extra-newer-pointers in src,
	 i.e. the case when srcPtrSize > dstPtrSize, by only
	 running j over the size of dstPtrSize, the destination size.
	srcPtrSize := src.ptrs * 8
	dstPtrSize := int(dest.ptrs * 8)
	for j := 0; j < dstPtrSize; j += 8 {
		if j < srcPtrSize {
			m := src.Segment.readPtr(src.off + srcListInc + src.datasz + j)
			fmt.Printf("debug: PointerList.Set(i=%d, src=%#v). source ptr is m = %#v\n", i, src, m)
			if err := dest.Segment.writePtr(dest.off+destListInc+dest.datasz+j, m, copies, depth+1); err != nil {
				return err
			}
		} else {
			 destination p is a newer version than source
			  so these extra new pointer fields in p must be zeroed.
			binary.LittleEndian.PutUint64(dest.Segment.Data[dest.off+destListInc+dest.datasz+j:], 0)
		}
	}
	 Nothing more here: so any other pointers in srcPtrSize beyond
	 those in dstPtrSize are ignored and discarded.
	return nil
}
func copyStructHandlingVersionSkew ( dest Object , src Object , copies * rbtree . Tree , depth int , destListPos int , srcListPos int ) error { if dest . Segment == nil { return nil } destElemSz := dest . datasz + dest . ptrs * 8 srcElemSz := src . datasz + src . ptrs * 8 destListInc := destElemSz * destListPos srcListInc := srcElemSz * srcListPos toData := dest . Segment . Data [ dest . off + destListInc : dest . off + destListInc + dest . datasz ] from := src . Segment . Data [ src . off + srcListInc : src . off + srcListInc + src . datasz ] copyCount := copy ( toData , from ) toData = toData [ copyCount : ] for j := range toData { toData [ j ] = 0 } srcPtrSize := src . ptrs * 8 dstPtrSize := int ( dest . ptrs * 8 ) for j := 0 ; j < dstPtrSize ; j += 8 { if j < srcPtrSize { m := src . Segment . readPtr ( src . off + srcListInc + src . datasz + j ) if err := dest . Segment . writePtr ( dest . off + destListInc + dest . datasz + j , m , copies , depth + 1 ) ; err != nil { return err } } else { binary . LittleEndian . PutUint64 ( dest . Segment . Data [ dest . off + destListInc + dest . datasz + j : ] , 0 ) } } return nil }
listpos allows us to use this routine for copying elements between lists
listpos allows us to use this routine for copying elements between lists
// handle VoidList destinations // handle assignment into a size-zero object/empty struct/old version //if destElemSz == 0 { // return nil // } //fmt.Printf("\n\n debug: destElemSz = %d, srcElemSz = %d, destListInc = %d, srcListInc = %d, toData = %#v, len(toData)=%d\n", destElemSz, srcElemSz, destListInc, srcListInc, toData, len(toData)) // Q: how does version handling happen here, when the //    desination toData[] slice can be bigger or smaller //    than the source data slice, which is in //    src.Segment.Data[src.off:src.off+src.datasz] ? // // A: Newer fields only come *after* old fields. Note that //    copy only copies min(len(src), len(dst)) size, //    and then we manually zero the rest in the for loop //    that writes toData[j] = 0. // // data section: //fmt.Printf("\n\n  debug: len(src.Segment.Data) = %d, src.off(%d)+srcListInc(%d) = %d\n", len(src.Segment.Data), src.off, srcListInc, src.off+srcListInc) //fmt.Printf("\n\n  debug: len(src.Segment.Data) = %d, src.off(%d)+srcListInc(%d) = %d,  len(from)=%d\n", len(src.Segment.Data), src.off, srcListInc, src.off+srcListInc, len(from)) //fmt.Printf("\n\n  debug: copyCount = %d\n", copyCount) // ptrs section: // version handling: we ignore any extra-newer-pointers in src, // i.e. the case when srcPtrSize > dstPtrSize, by only // running j over the size of dstPtrSize, the destination size. //fmt.Printf("debug: PointerList.Set(i=%d, src=%#v). source ptr is m = %#v\n", i, src, m) // destination p is a newer version than source //  so these extra new pointer fields in p must be zeroed. // Nothing more here: so any other pointers in srcPtrSize beyond // those in dstPtrSize are ignored and discarded.