真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PostgreSQL源碼解讀(247)-HTAB動(dòng)態(tài)擴(kuò)展圖解#1

本節(jié)簡(jiǎn)單介紹了PostgreSQL中的HTAB如何動(dòng)態(tài)擴(kuò)展,這是第1部分.

創(chuàng)新互聯(lián)建站制作網(wǎng)站網(wǎng)頁(yè)找三站合一網(wǎng)站制作公司,專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)站建設(shè)、成都做網(wǎng)站,網(wǎng)站設(shè)計(jì),企業(yè)網(wǎng)站搭建,網(wǎng)站開(kāi)發(fā),建網(wǎng)站業(yè)務(wù),680元做網(wǎng)站,已為上千余家服務(wù),創(chuàng)新互聯(lián)建站網(wǎng)站建設(shè)將一如既往的為我們的客戶提供最優(yōu)質(zhì)的網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣服務(wù)!

一、數(shù)據(jù)結(jié)構(gòu)

/*
 * Top control structure for a hashtable --- in a shared table, each backend
 * has its own copy (OK since no fields change at runtime)
 * 哈希表的頂層控制結(jié)構(gòu).
 * 在這個(gè)共享哈希表中,每一個(gè)后臺(tái)進(jìn)程都有自己的拷貝
 * (之所以沒(méi)有問(wèn)題是因?yàn)閒ork出來(lái)后,在運(yùn)行期沒(méi)有字段會(huì)變化)
 */
struct HTAB
{
    //指向共享的控制信息
    HASHHDR    *hctl;           /* => shared control information */
    //段目錄
    HASHSEGMENT *dir;           /* directory of segment starts */
    //哈希函數(shù)
    HashValueFunc hash;         /* hash function */
    //哈希鍵比較函數(shù)
    HashCompareFunc match;      /* key comparison function */
    //哈希鍵拷貝函數(shù)
    HashCopyFunc keycopy;       /* key copying function */
    //內(nèi)存分配器
    HashAllocFunc alloc;        /* memory allocator */
    //內(nèi)存上下文
    MemoryContext hcxt;         /* memory context if default allocator used */
    //表名(用于錯(cuò)誤信息)
    char       *tabname;        /* table name (for error messages) */
    //如在共享內(nèi)存中,則為T(mén)
    bool        isshared;       /* true if table is in shared memory */
    //如為T(mén),則固定大小不能擴(kuò)展
    bool        isfixed;        /* if true, don't enlarge */
    /* freezing a shared table isn't allowed, so we can keep state here */
    //不允許凍結(jié)共享表,因此這里會(huì)保存相關(guān)狀態(tài)
    bool        frozen;         /* true = no more inserts allowed */
    /* We keep local copies of these fixed values to reduce contention */
    //保存這些固定值的本地拷貝,以減少?zèng)_突
    //哈希鍵長(zhǎng)度(以字節(jié)為單位)
    Size        keysize;        /* hash key length in bytes */
    //段大小,必須為2的冪
    long        ssize;          /* segment size --- must be power of 2 */
    //段偏移,ssize的對(duì)數(shù)
    int         sshift;         /* segment shift = log2(ssize) */
};
/*
 * Header structure for a hash table --- contains all changeable info
 * 哈希表的頭部結(jié)構(gòu) -- 存儲(chǔ)所有可變信息
 *
 * In a shared-memory hash table, the HASHHDR is in shared memory, while
 * each backend has a local HTAB struct.  For a non-shared table, there isn't
 * any functional difference between HASHHDR and HTAB, but we separate them
 * anyway to share code between shared and non-shared tables.
 * 在共享內(nèi)存哈希表中,HASHHDR位于共享內(nèi)存中,每一個(gè)后臺(tái)進(jìn)程都有一個(gè)本地HTAB結(jié)構(gòu).
 * 對(duì)于非共享哈希表,HASHHDR和HTAB沒(méi)有任何功能性的不同,
 * 但無(wú)論如何,我們還是把它們區(qū)分為共享和非共享表.
 */
