前言:
在pg存儲中有一種格式就是擴充格式,或者成為線外存儲,本章解釋的宏就是其中的一個。
翻譯
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
do { \
varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
Assert(VARATT_IS_EXTERNAL(attre)); \
Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
} while ()
typedef unsigned char uint8; /* == 8 bits */
typedef struct
{
uint8 va_header; /* Always 0x80 or 0x01 */
uint8 va_tag; /* Type of datum */
char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Type-specific data */
} varattrib_1b_e;
//2,3部分宏
//判斷PTR的第一個位元組是否為'0x01'
#define VARATT_IS_EXTERNAL(PTR) VARATT_IS_1B_E(PTR)
#define VARATT_IS_1B_E(PTR) ((((varattrib_1b *) (PTR))->va_header) == 0x01)
/*求結構體varattrib_1b_e*的va_data偏移,其實就是前兩個元素,header和tag位元組大小,此處為2*/
#define VARHDRSZ_EXTERNAL offsetof(varattrib_1b_e, va_data)
/*求頭部大小加根據tag類型擷取大小*/
#define VARSIZE_EXTERNAL(PTR) (VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR)))
/*擷取PTR的tag的值/類型*/
#define VARTAG_EXTERNAL(PTR) VARTAG_1B_E(PTR)
#define VARTAG_1B_E(PTR) (((varattrib_1b_e *) (PTR))->va_tag)
/*根據tag的類型進行求不同結構體大小*/
#define VARTAG_SIZE(tag) \
((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \
VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \
(tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \
TrapMacro(true, "unrecognized TOAST vartag"))
第一步,将傳入參數強轉為
attr
類型,此時attr的前兩個位元組分别對應結構體的
varattrib_1b_e *
和
va_header
va_tag
。
第二步,判斷
是否為
va_header
,意思是判斷
0x01
attre
是否是擴充類型
第三步,求
中
attre
對應的結構體 大小是否與
tag
toast_pointer
相同
二,三步其實是assert,判斷,閱讀代碼時,可以忽略.
第四步,将
拷貝到
attre
中。
toast_pointer
原版
/*
* Macro to fetch the possibly-unaligned contents of an EXTERNAL datum
* into a local "struct varatt_external" toast pointer. This should be
* just a memcpy, but some versions of gcc seem to produce broken code
* that assumes the datum contents are aligned. Introducing an explicit
* intermediate "varattrib_1b_e *" variable seems to fix it.
*/
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
do { \
varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
Assert(VARATT_IS_EXTERNAL(attre)); \
Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
} while ()**
綜上所述:該宏其實就是一個拷貝過程。最終将
attr
的資料,(從第三個位元組開始為資料)拷貝到
toast_pointer
中。
中間過程簡單解釋:判斷tag的類型,并根據tag類型求該類型對應的結構體大小,并将此結構體大小與
toast_pointer
(結構體)進行判斷以确定是否可以拷貝。