Ejemplo n.º 1
0
Archivo: sum.go Proyecto: smtc/rsync
// use rollsum do weak sum
func weakSum(p []byte) (s uint32) {
	var rs rollsum.Rollsum

	rs.Init()
	rs.Update(p)
	return rs.Digest()
}
Ejemplo n.º 2
0
Archivo: delta.go Proyecto: smtc/rsync
func (d *delta) genDelta(src io.ReadSeeker, srcLen int64) (err error) {
	var (
		c        byte
		p        []byte
		rs       rollsum.Rollsum
		rb       *rotateBuffer
		srcPos   int64
		matchAt  int64
		blockLen int
	)

	if d.debug {
		d.dumpSign()
	}

	blockLen = int(d.sig.block_len)

	rb = NewRotateBuffer(srcLen, d.sig.block_len, src)
	p, srcPos, err = rb.rollFirst()
	if err == nil {
		// 计算初始weaksum
		rs.Init()
		rs.Update(p)
		for err == nil {
			// srcPos是当前读取src文件的绝对位置,matchAt对应于dstSig和dst文件的位置
			matchAt = d.findMatch(p, srcPos, rs.Digest())
			if matchAt < 0 {
				p, c, srcPos, err = rb.rollByte()
				if err != nil {
					break
				}
				rs.Rotate(c, p[blockLen-1])
			} else {
				p, srcPos, err = rb.rollBlock()
				rs.Init()
				if err != nil {
					break
				}
				rs.Update(p)
			}
		}
	} else if err == noBytesLeft {
		// reader没有内容
		if d.debug {
			fmt.Println("reader has no content:", srcLen)
		}
		err = nil
		return
	}

	if err != noBytesLeft && err != notEnoughBytes {
		// 出错
		return
	}

	if d.debug {
		fmt.Printf("rotate buffer left no more than a block: block=%d start=%d end=%d absHead=%d absTail=%d eof=%v\n",
			blockLen, rb.start, rb.end, rb.absHead, rb.absTail, rb.eof)
	}

	if p, c, srcPos, err = rb.rollLeft(); err == nil {
		rs.Init()
		rs.Update(p)

		for err == nil {
			matchAt = d.findMatch(p, srcPos, rs.Digest())

			if matchAt >= 0 {
				// 剩余的内容已经匹配到,不需要继续处理
				break
			} else {
				p, c, srcPos, err = rb.rollLeft()
				if err != nil {
					break
				}
				rs.Rollout(c)
			}
		}
	} else {
		if d.debug {
			fmt.Println(string(p), c, srcPos, err)
		}
	}

	if err == noBytesLeft || err == nil {
		if d.debug {
			fmt.Println("last match stat:", d.ms.match, d.ms.pos, d.ms.length)
		}
		d.mss = append(d.mss, d.ms)
		err = nil
	}

	return
}