struct HASHHDR
{
    /*
     * The freelist can become a point of contention in high-concurrency hash
     * tables, so we use an array of freelists, each with its own mutex and
     * nentries count, instead of just a single one.  Although the freelists
     * normally operate independently, we will scavenge entries from freelists
     * other than a hashcode's default freelist when necessary.
     * 在高并發(fā)的哈希表中,空閑鏈表會(huì)成為競(jìng)爭(zhēng)熱點(diǎn),因此我們使用空閑鏈表數(shù)組,
     *   數(shù)組中的每一個(gè)元素都有自己的mutex和條目統(tǒng)計(jì),而不是使用一個(gè).
     *
     * If the hash table is not partitioned, only freeList[0] is used and its
     * spinlock is not used at all; callers' locking is assumed sufficient.
     * 如果哈希表沒(méi)有分區(qū),那么只有freelist[0]元素是有用的,自旋鎖沒(méi)有任何用處;
     * 調(diào)用者鎖定被認(rèn)為已足夠OK.
     */
    /* Number of freelists to be used for a partitioned hash table. */
    //#define NUM_FREELISTS           32
    FreeListData freeList[NUM_FREELISTS];
    /* These fields can change, but not in a partitioned table */
    //這些域字段可以改變,但不適用于分區(qū)表
    /* Also, dsize can't change in a shared table, even if unpartitioned */
    //同時(shí),就算是非分區(qū)表,共享表的dsize也不能改變
    //目錄大小
    long        dsize;          /* directory size */
    //已分配的段大小(<= dsize)
    long        nsegs;          /* number of allocated segments (<= dsize) */
    //正在使用的最大桶ID
    uint32      max_bucket;     /* ID of maximum bucket in use */
    //進(jìn)入整個(gè)哈希表的模掩碼
    uint32      high_mask;      /* mask to modulo into entire table */
    //進(jìn)入低位哈希表的模掩碼
    uint32      low_mask;       /* mask to modulo into lower half of table */
    /* These fields are fixed at hashtable creation */
    //下面這些字段在哈希表創(chuàng)建時(shí)已固定
    //哈希鍵大小(以字節(jié)為單位)
    Size        keysize;        /* hash key length in bytes */
    //所有用戶元素大小(以字節(jié)為單位)
    Size        entrysize;      /* total user element size in bytes */
    //分區(qū)個(gè)數(shù)(2的冪),或者為0
    long        num_partitions; /* # partitions (must be power of 2), or 0 */
    //目標(biāo)的填充因子
    long        ffactor;        /* target fill factor */
    //如目錄是固定大小,則該值為dsize的上限值
    long        max_dsize;      /* 'dsize' limit if directory is fixed size */
    //段大小,必須是2的冪
    long        ssize;          /* segment size --- must be power of 2 */
    //段偏移,ssize的對(duì)數(shù)
    int         sshift;         /* segment shift = log2(ssize) */
    //一次性分配的條目個(gè)數(shù)
    int         nelem_alloc;    /* number of entries to allocate at once */
#ifdef HASH_STATISTICS
    /*
     * Count statistics here.  NB: stats code doesn't bother with mutex, so
     * counts could be corrupted a bit in a partitioned table.
     * 統(tǒng)計(jì)信息.
     * 注意:統(tǒng)計(jì)相關(guān)的代碼不會(huì)影響mutex,因此對(duì)于分區(qū)表,統(tǒng)計(jì)可能有一點(diǎn)點(diǎn)問(wèn)題
     */
    long        accesses;
    long        collisions;
#endif
};
/*
 * Per-freelist data.
 * 空閑鏈表數(shù)據(jù).
 *
 * In a partitioned hash table, each freelist is associated with a specific
 * set of hashcodes, as determined by the FREELIST_IDX() macro below.
 * nentries tracks the number of live hashtable entries having those hashcodes
 * (NOT the number of entries in the freelist, as you might expect).
 * 在一個(gè)分區(qū)哈希表中,每一個(gè)空閑鏈表與特定的hashcodes集合相關(guān),通過(guò)下面的FREELIST_IDX()宏進(jìn)行定義.
 * nentries跟蹤有這些hashcodes的仍存活的hashtable條目個(gè)數(shù).
 * (注意不要搞錯(cuò),不是空閑的條目個(gè)數(shù))
 *
 * The coverage of a freelist might be more or less than one partition, so it
 * needs its own lock rather than relying on caller locking.  Relying on that
 * wouldn't work even if the coverage was the same, because of the occasional
 * need to "borrow" entries from another freelist; see get_hash_entry().
 * 空閑鏈表的覆蓋范圍可能比一個(gè)分區(qū)多或少,因此需要自己的鎖而不能僅僅依賴調(diào)用者的鎖.
 * 依賴調(diào)用者鎖在覆蓋面一樣的情況下也不會(huì)起效,因?yàn)榕紶栃枰獜牧硪粋€(gè)自由列表“借用”條目,詳細(xì)參見(jiàn)get_hash_entry()
 *
 * Using an array of FreeListData instead of separate arrays of mutexes,
 * nentries and freeLists helps to reduce sharing of cache lines between
 * different mutexes.
 * 使用FreeListData數(shù)組而不是一個(gè)獨(dú)立的mutexes,nentries和freelists數(shù)組有助于減少不同mutexes之間的緩存線共享.
 */
typedef struct
{
    //該空閑鏈表的自旋鎖
    slock_t     mutex;          /* spinlock for this freelist */
    //相關(guān)桶中的條目個(gè)數(shù)
    long        nentries;       /* number of entries in associated buckets */
    //空閑元素鏈
    HASHELEMENT *freeList;      /* chain of free elements */
} FreeListData;
/*
 * HASHELEMENT is the private part of a hashtable entry.  The caller's data
 * follows the HASHELEMENT structure (on a MAXALIGN'd boundary).  The hash key
 * is expected to be at the start of the caller's hash entry data structure.
 * HASHELEMENT是哈希表?xiàng)l目的私有部分.
 * 調(diào)用者的數(shù)據(jù)按照HASHELEMENT結(jié)構(gòu)組織(位于MAXALIGN的邊界).
 * 哈希鍵應(yīng)位于調(diào)用者h(yuǎn)ash條目數(shù)據(jù)結(jié)構(gòu)的開(kāi)始位置.
 */
