Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbfb54ff

Browse files
committed
Make abbreviated key comparisons for text a bit cheaper.
If we do some byte-swapping while abbreviating, we can do comparisonsusing integer arithmetic rather than memcmp.Peter Geoghegan, reviewed and slightly revised by me.
1 parentdb0f6ca commitbfb54ff

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

‎src/backend/utils/adt/varlena.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include"libpq/pqformat.h"
2727
#include"miscadmin.h"
2828
#include"parser/scansup.h"
29+
#include"port/pg_bswap.h"
2930
#include"regex/regex.h"
3031
#include"utils/builtins.h"
3132
#include"utils/bytea.h"
@@ -1967,25 +1968,25 @@ bttextfastcmp_locale(Datum x, Datum y, SortSupport ssup)
19671968
staticint
19681969
bttextcmp_abbrev(Datumx,Datumy,SortSupportssup)
19691970
{
1970-
char*a= (char*)&x;
1971-
char*b= (char*)&y;
1972-
intresult;
1973-
1974-
result=memcmp(a,b,sizeof(Datum));
1975-
19761971
/*
1977-
* Whenresult = 0, the core system will call bttextfastcmp_c() or
1972+
* When0 is returned, the core system will call bttextfastcmp_c() or
19781973
* bttextfastcmp_locale(). Even a strcmp() on two non-truncated strxfrm()
19791974
* blobs cannot indicate *equality* authoritatively, for the same reason
19801975
* that there is a strcoll() tie-breaker call to strcmp() in varstr_cmp().
19811976
*/
1982-
returnresult;
1977+
if (x>y)
1978+
return1;
1979+
elseif (x==y)
1980+
return0;
1981+
else
1982+
return-1;
19831983
}
19841984

19851985
/*
19861986
* Conversion routine for sortsupport. Converts original text to abbreviated
19871987
* key representation. Our encoding strategy is simple -- pack the first 8
1988-
* bytes of a strxfrm() blob into a Datum.
1988+
* bytes of a strxfrm() blob into a Datum (on little-endian machines, the 8
1989+
* bytes are stored in reverse order), and treat it as an unsigned integer.
19891990
*/
19901991
staticDatum
19911992
bttext_abbrev_convert(Datumoriginal,SortSupportssup)
@@ -2104,6 +2105,16 @@ bttext_abbrev_convert(Datum original, SortSupport ssup)
21042105

21052106
addHyperLogLog(&tss->abbr_card,hash);
21062107

2108+
/*
2109+
* Byteswap on little-endian machines.
2110+
*
2111+
* This is needed so that bttextcmp_abbrev() (an unsigned integer 3-way
2112+
* comparator) works correctly on all platforms. If we didn't do this,
2113+
* the comparator would have to call memcmp() with a pair of pointers to
2114+
* the first byte of each abbreviated key, which is slower.
2115+
*/
2116+
res=DatumBigEndianToNative(res);
2117+
21072118
/* Don't leak memory here */
21082119
if (PointerGetDatum(authoritative)!=original)
21092120
pfree(authoritative);

‎src/include/port/pg_bswap.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
((x << 8) & 0x00ff0000) | \
2929
((x >> 8) & 0x0000ff00) | \
3030
((x >> 24) & 0x000000ff))
31-
#endif/* HAVE__BUILTIN_BSWAP32 */
31+
#endif/* HAVE__BUILTIN_BSWAP32 */
3232

3333
#ifdefHAVE__BUILTIN_BSWAP64
3434
#defineBSWAP64(x) __builtin_bswap64(x)
@@ -41,6 +41,28 @@
4141
((x >> 24) & 0x0000000000ff0000UL) | \
4242
((x >> 40) & 0x000000000000ff00UL) | \
4343
((x >> 56) & 0x00000000000000ffUL))
44-
#endif/* HAVE__BUILTIN_BSWAP64 */
44+
#endif/* HAVE__BUILTIN_BSWAP64 */
45+
46+
/*
47+
* Rearrange the bytes of a Datum from big-endian order into the native byte
48+
* order. On big-endian machines, this does nothing at all. Note that the C
49+
* type Datum is an unsigned integer type on all platforms.
50+
*
51+
* One possible application of the DatumBigEndianToNative() macro is to make
52+
* bitwise comparisons cheaper. A simple 3-way comparison of Datums
53+
* transformed by the macro (based on native, unsigned comparisons) will return
54+
* the same result as a memcmp() of the corresponding original Datums, but can
55+
* be much cheaper. It's generally safe to do this on big-endian systems
56+
* without any special transformation occurring first.
57+
*/
58+
#ifdefWORDS_BIGENDIAN
59+
#defineDatumBigEndianToNative(x)(x)
60+
#else/* !WORDS_BIGENDIAN */
61+
#ifSIZEOF_DATUM==8
62+
#defineDatumBigEndianToNative(x)BSWAP64(x)
63+
#else/* SIZEOF_DATUM != 8 */
64+
#defineDatumBigEndianToNative(x)BSWAP32(x)
65+
#endif/* SIZEOF_DATUM == 8 */
66+
#endif/* WORDS_BIGENDIAN */
4567

4668
#endif/* PG_BSWAP_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp