精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊聊 Redis 中的字典設計與實現

數據庫 Redis
本文筆者從字典的數據結構和常見操作的角度對 Redis 中字典的設計思想和優化思路進行深入的剖析,希望對你有幫助。

Redis作為非關系數據庫,其底層采用了字典(也稱為映射)保存鍵值對。本文會基于源碼分析的方式帶你了解redis中這一常見數據結構的精巧設計,希望對你有幫助。

哈希表的數據結構

我們簡單說明一下redis字典數據結構特征:

  • 用table管理當前存儲鍵值對而table本質上就是一個數組
  • 數組的大小可采用一個size字段維護
  • 添加一個鍵值時,會通過sizemask進行按位與運算得到table數組的某個索引位置并將其存儲,然后自增一下哈希表的used字段,標識當前數組元素+1。

可能上文說的比較抽象,我們不妨舉個例子,假設我們現在鍵入如下指令:

HSET student  xiaoming 18

redis完成命令解析后,定位到student這個key對應的字段空間的字典,找到當前正在使用的哈希表,按照如下步驟完成鍵值對存儲:

  • 計算xiaoming的哈希值。
  • 將計算出的哈希值和sizemask即3,也就是數組的索引范圍進行按位與運算,得到對應的數組索引位置。
  • 查看該位置是否有元素,如果沒有則直接添加,反之追加到該dictEntry的后面,這也就是我們常說的鏈地址法。
  • used字段自增一下,表示當前哈希表有一個元素。

我們可以在dict.h看到上文所提及的哈希表和字典中每一個元素的數據結構:

typedef struct dictht {
//存儲鍵值對的哈希表
    dictEntry **table;
    //當前哈希表的大小
    unsignedlong size;
    //計算哈希值的掩碼值
    unsignedlong sizemask;
    //當前哈希表的節點數
    unsignedlong used;
} dictht;

//記錄鍵值對的數據結構dictEntry 
typedefstruct dictEntry {
//指向鍵的指針
    void *key;
    
    //通過共用體存儲值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    //next指針指向下一個dictEntry 
    struct dictEntry *next;
} dictEntry;

字典的數據結構

上文我們講解了哈希結構,而哈希表在極端算法情況下會造成大量鍵值對沖突碰撞的情況,導致查詢效率由原來的O(1)變為O(n),所以為了保證針對沖突的數組進行優化,redis的字典采用的雙數組的方式管理鍵值對,所以這一小節我們著重說明redis如何基于字典管理兩個哈希表空間。

對應的我們也可以在dict.h看到dict 的定義,可以看到字典維護哈希表字段ht是一個空間為2的數組:

typedef struct dict {
  //.......
   //定義2個哈希表
    dictht ht[2];
    //-1時表示當前哈希表處于漸進式哈希
    int rehashidx; /* rehashing not in progress if rehashidx == -1 */
    //.......
} dict;

如下圖所示,可以看到dict的數據結構定義了大小為2的哈希表數組,當某個哈希表碰撞激烈需要進行調整時,就會采用漸進式哈希算法將鍵值對存到dictht[1],并通過rehashidx標志為-1表示當前處于漸進式哈希階段:

字典的初始化創建

進行鍵值對創建時,dictCreate會進行必要的內存分配,然后進入初始化工作:

  • 初始化兩個哈希表空間。
  • 設置類型特定函數type ,這個type 包含了各種類型哈希值計算、值復制以及鍵比對等各種方法的指針。
  • 設置私有數據privdata 。
  • 初始化rehashidx 為-1表示未進行漸進式再哈希。

對應的我們可以在dict.c中看到dictCreate函數的源代碼:

/* Create a new hash table */
dict *dictCreate(dictType *type,
        void *privDataPtr)
{
//內存分配
    dict *d = zmalloc(sizeof(*d));
//字典初始化
    _dictInit(d,type,privDataPtr);
    return d;
}

/* Initialize the hash table */
int _dictInit(dict *d, dictType *type,
        void *privDataPtr)
{
//重置哈希表
    _dictReset(&d->ht[0]);
    _dictReset(&d->ht[1]);
    //設置類型特定函數和私有數據
    d->type = type;
    d->privdata = privDataPtr;
    //初始化漸進式哈希標識
    d->rehashidx = -1;
    d->iterators = 0;
    return DICT_OK;
}

