📄 mach0data.ic
字号:
/**********************************************************************Utilities for converting data from the database fileto the machine format. (c) 1995 Innobase OyCreated 11/28/1995 Heikki Tuuri***********************************************************************//***********************************************************The following function is used to store data in one byte. */UNIV_INLINEvoid mach_write_to_1(/*============*/ byte* b, /* in: pointer to byte where to store */ ulint n) /* in: ulint integer to be stored, >= 0, < 256 */ { ut_ad(b); ut_ad(n <= 0xFFUL); b[0] = (byte)n;}/************************************************************The following function is used to fetch data from one byte. */UNIV_INLINEulint mach_read_from_1(/*=============*/ /* out: ulint integer, >= 0, < 256 */ byte* b) /* in: pointer to byte */{ ut_ad(b); return((ulint)(b[0]));}/***********************************************************The following function is used to store data in two consecutivebytes. We store the most significant byte to the lowest address. */UNIV_INLINEvoid mach_write_to_2(/*============*/ byte* b, /* in: pointer to two bytes where to store */ ulint n) /* in: ulint integer to be stored */ { ut_ad(b); ut_ad(n <= 0xFFFFUL); b[0] = (byte)(n >> 8); b[1] = (byte)(n);}/************************************************************The following function is used to fetch data from 2 consecutivebytes. The most significant byte is at the lowest address. */UNIV_INLINEulint mach_read_from_2(/*=============*/ /* out: ulint integer */ byte* b) /* in: pointer to 2 bytes */{ ut_ad(b); return( ((ulint)(b[0]) << 8) + (ulint)(b[1]) );}/************************************************************The following function is used to convert a 16-bit data itemto the canonical format, for fast bytewise equality testagainst memory. */UNIV_INLINEuint16mach_encode_2(/*==========*/ /* out: 16-bit integer in canonical format */ ulint n) /* in: integer in machine-dependent format */{ uint16 ret; ut_ad(2 == sizeof ret); mach_write_to_2((byte*) &ret, n); return(ret);}/************************************************************The following function is used to convert a 16-bit data itemfrom the canonical format, for fast bytewise equality testagainst memory. */UNIV_INLINEulintmach_decode_2(/*==========*/ /* out: integer in machine-dependent format */ uint16 n) /* in: 16-bit integer in canonical format */{ ut_ad(2 == sizeof n); return(mach_read_from_2((byte*) &n));}/***********************************************************The following function is used to store data in 3 consecutivebytes. We store the most significant byte to the lowest address. */UNIV_INLINEvoid mach_write_to_3(/*============*/ byte* b, /* in: pointer to 3 bytes where to store */ ulint n) /* in: ulint integer to be stored */ { ut_ad(b); ut_ad(n <= 0xFFFFFFUL); b[0] = (byte)(n >> 16); b[1] = (byte)(n >> 8); b[2] = (byte)(n);}/************************************************************The following function is used to fetch data from 3 consecutivebytes. The most significant byte is at the lowest address. */UNIV_INLINEulint mach_read_from_3(/*=============*/ /* out: ulint integer */ byte* b) /* in: pointer to 3 bytes */{ ut_ad(b); return( ((ulint)(b[0]) << 16) + ((ulint)(b[1]) << 8) + (ulint)(b[2]) );}/***********************************************************The following function is used to store data in four consecutivebytes. We store the most significant byte to the lowest address. */UNIV_INLINEvoid mach_write_to_4(/*============*/ byte* b, /* in: pointer to four bytes where to store */ ulint n) /* in: ulint integer to be stored */ { ut_ad(b);#if (0 == 1) && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC) /* We do not use this even on Intel, because unaligned accesses may be slow */ __asm MOV EAX, n __asm BSWAP EAX /* Intel is little-endian, must swap bytes */ __asm MOV n, EAX *((ulint*)b) = n;#else b[0] = (byte)(n >> 24); b[1] = (byte)(n >> 16); b[2] = (byte)(n >> 8); b[3] = (byte)n;#endif}/************************************************************The following function is used to fetch data from 4 consecutivebytes. The most significant byte is at the lowest address. */UNIV_INLINEulint mach_read_from_4(/*=============*/ /* out: ulint integer */ byte* b) /* in: pointer to four bytes */{#if (0 == 1) && !defined(__STDC__) && defined(UNIV_INTEL) && (UNIV_WORD_SIZE == 4) && defined(UNIV_VISUALC) /* We do not use this even on Intel, because unaligned accesses may be slow */ ulint res; ut_ad(b); __asm MOV EDX, b __asm MOV ECX, DWORD PTR [EDX] __asm BSWAP ECX /* Intel is little-endian, must swap bytes */ __asm MOV res, ECX return(res);#else ut_ad(b); return( ((ulint)(b[0]) << 24) + ((ulint)(b[1]) << 16) + ((ulint)(b[2]) << 8) + (ulint)(b[3]) );#endif}/*************************************************************Writes a ulint in a compressed form where the first byte codes thelength of the stored ulint. We look at the most significant bits ofthe byte. If the most significant bit is zero, it means 1-byte storage,else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,it means 3-byte storage, else if 4th is 0, it means 4-byte storage, else the storage is 5-byte. */UNIV_INLINEulintmach_write_compressed(/*==================*/ /* out: compressed size in bytes */ byte* b, /* in: pointer to memory where to store */ ulint n) /* in: ulint integer (< 2^32) to be stored */ { ut_ad(b); if (n < 0x80UL) { mach_write_to_1(b, n); return(1); } else if (n < 0x4000UL) { mach_write_to_2(b, n | 0x8000UL); return(2); } else if (n < 0x200000UL) { mach_write_to_3(b, n | 0xC00000UL); return(3); } else if (n < 0x10000000UL) { mach_write_to_4(b, n | 0xE0000000UL); return(4); } else { mach_write_to_1(b, 0xF0UL); mach_write_to_4(b + 1, n); return(5); }}/*************************************************************Returns the size of a ulint when written in the compressed form. */UNIV_INLINEulintmach_get_compressed_size(/*=====================*/ /* out: compressed size in bytes */ ulint n) /* in: ulint integer (< 2^32) to be stored */ { if (n < 0x80UL) { return(1); } else if (n < 0x4000UL) { return(2); } else if (n < 0x200000UL) { return(3); } else if (n < 0x10000000UL) { return(4); } else { return(5); }}/*************************************************************Reads a ulint in a compressed form. */UNIV_INLINEulintmach_read_compressed(/*=================*/ /* out: read integer (< 2^32) */ byte* b) /* in: pointer to memory from where to read */{ ulint flag; ut_ad(b); flag = mach_read_from_1(b); if (flag < 0x80UL) { return(flag); } else if (flag < 0xC0UL) { return(mach_read_from_2(b) & 0x7FFFUL); } else if (flag < 0xE0UL) { return(mach_read_from_3(b) & 0x3FFFFFUL); } else if (flag < 0xF0UL) { return(mach_read_from_4(b) & 0x1FFFFFFFUL); } else { ut_ad(flag == 0xF0UL); return(mach_read_from_4(b + 1)); }}/***********************************************************The following function is used to store data in 8 consecutivebytes. We store the most significant byte to the lowest address. */UNIV_INLINEvoid mach_write_to_8(/*============*/ byte* b, /* in: pointer to 8 bytes where to store */ dulint n) /* in: dulint integer to be stored */ { ut_ad(b); mach_write_to_4(b, ut_dulint_get_high(n)); mach_write_to_4(b + 4, ut_dulint_get_low(n));}/************************************************************The following function is used to fetch data from 8 consecutivebytes. The most significant byte is at the lowest address. */UNIV_INLINEdulint mach_read_from_8(/*=============*/ /* out: dulint integer */ byte* b) /* in: pointer to 8 bytes */{ ulint high; ulint low; ut_ad(b); high = mach_read_from_4(b); low = mach_read_from_4(b + 4); return(ut_dulint_create(high, low)); }/***********************************************************The following function is used to store data in 7 consecutivebytes. We store the most significant byte to the lowest address. */UNIV_INLINEvoid mach_write_to_7(/*============*/ byte* b, /* in: pointer to 7 bytes where to store */ dulint n) /* in: dulint integer to be stored */ { ut_ad(b); mach_write_to_3(b, ut_dulint_get_high(n)); mach_write_to_4(b + 3, ut_dulint_get_low(n));}/************************************************************The following function is used to fetch data from 7 consecutivebytes. The most significant byte is at the lowest address. */UNIV_INLINEdulint mach_read_from_7(/*=============*/ /* out: dulint integer */ byte* b) /* in: pointer to 7 bytes */{ ulint high; ulint low; ut_ad(b); high = mach_read_from_3(b); low = mach_read_from_4(b + 3); return(ut_dulint_create(high, low)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -