Changeset View
Changeset View
Standalone View
Standalone View
src/leveldb/util/crc32c.cc
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | ||||
// Use of this source code is governed by a BSD-style license that can be | // Use of this source code is governed by a BSD-style license that can be | ||||
// found in the LICENSE file. See the AUTHORS file for names of contributors. | // found in the LICENSE file. See the AUTHORS file for names of contributors. | ||||
// | // | ||||
// A portable implementation of crc32c, optimized to handle | // A portable implementation of crc32c, optimized to handle | ||||
// four bytes at a time. | // four bytes at a time. | ||||
#include "util/crc32c.h" | #include "util/crc32c.h" | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include "port/port.h" | |||||
#include "util/coding.h" | #include "util/coding.h" | ||||
namespace leveldb { | namespace leveldb { | ||||
namespace crc32c { | namespace crc32c { | ||||
static const uint32_t table0_[256] = { | static const uint32_t table0_[256] = { | ||||
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, | 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, | ||||
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, | 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, | ||||
▲ Show 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | static const uint32_t table3_[256] = { | ||||
0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842 | 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842 | ||||
}; | }; | ||||
// Used to fetch a naturally-aligned 32-bit word in little endian byte-order | // Used to fetch a naturally-aligned 32-bit word in little endian byte-order | ||||
static inline uint32_t LE_LOAD32(const uint8_t *p) { | static inline uint32_t LE_LOAD32(const uint8_t *p) { | ||||
return DecodeFixed32(reinterpret_cast<const char*>(p)); | return DecodeFixed32(reinterpret_cast<const char*>(p)); | ||||
} | } | ||||
// Determine if the CPU running this program can accelerate the CRC32C | |||||
// calculation. | |||||
static bool CanAccelerateCRC32C() { | |||||
// port::AcceleretedCRC32C returns zero when unable to accelerate. | |||||
static const char kTestCRCBuffer[] = "TestCRCBuffer"; | |||||
static const char kBufSize = sizeof(kTestCRCBuffer) - 1; | |||||
static const uint32_t kTestCRCValue = 0xdcbc59fa; | |||||
return port::AcceleratedCRC32C(0, kTestCRCBuffer, kBufSize) == kTestCRCValue; | |||||
} | |||||
uint32_t Extend(uint32_t crc, const char* buf, size_t size) { | uint32_t Extend(uint32_t crc, const char* buf, size_t size) { | ||||
static bool accelerate = CanAccelerateCRC32C(); | |||||
if (accelerate) { | |||||
return port::AcceleratedCRC32C(crc, buf, size); | |||||
} | |||||
const uint8_t *p = reinterpret_cast<const uint8_t *>(buf); | const uint8_t *p = reinterpret_cast<const uint8_t *>(buf); | ||||
const uint8_t *e = p + size; | const uint8_t *e = p + size; | ||||
uint32_t l = crc ^ 0xffffffffu; | uint32_t l = crc ^ 0xffffffffu; | ||||
#define STEP1 do { \ | #define STEP1 do { \ | ||||
int c = (l & 0xff) ^ *p++; \ | int c = (l & 0xff) ^ *p++; \ | ||||
l = table0_[c] ^ (l >> 8); \ | l = table0_[c] ^ (l >> 8); \ | ||||
} while (0) | } while (0) | ||||
Show All 38 Lines |