/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Compute 64-, 96-, and 128-bit Rabin fingerprints, as described in * Michael O. Rabin (1981) * Fingerprinting by Random Polynomials * Center for Research in Computing Technology, Harvard University * Tech Report TR-CSE-03-01 * * The implementation follows the optimization described in * Andrei Z. Broder (1993) * Some applications of Rabin's fingerprinting method * * extended for fingerprints larger than 64 bits, and modified to use * 64-bit instead of 32-bit integers for computation. * * The precomputed tables are in Fingerprint.cpp. * * Benchmarked on 10/13/2009 on a 2.5GHz quad-core Xeon L5420, * - Fingerprint<64>::update64() takes about 12ns * - Fingerprint<96>::update64() takes about 30ns * - Fingerprint<128>::update128() takes about 30ns * (unsurprisingly, Fingerprint<96> and Fingerprint<128> take the * same amount of time, as they both use 128-bit operations; the least * significant 32 bits of Fingerprint<96> will always be 0) */ #pragma once #include <array> #include <cstdint> #include <folly/Range.h> namespace folly { detail // namespace detail /** * Compute the Rabin fingerprint. * * TODO(tudorb): Extend this to allow removing values from the computed * fingerprint (so we can fingerprint a sliding window, as in the Rabin-Karp * string matching algorithm) * * update* methods return *this, so you can chain them together: * Fingerprint<96>().update8(x).update(str).update64(val).write(output); */ template <int BITS> class Fingerprint { … }; // Convenience functions /** * Return the 64-bit Rabin fingerprint of a string. */ inline uint64_t fingerprint64(StringPiece str) { … } /** * Compute the 96-bit Rabin fingerprint of a string. * Return the 64 most significant bits in *msb, and the 32 least significant * bits in *lsb. */ inline void fingerprint96(StringPiece str, uint64_t* msb, uint32_t* lsb) { … } /** * Compute the 128-bit Rabin fingerprint of a string. * Return the 64 most significant bits in *msb, and the 64 least significant * bits in *lsb. */ inline void fingerprint128(StringPiece str, uint64_t* msb, uint64_t* lsb) { … } template <> inline uint8_t Fingerprint<64>::shlor8(uint8_t v) { … } template <> inline uint32_t Fingerprint<64>::shlor32(uint32_t v) { … } template <> inline uint64_t Fingerprint<64>::shlor64(uint64_t v) { … } template <> inline uint8_t Fingerprint<96>::shlor8(uint8_t v) { … } template <> inline uint32_t Fingerprint<96>::shlor32(uint32_t v) { … } template <> inline uint64_t Fingerprint<96>::shlor64(uint64_t v) { … } template <> inline uint8_t Fingerprint<128>::shlor8(uint8_t v) { … } template <> inline uint32_t Fingerprint<128>::shlor32(uint32_t v) { … } template <> inline uint64_t Fingerprint<128>::shlor64(uint64_t v) { … } } // namespace folly