mirror of
https://github.com/MariaDB/server.git
synced 2025-09-15 22:02:21 +02:00
72 lines
2.6 KiB
C++
72 lines
2.6 KiB
C++
/*****************************************************************************
|
|
|
|
Copyright (c) 2024 Kristian Nielsen.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
Reading and writing of compressed integers.
|
|
|
|
Created 2024-10-01 Kristian Nielsen <knielsen@knielsen-hq.org>
|
|
*/
|
|
|
|
#ifndef MY_COMPR_INT_H
|
|
#define MY_COMPR_INT_H
|
|
|
|
#include "my_bit.h"
|
|
#include <stdint.h>
|
|
#include <utility>
|
|
|
|
|
|
/*
|
|
Read and write compressed (up to) 64-bit integers.
|
|
|
|
A 64-bit number is encoded with 1-9 bytes. The 3 first bits stores a tag
|
|
that determines the number of bytes used, and the encoding is written in
|
|
little-endian format as (TAG | (NUMBER << 3)). The tag is the number of
|
|
bytes used minus 1, except that 7 denotes 9 bytes used (numbers are never
|
|
encoded with 8 bytes). For example:
|
|
|
|
Number Encoding
|
|
0 0x00
|
|
0x1f 0xf8 (0 | (0x1f << 3))
|
|
0x20 0x01 0x01
|
|
0xf6 0xb1 0x07
|
|
0xd34a 0x52 0x9a 0x06
|
|
0x1fffffffffffff 0xfe 0xff 0xff 0xff 0xff 0xff 0xff
|
|
0x20000000000000 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00
|
|
0xffffffffffffffff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x07
|
|
|
|
The main advantage over something like base-128 compression (also called
|
|
varint) is that the encoding and decoding can happen with just a single
|
|
conditional jump to determine if one or two 64-bit words are involved (or
|
|
even no or only well-predicted conditional jump if unaligned reads/writes
|
|
and buffer padding can be assumed).
|
|
*/
|
|
|
|
#define COMPR_INT_MAX32 5
|
|
#define COMPR_INT_MAX64 9
|
|
#define COMPR_INT_MAX COMPR_INT_MAX64
|
|
|
|
/* Write compressed unsigned integer */
|
|
extern unsigned char *compr_int_write(unsigned char *p, uint64_t v);
|
|
/*
|
|
Read compressed integer.
|
|
Returns a pair of the value read and the incremented pointer.
|
|
*/
|
|
extern std::pair<uint64_t, const unsigned char *>
|
|
compr_int_read(const unsigned char *p);
|
|
|
|
#endif /* MY_COMPR_INT_H */
|