github.com/pingcap/tidb-lightning@v5.0.0-rc.0.20210428090220-84b649866577+incompatible/lightning/verification/checksum.go (about)

     1  // Copyright 2019 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package verification
    15  
    16  import (
    17  	"fmt"
    18  	"hash/crc64"
    19  
    20  	"go.uber.org/zap/zapcore"
    21  
    22  	"github.com/pingcap/tidb-lightning/lightning/common"
    23  )
    24  
    25  var ecmaTable = crc64.MakeTable(crc64.ECMA)
    26  
    27  type KVChecksum struct {
    28  	bytes    uint64
    29  	kvs      uint64
    30  	checksum uint64
    31  }
    32  
    33  func NewKVChecksum(checksum uint64) *KVChecksum {
    34  	return &KVChecksum{
    35  		checksum: checksum,
    36  	}
    37  }
    38  
    39  func MakeKVChecksum(bytes uint64, kvs uint64, checksum uint64) KVChecksum {
    40  	return KVChecksum{
    41  		bytes:    bytes,
    42  		kvs:      kvs,
    43  		checksum: checksum,
    44  	}
    45  }
    46  
    47  func (c *KVChecksum) UpdateOne(kv common.KvPair) {
    48  	sum := crc64.Update(0, ecmaTable, kv.Key)
    49  	sum = crc64.Update(sum, ecmaTable, kv.Val)
    50  
    51  	c.bytes += uint64(len(kv.Key) + len(kv.Val))
    52  	c.kvs++
    53  	c.checksum ^= sum
    54  }
    55  
    56  func (c *KVChecksum) Update(kvs []common.KvPair) {
    57  	var (
    58  		checksum uint64
    59  		sum      uint64
    60  		kvNum    int
    61  		bytes    int
    62  	)
    63  
    64  	for _, pair := range kvs {
    65  		sum = crc64.Update(0, ecmaTable, pair.Key)
    66  		sum = crc64.Update(sum, ecmaTable, pair.Val)
    67  		checksum ^= sum
    68  		kvNum++
    69  		bytes += (len(pair.Key) + len(pair.Val))
    70  	}
    71  
    72  	c.bytes += uint64(bytes)
    73  	c.kvs += uint64(kvNum)
    74  	c.checksum ^= checksum
    75  }
    76  
    77  func (c *KVChecksum) Add(other *KVChecksum) {
    78  	c.bytes += other.bytes
    79  	c.kvs += other.kvs
    80  	c.checksum ^= other.checksum
    81  }
    82  
    83  func (c *KVChecksum) Sum() uint64 {
    84  	return c.checksum
    85  }
    86  
    87  func (c *KVChecksum) SumSize() uint64 {
    88  	return c.bytes
    89  }
    90  
    91  func (c *KVChecksum) SumKVS() uint64 {
    92  	return c.kvs
    93  }
    94  
    95  // MarshalLogObject implements the zapcore.ObjectMarshaler interface.
    96  func (c *KVChecksum) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
    97  	encoder.AddUint64("cksum", c.checksum)
    98  	encoder.AddUint64("size", c.bytes)
    99  	encoder.AddUint64("kvs", c.kvs)
   100  	return nil
   101  }
   102  
   103  // MarshalJSON implements the json.Marshaler interface.
   104  func (c KVChecksum) MarshalJSON() ([]byte, error) {
   105  	result := fmt.Sprintf(`{"checksum":%d,"size":%d,"kvs":%d}`, c.checksum, c.bytes, c.kvs)
   106  	return []byte(result), nil
   107  }