summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/util/file_checksum_helper.h
blob: 7ad9ea7323e5e6d25a05e047510872902e5cb6fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).

#pragma once
#include <cassert>
#include <unordered_map>
#include "port/port.h"
#include "rocksdb/file_checksum.h"
#include "rocksdb/status.h"
#include "util/crc32c.h"
#include "util/string_util.h"

namespace ROCKSDB_NAMESPACE {

// This is the class to generate the file checksum based on Crc32. It
// will be used as the default checksum method for SST file checksum
class FileChecksumFuncCrc32c : public FileChecksumFunc {
 public:
  std::string Extend(const std::string& init_checksum, const char* data,
                     size_t n) override {
    assert(data != nullptr);
    uint32_t checksum_value = StringToUint32(init_checksum);
    return Uint32ToString(crc32c::Extend(checksum_value, data, n));
  }

  std::string Value(const char* data, size_t n) override {
    assert(data != nullptr);
    return Uint32ToString(crc32c::Value(data, n));
  }

  std::string ProcessChecksum(const std::string& checksum) override {
    uint32_t checksum_value = StringToUint32(checksum);
    return Uint32ToString(crc32c::Mask(checksum_value));
  }

  const char* Name() const override { return "FileChecksumCrc32c"; }

  // Convert a uint32_t type data into a 4 bytes string.
  static std::string Uint32ToString(uint32_t v) {
    std::string s;
    if (port::kLittleEndian) {
      s.append(reinterpret_cast<char*>(&v), sizeof(v));
    } else {
      char buf[sizeof(v)];
      buf[0] = v & 0xff;
      buf[1] = (v >> 8) & 0xff;
      buf[2] = (v >> 16) & 0xff;
      buf[3] = (v >> 24) & 0xff;
      s.append(buf, sizeof(v));
    }
    size_t i = 0, j = s.size() - 1;
    while (i < j) {
      char tmp = s[i];
      s[i] = s[j];
      s[j] = tmp;
      ++i;
      --j;
    }
    return s;
  }

  // Convert a 4 bytes size string into a uint32_t type data.
  static uint32_t StringToUint32(std::string s) {
    assert(s.size() == sizeof(uint32_t));
    size_t i = 0, j = s.size() - 1;
    while (i < j) {
      char tmp = s[i];
      s[i] = s[j];
      s[j] = tmp;
      ++i;
      --j;
    }
    uint32_t v = 0;
    if (port::kLittleEndian) {
      memcpy(&v, s.c_str(), sizeof(uint32_t));
    } else {
      const char* buf = s.c_str();
      v |= static_cast<uint32_t>(buf[0]);
      v |= (static_cast<uint32_t>(buf[1]) << 8);
      v |= (static_cast<uint32_t>(buf[2]) << 16);
      v |= (static_cast<uint32_t>(buf[3]) << 24);
    }
    return v;
  }
};

// The default implementaion of FileChecksumList
class FileChecksumListImpl : public FileChecksumList {
 public:
  FileChecksumListImpl() {}
  void reset() override;

  size_t size() const override;

  Status GetAllFileChecksums(
      std::vector<uint64_t>* file_numbers, std::vector<std::string>* checksums,
      std::vector<std::string>* checksum_func_names) override;

  Status SearchOneFileChecksum(uint64_t file_number, std::string* checksum,
                               std::string* checksum_func_name) override;

  Status InsertOneFileChecksum(uint64_t file_number,
                               const std::string& checksum,
                               const std::string& checksum_func_name) override;

  Status RemoveOneFileChecksum(uint64_t file_number) override;

 private:
  // Key is the file number, the first portion of the value is checksum, the
  // second portion of the value is checksum function name.
  std::unordered_map<uint64_t, std::pair<std::string, std::string>>
      checksum_map_;
};

}  // namespace ROCKSDB_NAMESPACE