mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:34:14 +08:00
mdbx: микро-оптимизация cmp_reverse()
.
This commit is contained in:
parent
bcddeaba9f
commit
8519fde741
54
src/core.c
54
src/core.c
@ -11894,16 +11894,54 @@ tail3le(const uint8_t *p, size_t l) {
|
|||||||
|
|
||||||
/* Compare two items in reverse byte order */
|
/* Compare two items in reverse byte order */
|
||||||
__hot static int cmp_reverse(const MDBX_val *a, const MDBX_val *b) {
|
__hot static int cmp_reverse(const MDBX_val *a, const MDBX_val *b) {
|
||||||
const size_t shortest = (a->iov_len < b->iov_len) ? a->iov_len : b->iov_len;
|
size_t left = (a->iov_len < b->iov_len) ? a->iov_len : b->iov_len;
|
||||||
if (likely(shortest)) {
|
if (likely(left)) {
|
||||||
const uint8_t *pa = ptr_disp(a->iov_base, a->iov_len);
|
const uint8_t *pa = ptr_disp(a->iov_base, a->iov_len);
|
||||||
const uint8_t *pb = ptr_disp(b->iov_base, b->iov_len);
|
const uint8_t *pb = ptr_disp(b->iov_base, b->iov_len);
|
||||||
const uint8_t *const end = pa - shortest;
|
while (left >= sizeof(size_t)) {
|
||||||
do {
|
pa -= sizeof(size_t);
|
||||||
int diff = *--pa - *--pb;
|
pb -= sizeof(size_t);
|
||||||
if (likely(diff))
|
left -= sizeof(size_t);
|
||||||
return diff;
|
STATIC_ASSERT(sizeof(size_t) == 4 || sizeof(size_t) == 8);
|
||||||
} while (pa != end);
|
if (sizeof(size_t) == 4) {
|
||||||
|
uint32_t xa = unaligned_peek_u32(1, pa);
|
||||||
|
uint32_t xb = unaligned_peek_u32(1, pb);
|
||||||
|
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||||
|
xa = osal_bswap32(xa);
|
||||||
|
xb = osal_bswap32(xb);
|
||||||
|
#endif /* __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ */
|
||||||
|
if (xa != xb)
|
||||||
|
return (xa < xb) ? -1 : 1;
|
||||||
|
} else {
|
||||||
|
uint64_t xa = unaligned_peek_u64(1, pa);
|
||||||
|
uint64_t xb = unaligned_peek_u64(1, pb);
|
||||||
|
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||||
|
xa = osal_bswap64(xa);
|
||||||
|
xb = osal_bswap64(xb);
|
||||||
|
#endif /* __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ */
|
||||||
|
if (xa != xb)
|
||||||
|
return (xa < xb) ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sizeof(size_t) == 8 && left >= 4) {
|
||||||
|
pa -= 4;
|
||||||
|
pb -= 4;
|
||||||
|
left -= 4;
|
||||||
|
uint32_t xa = unaligned_peek_u32(1, pa);
|
||||||
|
uint32_t xb = unaligned_peek_u32(1, pb);
|
||||||
|
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||||
|
xa = osal_bswap32(xa);
|
||||||
|
xb = osal_bswap32(xb);
|
||||||
|
#endif /* __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ */
|
||||||
|
if (xa != xb)
|
||||||
|
return (xa < xb) ? -1 : 1;
|
||||||
|
}
|
||||||
|
if (left) {
|
||||||
|
unsigned xa = tail3le(pa - left, left);
|
||||||
|
unsigned xb = tail3le(pb - left, left);
|
||||||
|
if (xa != xb)
|
||||||
|
return (xa < xb) ? -1 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return CMP2INT(a->iov_len, b->iov_len);
|
return CMP2INT(a->iov_len, b->iov_len);
|
||||||
}
|
}
|
||||||
|
40
src/osal.h
40
src/osal.h
@ -890,6 +890,46 @@ MDBX_INTERNAL_VAR MDBX_SetFileIoOverlappedRange mdbx_SetFileIoOverlappedRange;
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint64_t
|
||||||
|
osal_bswap64(uint64_t v) {
|
||||||
|
#if __GNUC_PREREQ(4, 4) || __CLANG_PREREQ(4, 0) || \
|
||||||
|
__has_builtin(__builtin_bswap64)
|
||||||
|
return __builtin_bswap64(v);
|
||||||
|
#elif defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
return _byteswap_uint64(v);
|
||||||
|
#elif defined(__bswap_64)
|
||||||
|
return __bswap_64(v);
|
||||||
|
#elif defined(bswap_64)
|
||||||
|
return bswap_64(v);
|
||||||
|
#else
|
||||||
|
return v << 56 | v >> 56 | ((v << 40) & UINT64_C(0x00ff000000000000)) |
|
||||||
|
((v << 24) & UINT64_C(0x0000ff0000000000)) |
|
||||||
|
((v << 8) & UINT64_C(0x000000ff00000000)) |
|
||||||
|
((v >> 8) & UINT64_C(0x00000000ff000000)) |
|
||||||
|
((v >> 24) & UINT64_C(0x0000000000ff0000)) |
|
||||||
|
((v >> 40) & UINT64_C(0x000000000000ff00));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint32_t
|
||||||
|
osal_bswap32(uint32_t v) {
|
||||||
|
#if __GNUC_PREREQ(4, 4) || __CLANG_PREREQ(4, 0) || \
|
||||||
|
__has_builtin(__builtin_bswap32)
|
||||||
|
return __builtin_bswap32(v);
|
||||||
|
#elif defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
return _byteswap_ulong(v);
|
||||||
|
#elif defined(__bswap_32)
|
||||||
|
return __bswap_32(v);
|
||||||
|
#elif defined(bswap_32)
|
||||||
|
return bswap_32(v);
|
||||||
|
#else
|
||||||
|
return v << 24 | v >> 24 | ((v << 8) & UINT32_C(0x00ff0000)) |
|
||||||
|
((v >> 8) & UINT32_C(0x0000ff00));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
/* LY: MSVC 2015/2017/2019 has buggy/inconsistent PRIuPTR/PRIxPTR macros
|
/* LY: MSVC 2015/2017/2019 has buggy/inconsistent PRIuPTR/PRIxPTR macros
|
||||||
* for internal format-args checker. */
|
* for internal format-args checker. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user