元素的插入

字典的插入操作大體流程也很市面上常見的哈希表實現差不多,通過哈希算法(MurmurHash2)定位元素插入的位置再進行插入操作,唯一有所區別的是,redis版本字典的鏈地址法解決沖突的上的優化,為了保證哈希定位的位置存在元素時能夠快速插入,redis字典的插入采用的是頭插法,即將最新的元素作為鏈表頭元素插入:

與之對應的我們給出代碼的入口,也就是dict.c下的dictAdd方法,可以看到其內部是通過完成鍵的添加,只有key插入成功后才會通過setVal方法維護插入的entry的值:

int dictAdd(dict *d, void *key, void *val)
{
 //通過dictAddRaw完成key的插入
    dictEntry *entry = dictAddRaw(d,key);
 //如果插入成功再維護value
    if (!entry) return DICT_ERR;
    dictSetVal(d, entry, val);
    return DICT_OK;
}

dictAddRaw邏輯也比較簡單,先檢查當前的字典表是否因為大量沖突而處理漸進式哈希(關于漸進式哈希后文會詳細講解,這里也補充一些簡單的概念),通過_dictKeyIndex定位到當前元素插入的索引位置,采用頭插法將其插入到對應索引位置的鏈表首部:

dictEntry *dictAddRaw(dict *d, void *key)
{
    int index;
    dictEntry *entry;
    dictht *ht;
//是否處于漸進式哈希階段
    if (dictIsRehashing(d)) _dictRehashStep(d);

   //定位索引位置
    if ((index = _dictKeyIndex(d, key)) == -1)
        returnNULL;

   //定位要存儲元素的哈希表位置
    ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
    //分配內存空間
    entry = zmalloc(sizeof(*entry));
    //采用頭插法將元素插入到對應哈希表的索引位置上
    entry->next = ht->table[index];
    ht->table[index] = entry;
    //當前插入元素數加一
    ht->used++;

    /* Set the hash entry fields. */
    dictSetKey(d, entry, key);
    return entry;
}

漸進式哈希驅逐解決頻繁哈希碰撞

隨著我們不斷的新增鍵值對,當前的哈希算法得到的索引位置很大概率會出現哈希沖突,即每次定位到的索引位置都很大概率存在元素,這也就是我們的常說的哈希沖突,這就是redis的字典默認會初始化兩張哈希表的原因所在。

符合以下兩個條件時,字典就會觸發擴容機制:

  • 未進行BGSAVE命令或者BGREWRITEAOF持久化操作,且當前哈希表元素數和哈希表空間大小一樣。
  • 正進行BGSAVE命令或者BGREWRITEAOF持久化操作,當且哈希表元素數已是哈希表空間的5倍。

觸發擴容時,字典會將rehashidx設置為0意為當前因為大量沖突碰撞而從0索引開始漸進式再哈希,ht[1]就會基于ht[0]數組長度創建一個其2倍的數組空間,后續的新插入的元素也都會根據哈希算法將元素插入到ht[1]中。

對于舊有存在的元素,考慮到整個哈希表可能存在不可預估數量的鍵值對,redis的字典會通過漸進式哈希的方式在元素每次進行增刪改查操作時將舊有元素逐批次遷移到ht[1]中,一旦所有元素全部遷移到ht[1]后,哈希表就會將ht[1]指向的哈希表指針賦值給ht[0],并將ht[0]原有哈希表釋放。

了解整體的設計之后,我們就可以從源碼角度印證這個問題了,可以看到字典在每次進行哈希索引定位時都會調用_dictKeyIndex方法,而該方法內部則有一個_dictExpandIfNeeded操作,其內部就會根據我們上文所說的閾值判斷當前哈希表是否需要進行擴容:

