proxygen
FingerprintPolynomial.h
Go to the documentation of this file.
1 /*
2  * Copyright 2012-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstdint>
20 
21 namespace folly {
22 namespace detail {
23 
31 template <int DEG>
33  public:
34  static constexpr int size() {
35  return 1 + DEG / 64;
36  }
37 
38  constexpr FingerprintPolynomial() {}
39 
40  constexpr explicit FingerprintPolynomial(const uint64_t (&vals)[size()]) {
41  for (int i = 0; i < size(); i++) {
42  val_[i] = vals[i];
43  }
44  }
45 
46  constexpr uint64_t get(size_t i) const {
47  return val_[i];
48  }
49 
50  constexpr void add(const FingerprintPolynomial<DEG>& other) {
51  for (int i = 0; i < size(); i++) {
52  val_[i] ^= other.val_[i];
53  }
54  }
55 
56  // Multiply by X. The actual degree must be < DEG.
57  constexpr void mulX() {
58  uint64_t b = 0;
59  for (int i = size() - 1; i >= 0; i--) {
60  uint64_t nb = val_[i] >> 63;
61  val_[i] = (val_[i] << 1) | b;
62  b = nb;
63  }
64  }
65 
66  // Compute (this * X) mod P(X), where P(X) is a monic polynomial of degree
67  // DEG+1 (represented as a FingerprintPolynomial<DEG> object, with the
68  // implicit coefficient of X^(DEG+1)==1)
69  //
70  // This is a bit tricky. If k=DEG+1:
71  // Let P(X) = X^k + p_(k-1) * X^(k-1) + ... + p_1 * X + p_0
72  // Let this = A(X) = a_(k-1) * X^(k-1) + ... + a_1 * X + a_0
73  // Then:
74  // A(X) * X
75  // = a_(k-1) * X^k + (a_(k-2) * X^(k-1) + ... + a_1 * X^2 + a_0 * X)
76  // = a_(k-1) * X^k + (the binary representation of A, left shift by 1)
77  //
78  // if a_(k-1) = 0, we can ignore the first term.
79  // if a_(k-1) = 1, then:
80  // X^k mod P(X)
81  // = X^k - P(X)
82  // = P(X) - X^k
83  // = p_(k-1) * X^(k-1) + ... + p_1 * X + p_0
84  // = exactly the binary representation passed in as an argument to this
85  // function!
86  //
87  // So A(X) * X mod P(X) is:
88  // the binary representation of A, left shift by 1,
89  // XOR p if a_(k-1) == 1
90  constexpr void mulXmod(const FingerprintPolynomial<DEG>& p) {
91  bool needXOR = (val_[0] & (1ULL << 63));
92  val_[0] &= ~(1ULL << 63);
93  mulX();
94  if (needXOR) {
95  add(p);
96  }
97  }
98 
99  // Compute (this * X^k) mod P(X) by repeatedly multiplying by X (see above)
100  constexpr void mulXkmod(int k, const FingerprintPolynomial<DEG>& p) {
101  for (int i = 0; i < k; i++) {
102  mulXmod(p);
103  }
104  }
105 
106  // add X^k, where k <= DEG
107  constexpr void addXk(int k) {
108  int word_offset = (DEG - k) / 64;
109  int bit_offset = 63 - (DEG - k) % 64;
110  val_[word_offset] ^= (1ULL << bit_offset);
111  }
112 
113  // Set the highest 8 bits to val.
114  // If val is interpreted as polynomial of degree 7, then this sets *this
115  // to val * X^(DEG-7)
116  constexpr void setHigh8Bits(uint8_t val) {
117  val_[0] = ((uint64_t)val) << (64 - 8);
118  for (int i = 1; i < size(); i++) {
119  val_[i] = 0;
120  }
121  }
122 
123  private:
124  // Internal representation: big endian
125  // val_[0] contains the highest order coefficients, with bit 63 as the
126  // highest order coefficient
127  //
128  // If DEG+1 is not a multiple of 64, val_[size()-1] only uses the highest
129  // order (DEG+1)%64 bits (the others are always 0)
130  uint64_t val_[size()] = {};
131 };
132 
133 } // namespace detail
134 } // namespace folly
constexpr void add(const FingerprintPolynomial< DEG > &other)
constexpr void setHigh8Bits(uint8_t val)
constexpr void mulXmod(const FingerprintPolynomial< DEG > &p)
char b
constexpr FingerprintPolynomial(const uint64_t(&vals)[size()])
double val
Definition: String.cpp:273
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
constexpr void mulXkmod(int k, const FingerprintPolynomial< DEG > &p)
KeyT k