typedef struct HASHELEMENT
{
    //鏈接到相同桶中的下一個(gè)條目
    struct HASHELEMENT *link;   /* link to next entry in same bucket */
    //該條目的哈希函數(shù)結(jié)果
    uint32      hashvalue;      /* hash function result for this entry */
} HASHELEMENT;
/* Hash table header struct is an opaque type known only within dynahash.c */
//哈希表頭部結(jié)構(gòu),非透明類(lèi)型,用于dynahash.c
typedef struct HASHHDR HASHHDR;
/* Hash table control struct is an opaque type known only within dynahash.c */
//哈希表控制結(jié)構(gòu),非透明類(lèi)型,用于dynahash.c
typedef struct HTAB HTAB;
/* Parameter data structure for hash_create */
//hash_create使用的參數(shù)數(shù)據(jù)結(jié)構(gòu)
/* Only those fields indicated by hash_flags need be set */
//根據(jù)hash_flags標(biāo)記設(shè)置相應(yīng)的字段
typedef struct HASHCTL
{
    //分區(qū)個(gè)數(shù)(必須是2的冪)
    long        num_partitions; /* # partitions (must be power of 2) */
    //段大小
    long        ssize;          /* segment size */
    //初始化目錄大小
    long        dsize;          /* (initial) directory size */
    //dsize上限
    long        max_dsize;      /* limit to dsize if dir size is limited */
    //填充因子
    long        ffactor;        /* fill factor */
    //哈希鍵大小(字節(jié)為單位)
    Size        keysize;        /* hash key length in bytes */
    //參見(jiàn)上述數(shù)據(jù)結(jié)構(gòu)注釋
    Size        entrysize;      /* total user element size in bytes */
    //
    HashValueFunc hash;         /* hash function */
    HashCompareFunc match;      /* key comparison function */
    HashCopyFunc keycopy;       /* key copying function */
    HashAllocFunc alloc;        /* memory allocator */
    MemoryContext hcxt;         /* memory context to use for allocations */
    //共享內(nèi)存中的哈希頭部結(jié)構(gòu)地址
    HASHHDR    *hctl;           /* location of header in shared mem */
} HASHCTL;
/* A hash bucket is a linked list of HASHELEMENTs */
//哈希桶是HASHELEMENTs鏈表
typedef HASHELEMENT *HASHBUCKET;
/* A hash segment is an array of bucket headers */
//hash segment是桶數(shù)組
typedef HASHBUCKET *HASHSEGMENT;
/*
 * Hash functions must have this signature.
 * Hash函數(shù)必須有它自己的標(biāo)識(shí)
 */
typedef uint32 (*HashValueFunc) (const void *key, Size keysize);
 /*
 * Key comparison functions must have this signature.  Comparison functions
 * return zero for match, nonzero for no match.  (The comparison function
 * definition is designed to allow memcmp() and strncmp() to be used directly
 * as key comparison functions.)
 * 哈希鍵對(duì)比函數(shù)必須有自己的標(biāo)識(shí).
 * 如匹配則對(duì)比函數(shù)返回0,不匹配返回非0.
 * (對(duì)比函數(shù)定義被設(shè)計(jì)為允許在對(duì)比鍵值時(shí)可直接使用memcmp()和strncmp())
 */
typedef int (*HashCompareFunc) (const void *key1, const void *key2,
 Size keysize);
 /*
 * Key copying functions must have this signature.  The return value is not
 * used.  (The definition is set up to allow memcpy() and strlcpy() to be
 * used directly.)
 * 鍵拷貝函數(shù)必須有自己的標(biāo)識(shí).
 * 返回值無(wú)用.
 */
typedef void *(*HashCopyFunc) (void *dest, const void *src, Size keysize);
/*
 * Space allocation function for a hashtable --- designed to match malloc().
 * Note: there is no free function API; can't destroy a hashtable unless you
 * use the default allocator.
 * 哈希表的恐懼分配函數(shù) -- 被設(shè)計(jì)為與malloc()函數(shù)匹配.
 * 注意:這里沒(méi)有釋放函數(shù)API;不能銷(xiāo)毀哈希表,除非使用默認(rèn)的分配器.
 */
typedef void *(*HashAllocFunc) (Size request);

其結(jié)構(gòu)如下圖所示:
PostgreSQL 源碼解讀(247)- HTAB動(dòng)態(tài)擴(kuò)展圖解#1

擴(kuò)展后的結(jié)構(gòu)如下圖所示:
PostgreSQL 源碼解讀(247)- HTAB動(dòng)態(tài)擴(kuò)展圖解#1

二、跟蹤分析

N/A

三、參考資料

N/A


網(wǎng)站欄目:PostgreSQL源碼解讀(247)-HTAB動(dòng)態(tài)擴(kuò)展圖解#1
網(wǎng)頁(yè)URL:http://weahome.cn/article/pjsedc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部