static int _dictKeyIndex(dict *d, constvoid *key)
{
    unsignedint h, idx, table;
    dictEntry *he;

    //判斷當前哈希表是否需要進行擴容操作
    if (_dictExpandIfNeeded(d) == DICT_ERR)
        return-1;
   //獲取當前key的哈希值
    h = dictHashKey(d, key);
    //計算哈希值
    for (table = 0; table <= 1; table++) {
     //計算索引
        idx = h & d->ht[table].sizemask;

        he = d->ht[table].table[idx];
        while(he) {
            if (dictCompareKeys(d, key, he->key))
                return-1;
            he = he->next;
        }
        //如果不處于漸進式哈希階段,則直接將該索引值返回,后續元素直接存入ht[0]表中,反之進入下一個循環計算當前元素在ht[1]表的索引
        if (!dictIsRehashing(d)) break;
    }
    return idx;
}

我們繼續步入_dictExpandIfNeeded即可看到擴容判斷的邏輯,也就是我們上文所說的符合兩個擴容條件:

  • 數組0使用空間大于等于數組長度且dict_can_resize為1(持久化結束或者未進行持久化這個值都不會被設置為1),若為1則是允許resize操作。
  • 數組0使用空間大于等于數組長度,且數組0使用空間已經打到數組長度的5倍。

只要符合上述的條件,該函數就會調用dictExpand觸發擴容,并將rehashidx設置為0即代表從數組0的索引0位置嘗試漸進式驅逐:

static int _dictExpandIfNeeded(dict *d)
{
   //......
    /**
     * 如果數組0使用空間大于等于數組長度則判斷:
     * 1. dict_can_resize是否為1(持久化結束或者未進行持久化這個值都不會被設置為1),若為1則是允許resize操作
     * 2. 數組0使用空間是否是數組長度的5倍
     * 若符合上述要求,則調用dictExpand將數組1設置為數組0空間的兩倍
     */
    if (d->ht[0].used >= d->ht[0].size &&
        (dict_can_resize ||
         d->ht[0].used/d->ht[0].size > dict_force_resize_ratio))
    {
        return dictExpand(d, d->ht[0].used*2);
    }
    return DICT_OK;
}

此時我們再回看之前的鍵值對插入操作,它會根據dictIsRehashing判斷rehashidx是否為0以確定是否處于漸進式再哈希,從而調用_dictRehashStep進入漸進式哈希操作在鍵值對維護:

dictEntry *dictAddRaw(dict *d, void *key)
{
    int index;
    dictEntry *entry;
    dictht *ht;
 //dictIsRehashing會判斷當前是否處于再哈希階段,若符合要求則進行一次ht[0]哈希表元素驅逐操作
    if (dictIsRehashing(d)) _dictRehashStep(d);

   //保存鍵值對操作
   //......
    return entry;
}

我們直接查看_dictRehashStep內部的實現就可以看到一個dictRehash的函數,它就是漸進式哈希的核心實現,該方法會從0開始每次驅逐10個元素到ht[1]中:

int dictRehash(dict *d, int n) {
    //基于傳入的n得出訪問空bucket的最大次數,默認為1*10=10
    int empty_visits = n*10;
    if (!dictIsRehashing(d)) return0;

    while(n-- && d->ht[0].used != 0) {
        dictEntry *de, *nextde;

        
        assert(d->ht[0].size > (unsignedlong)d->rehashidx);
        //基于empty_visits 循環找到第一個非空的bucket
        while(d->ht[0].table[d->rehashidx] == NULL) {
            d->rehashidx++;
            if (--empty_visits == 0) return1;
        }
        //定位到需要驅逐元素的bucket
        de = d->ht[0].table[d->rehashidx];
        
        //計算當前元素在ht[1]中的位置并驅逐過去
        while(de) {
            unsignedint h;

            nextde = de->next;
           
            //計算當前元素在新哈希表的索引位置
            h = dictHashKey(d, de->key) & d->ht[1].sizemask;
            //基于頭插法,將舊元素指向新哈希表的第一個元素,構成鏈表
            de->next = d->ht[1].table[h];
            //投節點指向待遷移元素
            d->ht[1].table[h] = de;
            //舊有哈希表元素數減去1
            d->ht[0].used--;
            //新的哈希元素空間加上1
            d->ht[1].used++;
            //de指向下一個元素,進行下一輪迭代
            de = nextde;
        }
        d->ht[0].table[d->rehashidx] = NULL;
        d->rehashidx++;
    }


    //used 為0說明所有元素驅逐完成,將ht[1]指向的哈希表賦值給ht[0],重置rehashidx ,并返回0
    if (d->ht[0].used == 0) {
        zfree(d->ht[0].table);
        d->ht[0] = d->ht[1];
        _dictReset(&d->ht[1]);
        d->rehashidx = -1;
        return0;
    }


    return1;
}

