FingerprintTest.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. #include <folly/Fingerprint.h>
  17. #include <glog/logging.h>
  18. #include <folly/Benchmark.h>
  19. #include <folly/detail/SlowFingerprint.h>
  20. #include <folly/portability/GTest.h>
  21. using namespace folly;
  22. using namespace folly::detail;
  23. TEST(Fingerprint, BroderOptimization) {
  24. // Test that the Broder optimization produces the same result as
  25. // the default (slow) implementation that processes one bit at a time.
  26. uint64_t val_a = 0xfaceb00cdeadbeefUL;
  27. uint64_t val_b = 0x1234567890abcdefUL;
  28. uint64_t slow[2];
  29. uint64_t fast[2];
  30. SlowFingerprint<64>().update64(val_a).update64(val_b).write(slow);
  31. Fingerprint<64>().update64(val_a).update64(val_b).write(fast);
  32. EXPECT_EQ(slow[0], fast[0]);
  33. SlowFingerprint<96>().update64(val_a).update64(val_b).write(slow);
  34. Fingerprint<96>().update64(val_a).update64(val_b).write(fast);
  35. EXPECT_EQ(slow[0], fast[0]);
  36. EXPECT_EQ(slow[1], fast[1]);
  37. SlowFingerprint<128>().update64(val_a).update64(val_b).write(slow);
  38. Fingerprint<128>().update64(val_a).update64(val_b).write(fast);
  39. EXPECT_EQ(slow[0], fast[0]);
  40. EXPECT_EQ(slow[1], fast[1]);
  41. }
  42. TEST(Fingerprint, MultiByteUpdate) {
  43. // Test that the multi-byte update functions (update32, update64,
  44. // update(StringPiece)) produce the same result as calling update8
  45. // repeatedly.
  46. uint64_t val_a = 0xfaceb00cdeadbeefUL;
  47. uint64_t val_b = 0x1234567890abcdefUL;
  48. uint8_t bytes[16];
  49. for (int i = 0; i < 8; i++) {
  50. bytes[i] = (val_a >> (8 * (7 - i))) & 0xff;
  51. }
  52. for (int i = 0; i < 8; i++) {
  53. bytes[i + 8] = (val_b >> (8 * (7 - i))) & 0xff;
  54. }
  55. StringPiece sp((const char*)bytes, 16);
  56. uint64_t u8[2]; // updating 8 bits at a time
  57. uint64_t u32[2]; // updating 32 bits at a time
  58. uint64_t u64[2]; // updating 64 bits at a time
  59. uint64_t usp[2]; // update(StringPiece)
  60. uint64_t uconv[2]; // convenience function (fingerprint*(StringPiece))
  61. {
  62. Fingerprint<64> fp;
  63. for (int i = 0; i < 16; i++) {
  64. fp.update8(bytes[i]);
  65. }
  66. fp.write(u8);
  67. }
  68. Fingerprint<64>()
  69. .update32(val_a >> 32)
  70. .update32(val_a & 0xffffffff)
  71. .update32(val_b >> 32)
  72. .update32(val_b & 0xffffffff)
  73. .write(u32);
  74. Fingerprint<64>().update64(val_a).update64(val_b).write(u64);
  75. Fingerprint<64>().update(sp).write(usp);
  76. uconv[0] = fingerprint64(sp);
  77. EXPECT_EQ(u8[0], u32[0]);
  78. EXPECT_EQ(u8[0], u64[0]);
  79. EXPECT_EQ(u8[0], usp[0]);
  80. EXPECT_EQ(u8[0], uconv[0]);
  81. {
  82. Fingerprint<96> fp;
  83. for (int i = 0; i < 16; i++) {
  84. fp.update8(bytes[i]);
  85. }
  86. fp.write(u8);
  87. }
  88. Fingerprint<96>()
  89. .update32(val_a >> 32)
  90. .update32(val_a & 0xffffffff)
  91. .update32(val_b >> 32)
  92. .update32(val_b & 0xffffffff)
  93. .write(u32);
  94. Fingerprint<96>().update64(val_a).update64(val_b).write(u64);
  95. Fingerprint<96>().update(sp).write(usp);
  96. uint32_t uconv_lsb;
  97. fingerprint96(sp, &(uconv[0]), &uconv_lsb);
  98. uconv[1] = (uint64_t)uconv_lsb << 32;
  99. EXPECT_EQ(u8[0], u32[0]);
  100. EXPECT_EQ(u8[1], u32[1]);
  101. EXPECT_EQ(u8[0], u64[0]);
  102. EXPECT_EQ(u8[1], u64[1]);
  103. EXPECT_EQ(u8[0], usp[0]);
  104. EXPECT_EQ(u8[1], usp[1]);
  105. EXPECT_EQ(u8[0], uconv[0]);
  106. EXPECT_EQ(u8[1], uconv[1]);
  107. {
  108. Fingerprint<128> fp;
  109. for (int i = 0; i < 16; i++) {
  110. fp.update8(bytes[i]);
  111. }
  112. fp.write(u8);
  113. }
  114. Fingerprint<128>()
  115. .update32(val_a >> 32)
  116. .update32(val_a & 0xffffffff)
  117. .update32(val_b >> 32)
  118. .update32(val_b & 0xffffffff)
  119. .write(u32);
  120. Fingerprint<128>().update64(val_a).update64(val_b).write(u64);
  121. Fingerprint<128>().update(sp).write(usp);
  122. fingerprint128(sp, &(uconv[0]), &(uconv[1]));
  123. EXPECT_EQ(u8[0], u32[0]);
  124. EXPECT_EQ(u8[1], u32[1]);
  125. EXPECT_EQ(u8[0], u64[0]);
  126. EXPECT_EQ(u8[1], u64[1]);
  127. EXPECT_EQ(u8[0], usp[0]);
  128. EXPECT_EQ(u8[1], usp[1]);
  129. EXPECT_EQ(u8[0], uconv[0]);
  130. EXPECT_EQ(u8[1], uconv[1]);
  131. }
  132. TEST(Fingerprint, Alignment) {
  133. // Test that update() gives the same result regardless of string alignment
  134. const char test_str[] = "hello world 12345";
  135. int len = sizeof(test_str) - 1;
  136. std::unique_ptr<char[]> str(new char[len + 8]);
  137. uint64_t ref_fp;
  138. SlowFingerprint<64>().update(StringPiece(test_str, len)).write(&ref_fp);
  139. for (int i = 0; i < 8; i++) {
  140. char* p = str.get();
  141. char* q;
  142. // Fill the string as !!hello??????
  143. for (int j = 0; j < i; j++) {
  144. *p++ = '!';
  145. }
  146. q = p;
  147. for (int j = 0; j < len; j++) {
  148. *p++ = test_str[j];
  149. }
  150. for (int j = i; j < 8; j++) {
  151. *p++ = '?';
  152. }
  153. uint64_t fp;
  154. Fingerprint<64>().update(StringPiece(q, len)).write(&fp);
  155. EXPECT_EQ(ref_fp, fp);
  156. }
  157. }
  158. int main(int argc, char* argv[]) {
  159. testing::InitGoogleTest(&argc, argv);
  160. gflags::ParseCommandLineFlags(&argc, &argv, true);
  161. auto ret = RUN_ALL_TESTS();
  162. if (!ret) {
  163. folly::runBenchmarksOnFlag();
  164. }
  165. return ret;
  166. }