查詢操作

有了上述的基礎后,我們查看查詢操作就比較簡單了,其步驟比較固定:

  • 計算key的哈希值。
  • 計算對應索引位置到ht[0]定位,如果找到了直接返回。
  • 如果沒找到,查看當前是否處于擴容階段,若是則到ht[1]進行哈希定位,若找到直接返回。
  • 上述操作都未找到該元素,直接返回null。
dictEntry *dictFind(dict *d, const void *key)
{
    //......
    //計算哈希值
    h = dictHashKey(d, key);
    //通過哈希算法定位索引,到哈希表進行查詢
    for (table = 0; table <= 1; table++) {
        idx = h & d->ht[table].sizemask;
        he = d->ht[table].table[idx];
        //遍歷當前索引位置的元素,找到比對一致的返回
        while(he) {
            if (dictCompareKeys(d, key, he->key))
                return he;
            he = he->next;
        }
        //上一步沒找到則判斷是否處于擴容,若處于擴容則進入下一個循環到ht[1]表找,反之直接返回null
        if (!dictIsRehashing(d)) returnNULL;
    }
    returnNULL;
}

刪除操作

同理我們最后給出刪除操作的源碼,也查詢操作一樣,定位到元素后,將其從索引位置中解除該元素和前驅節點關系即可:

static int dictGenericDelete(dict *d, const void *key, int nofree)
{
//......

    //定位元素
    h = dictHashKey(d, key);

    for (table = 0; table <= 1; table++) {
        idx = h & d->ht[table].sizemask;
        he = d->ht[table].table[idx];
        prevHe = NULL;
        while(he) {
         //找到比對一致的鍵值對
            if (dictCompareKeys(d, key, he->key)) {
               //解除該元素和前驅節點的關系
                if (prevHe)
                    prevHe->next = he->next;
                else
                    d->ht[table].table[idx] = he->next;
                //釋放當前節點
                if (!nofree) {
                    dictFreeKey(d, he);
                    dictFreeVal(d, he);
                }
                zfree(he);
                //元素數減去1
                d->ht[table].used--;
                return DICT_OK;
            }
            prevHe = he;
            he = he->next;
        }
        if (!dictIsRehashing(d)) break;
    }
    return DICT_ERR; /* not found */
}


責任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關推薦

2025-03-20 09:54:47

2025-02-25 09:29:34

2023-05-26 08:24:17

短信渠道模型

2022-10-18 08:28:38

運營活動實現邏輯整體協作

2025-02-19 10:27:48

哨兵Redis故障轉移

2023-03-06 07:48:01

數據字典Spring

2020-09-04 07:33:12

Redis HashMap 數據

2021-12-28 19:05:41

路由服務治理

2024-11-04 08:00:00

Netty客戶端

2024-01-31 08:41:43

異步設計項目

2023-02-10 08:59:42

業務技術核心

2025-01-06 08:10:00

Redis跳表索引

2024-12-13 16:28:43

2024-12-13 08:28:45

設計模式依賴

2022-08-16 08:17:09

CDPCRM數據

2020-07-19 10:26:47

Kubernetes數據結構

2021-03-28 08:32:58

Java

2021-09-14 13:25:23

容器pod僵尸進程

2024-05-15 09:11:51

委托事件C#

2024-11-04 06:00:00

redis雙向鏈表
點贊
收藏

51CTO技術棧公眾號

国产高潮免费视频| 国产精品久久久久久久久久久久午夜片 | 91福利国产在线观看菠萝蜜| 国产成人av电影在线| 777国产偷窥盗摄精品视频| 91狠狠综合久久久久久| 日韩一区二区三区精品视频第3页| 婷婷开心激情综合| 中文字幕一区二区三区四区五区 | 麻豆中文字幕在线观看| 蜜桃av鲁一鲁一鲁一鲁俄罗斯的| 日韩经典中文字幕一区| 欧美俄罗斯乱妇| 成人在线观看免费高清| 国产精品qvod| 91精品在线一区二区| 97在线免费公开视频| 亚洲www色| 欧美高清一级片在线观看| 国产日韩精品推荐| 99久久精品国产一区二区成人| 国产视频一区免费看| 欧美xxxx18国产| 欧美黄色一级生活片| 欧美激情网址| 日韩欧美国产高清| 中日韩av在线播放| 偷拍视频一区二区三区| 亚洲一区二区三区三| 最新欧美日韩亚洲| av在线免费观看网| 久久久影视传媒| 国产亚洲欧美一区二区| av手机免费看| 精品一区二区免费视频| 国产精品久久久久久搜索| 日韩人妻无码一区二区三区99| 欧美成熟视频| 久久人体大胆视频| 国产毛片欧美毛片久久久| 欧美一级一片| 亚洲第一区在线| 一级片黄色免费| 亚洲综合视频| 欧美精品亚洲一区二区在线播放| www日韩视频| 中文字幕成在线观看| 欧美日韩国产页| 日韩精品一区在线视频| 中文字幕在线三区| 一区二区三区加勒比av| 大陆极品少妇内射aaaaaa| 免费人成在线观看播放视频| 国产精品久久久久久久久图文区| 日本一区二区高清视频| 国产青青草在线| 亚洲国产精品国自产拍av| 日韩中文一区二区三区| av男人的天堂在线| 中文字幕一区二区视频| 91免费视频黄| 在线三级中文| 亚洲观看高清完整版在线观看| 国产免费一区二区视频| 91吃瓜在线观看| 色综合久久66| 国产高清视频网站| 亚洲午夜国产成人| 日韩精品一区二区三区视频在线观看 | 国产精品亚洲成在人线| 欧美日韩二区三区| 69久久精品无码一区二区| 亚洲乱码一区| 日韩精品中文字幕久久臀| mm131丰满少妇人体欣赏图| 波多野结衣一区| 久久亚洲私人国产精品va| 久草视频中文在线| 久久亚洲风情| 国产日韩欧美日韩| 精品国精品国产自在久不卡| 9人人澡人人爽人人精品| 日本不卡二区高清三区| 黄色av免费在线| 亚洲va中文字幕| 婷婷六月天在线| 97se亚洲| 亚洲视频日韩精品| 真实国产乱子伦对白在线| 国产视频一区三区| 国产日本欧美一区二区三区在线 | 日韩电影免费观看在线观看| 国产又粗又猛又爽又黄av| 香蕉精品视频在线观看| 高清视频欧美一级| 亚洲图片中文字幕| 成人精品小蝌蚪| 视频一区二区在线观看| 成人超碰在线| 欧美男男青年gay1069videost| 97中文字幕在线观看| 欧美美女一区| 91精品国产高清久久久久久91| 免费视频网站在线观看入口| 国产激情视频一区二区在线观看| 免费在线成人av| 中文字幕免费高清电视剧网站在线观看| 亚洲aaa精品| 久久久精品高清| 亚洲最好看的视频| 欧美激情视频免费观看| 在线观看国产成人| 久久综合精品国产一区二区三区| 2021狠狠干| 精品国产欧美日韩一区二区三区| 精品国产污污免费网站入口| av在线播放中文字幕| 夜久久久久久| 99re在线国产| 免费在线观看av| 欧美性猛交xxxx乱大交退制版 | h狠狠躁死你h高h| 国产日韩视频一区二区三区| 国产69精品久久久久999小说| 亚洲欧洲二区| 中文字幕欧美亚洲| 亚洲综合图片网| 99久久99久久精品国产片果冻| 麻豆传媒网站在线观看| 日韩在线激情| 亚洲九九九在线观看| 日本一级淫片色费放| 国产成人自拍高清视频在线免费播放 | 丁香六月色婷婷| 成人欧美一区二区三区在线播放| 日本一极黄色片| 任我爽精品视频在线播放| 色综合久久悠悠| 国产成人精品一区二区无码呦| 国产精品美女一区二区三区 | 91视频你懂的| 拔插拔插海外华人免费| 一区二区在线视频观看| 欧美成人精品不卡视频在线观看| 国产精品久久欧美久久一区| 国产精品伦理一区二区| xxx国产在线观看| 久久精品av| 成人午夜高潮视频| 国产视频一区二区| 日韩一区二区三区在线| 日本天堂中文字幕| 成人午夜激情影院| 欧美不卡在线播放| 日韩有码中文字幕在线| 青青在线视频一区二区三区| 国产中文字幕在线| 欧美系列日韩一区| 黄色录像一级片| 国产福利一区在线观看| www精品久久| 午夜精品福利影院| 国产精品成人一区| 色开心亚洲综合| 欧美一区二区三区思思人| 欧美日韩一级在线观看| 成人三级伦理片| 国产二区视频在线播放| 精品国产91| 91免费版网站入口| 国产乱码在线| 亚洲女人被黑人巨大进入| 最近中文字幕免费在线观看| 亚洲视频在线一区观看| 国产日韩视频一区| 久久经典综合| 一区二区三区在线视频看| 久久一级大片| 亲子乱一区二区三区电影 | 国产黄色美女视频| 舔着乳尖日韩一区| 天天躁夜夜躁狠狠是什么心态| 久久97超碰色| 蜜臀av无码一区二区三区| 久久最新网址| 亚洲综合成人婷婷小说| 美女的胸无遮挡在线观看| 中文字幕久精品免费视频| 国产人妻精品一区二区三| 亚洲3atv精品一区二区三区| 黄色三级生活片| 国产成人av一区| jizz欧美激情18| 国产精品mm| 日韩一区二区三区高清| 91成人入口| 国产精品入口福利| 大桥未久在线播放| 中文字幕亚洲精品| 无码精品在线观看| 91麻豆精品国产91久久久| 日韩美一区二区| 一个色综合av| 久久午夜精品视频| 成人av电影在线观看| 依人在线免费视频| 国产精品久久国产愉拍| 亚洲国产精品女人| 精品欧美久久| 狠狠色综合欧美激情| 日本中文字幕视频一区| 欧美最猛黑人xxxx黑人猛叫黄| 天堂va在线| 搡老女人一区二区三区视频tv| 日韩a在线观看| 精品99一区二区| 国产欧美一区二区三区视频在线观看| 欧美日韩中文在线| 激情综合网五月婷婷| 亚洲欧美日韩国产一区二区三区| 最近中文字幕在线mv视频在线| 成人动漫在线一区| 激情成人在线观看| 精品一区二区在线观看| 免费在线观看的毛片| 野花国产精品入口| 国产在线播放观看| 黄色成人av网站| 国产成人亚洲综合无码| 久久久人成影片免费观看| 日韩亚洲视频在线| 国产精品欧美日韩一区| 久久久一本精品99久久精品66| 香蕉免费一区二区三区在线观看| 成人网址在线观看| 亚洲在线资源| 亚洲a级在线观看| 日韩一级特黄| 91中文字幕在线观看| 韩国精品视频在线观看| 国产精品三级网站| 不卡亚洲精品| 国产在线精品一区免费香蕉| 巨大黑人极品videos精品| 国产精品国产三级国产aⅴ浪潮 | http;//www.99re视频| 免费一级欧美在线大片| 亚洲影视中文字幕| 日韩在线成人| 国产精品久久久久久久久婷婷 | xxxxx性欧美特大| 日本精品一区二区三区在线播放视频 | 日日干夜夜操s8| 久久国产精品第一页| 五月婷婷之婷婷| 国产乱淫av一区二区三区| 久久人人爽人人片| 国产成人午夜高潮毛片| 人妻 日韩 欧美 综合 制服| 99久久伊人精品| 一级片视频免费看| 国产精品国产三级国产专播品爱网| 亚洲女人久久久| 亚洲伊人色欲综合网| 日本少妇裸体做爰| 一本一道综合狠狠老| 中国女人一级一次看片| 91精品国产免费| 囯产精品久久久久久| 亚洲精品国产品国语在线| 国内三级在线观看| 久久激情视频免费观看| 国产美女福利在线观看| 国产大片精品免费永久看nba| 欧美一区二区三区婷婷| 国产精品xxxx| 国产精品一在线观看| 天天干天天操天天干天天操| 国内精品99| 中文字幕视频在线免费观看| 国产一区二三区好的| 538国产视频| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 精品一区二区三区影院在线午夜| 乳色吐息在线观看| 99久久er热在这里只有精品15| 五月天婷婷丁香网| 亚洲最大的成人av| 黄色污污视频软件| 欧美刺激午夜性久久久久久久| 日韩精品视频在线观看一区二区三区| 一区二区在线视频播放| 欧美1234区| 国产精品露脸自拍| 欧美电影免费网站| 在线综合视频网站| 香蕉久久久久久久av网站| 日本高清免费在线视频| 久久蜜桃av一区二区天堂| 国产一区二区视频在线观看免费| 欧美性jizz18性欧美| 国产麻豆一精品一男同| 亚洲欧美日韩在线高清直播| 青草视频在线免费直播| 国产美女扒开尿口久久久| 欧美人妖视频| 久操手机在线视频| 蜜桃久久久久久| 丰满少妇在线观看资源站| 亚洲精品国产精品乱码不99| 波多野结衣大片| 日韩av在线看| 91麻豆免费在线视频| 国产精品欧美日韩久久| 日韩有码av| 丰满少妇久久久| 国产伦精品一区二区三区在线观看| 无码人妻精品一区二区三应用大全| 一区二区三区在线视频免费观看| 亚洲手机在线观看| 亚洲一级片在线看| 成人小电影网站| 国产一区二区三区色淫影院| 永久亚洲成a人片777777| 色婷婷.com| 国产午夜精品福利| 四虎成人在线观看| 亚洲美腿欧美激情另类| 久久影院午夜精品| 国产精品一区视频网站| 欧美深夜福利| 中文写幕一区二区三区免费观成熟| 国产精品不卡一区二区三区| 中文字幕永久免费视频| 亚洲性生活视频| 影视一区二区三区| 欧美尤物一区| 老牛国产精品一区的观看方式| 黑人巨大精品欧美| 欧美视频在线看| 美女做暖暖视频免费在线观看全部网址91 | 日韩视频免费观看高清完整版 | 日本电影一区二区| 制服丝袜综合网| 国产精品第13页| 国产精品无码在线播放| 久久国产精品久久久| 日本精品视频| 久久av高潮av| 成人黄色小视频在线观看| 国产无遮挡免费视频| 精品福利在线导航| 国产美女高潮在线观看| 欧美成人dvd在线视频| 老牛嫩草一区二区三区日本| 久久国产柳州莫菁门| 欧美美女直播网站| 七七成人影院| 精品蜜桃一区二区三区| 另类亚洲自拍| 妖精视频在线观看免费| 91精品国产一区二区三区香蕉| 超碰最新在线| 国产一区二区高清视频| 亚洲女同在线| 国产精品视频看看| 欧美刺激脚交jootjob| 性爽视频在线| 亚洲自拍偷拍二区| 粉嫩一区二区三区性色av| 日韩欧美不卡视频| 一区二区亚洲欧洲国产日韩| 国语精品视频| 亚洲人精品午夜射精日韩| 久久久久99精品国产片| 91片黄在线观看喷潮| 欧美激情小视频| 精品av一区二区| 超碰中文字幕在线观看| 黄色成人在线播放| 国产人成在线观看| 99re在线| 免费观看成人鲁鲁鲁鲁鲁视频| 五月天丁香激情| 亚洲深夜福利在线| 日韩成人在线看| 能在线观看的av网站| 一个色综合av| 草草影院在线观看| 国产专区一区二区| 精品一区二区三区在线播放视频| 日韩欧美激情视频| 日韩在线视频免费观看| 欧美成人一区在线观看| 在线免费看污网站| 欧美性猛交99久久久久99按摩| 国产美女av在线| 欧美主播一区二区三区美女 久久精品人 | 海角社区69精品视频| 精品日韩在线视频|