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

[PHP內(nèi)核探索]PHP中的哈希表

移動開發(fā) 開發(fā)
在PHP內(nèi)核中,其中一個很重要的數(shù)據(jù)結(jié)構(gòu)就是HashTable。我們常用的數(shù)組,在內(nèi)核中就是用HashTable來實現(xiàn)。那么,PHP的HashTable是怎么實現(xiàn)的呢?

在PHP內(nèi)核中,其中一個很重要的數(shù)據(jù)結(jié)構(gòu)就是HashTable。我們常用的數(shù)組,在內(nèi)核中就是用HashTable來實現(xiàn)。那么,PHP的HashTable是怎么實現(xiàn)的呢?最近在看HashTable的數(shù)據(jù)結(jié)構(gòu),但是算法書籍里面沒有具體的實現(xiàn)算法,剛好最近也在閱讀PHP的源碼,于是參考PHP的HashTable的實現(xiàn),自己實現(xiàn)了一個簡易版的HashTable,總結(jié)了一些心得,下面給大家分享一下。

筆者github上有一個簡易版的HashTable的實現(xiàn):HashTable實現(xiàn)

另外,我在github有對PHP源碼更詳細的注解。感興趣的可以圍觀一下,給個star。PHP5.4源碼注解。可以通過commit記錄查看已添加的注解。

HashTable的介紹

哈希表是實現(xiàn)字典操作的一種有效數(shù)據(jù)結(jié)構(gòu)。

定義

簡單地說,HashTable(哈希表)就是一種鍵值對的數(shù)據(jù)結(jié)構(gòu)。支持插入,查找,刪除等操作。在一些合理的假設(shè)下,在哈希表中的所有操作的時間復(fù)雜度是O(1)(對相關(guān)證明感興趣的可以自行查閱)。

實現(xiàn)哈希表的關(guān)鍵

在哈希表中,不是使用關(guān)鍵字做下標(biāo),而是通過哈希函數(shù)計算出key的哈希值作為下標(biāo),然后查找/刪除時再計算出key的哈希值,從而快速定位元素保存的位置。

在一個哈希表中,不同的關(guān)鍵字可能會計算得到相同的哈希值,這叫做“哈希沖突”,就是處理兩個或多個鍵的哈希值相同的情況。解決哈希沖突的方法有很多,開放尋址法,拉鏈法等等。

因此,實現(xiàn)一個好的哈希表的關(guān)鍵就是一個好的哈希函數(shù)和處理哈希沖突的方法。

Hash函數(shù)

判斷一個哈希算法的好壞有以下四個定義:

  • 一致性,等價的鍵必然產(chǎn)生相等的哈希值;
  • 高效性,計算簡便;
  • 均勻性,均勻地對所有的鍵進行哈希。

哈希函數(shù)建立了關(guān)鍵值與哈希值的對應(yīng)關(guān)系,即:h = hash_func(key)。對應(yīng)關(guān)系見下圖:

對應(yīng)關(guān)系

設(shè)計一個完美的哈希函數(shù)就交由專家去做吧,我們只管用已有的較成熟的哈希函數(shù)就好了。PHP內(nèi)核使用的哈希函數(shù)是time33函數(shù),又叫DJBX33A,其實現(xiàn)如下:

static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
{
         register ulong hash = 5381;

        /* variant with the hash unrolled eight times */
        for (; nKeyLength >= 8; nKeyLength -= 8) {
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
            hash = ((hash << 5) + hash) + *arKey++;
    }

    switch (nKeyLength) {
        case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
        case 1: hash = ((hash << 5) + hash) + *arKey++; break;
        case 0: break;
        EMPTY_SWITCH_DEFAULT_CASE()
    }
    return hash;
}

注:函數(shù)使用了一個8次循環(huán)+switch來實現(xiàn),是對for循環(huán)的優(yōu)化,減少循環(huán)的運行次數(shù),然后在switch里面執(zhí)行剩下的沒有遍歷到的元素。

拉鏈法

將所有具有相同哈希值的元素都保存在一條鏈表中的方法叫拉鏈法。查找的時候通過先計算key對應(yīng)的哈希值,然后根據(jù)哈希值找到對應(yīng)的鏈表,最后沿著鏈表順序查找相應(yīng)的值。
具體保存后的結(jié)構(gòu)圖如下:

結(jié)構(gòu)圖

PHP的HashTable結(jié)構(gòu)

簡單地介紹了哈希表的數(shù)據(jù)結(jié)構(gòu)之后,繼續(xù)看看PHP中是如何實現(xiàn)哈希表的。

PHP內(nèi)核hashtable的定義:

typedef struct _hashtable {
          uint nTableSize;
          uint nTableMask;
          uint nNumOfElements;
          ulong nNextFreeElement;
          Bucket *pInternalPointer;
          Bucket *pListHead;
          Bucket *pListTail; 
          Bucket **arBuckets;
          dtor_func_t pDestructor;
          zend_bool persistent;
          unsigned char nApplyCount;
          zend_bool bApplyProtection;
          #if ZEND_DEBUG
               int inconsistent;
          #endif
} HashTable;
  • nTableSize,HashTable的大小,以2的倍數(shù)增長
  • nTableMask,用在與哈希值做與運算獲得該哈希值的索引取值,arBuckets初始化后永遠是nTableSize-1
  • nNumOfElements,HashTable當(dāng)前擁有的元素個數(shù),count函數(shù)直接返回這個值
  • nNextFreeElement,表示數(shù)字鍵值數(shù)組中下一個數(shù)字索引的位置
  • pInternalPointer,內(nèi)部指針,指向當(dāng)前成員,用于遍歷元素
  • pListHead,指向HashTable的第一個元素,也是數(shù)組的第一個元素
  • pListTail,指向HashTable的最后一個元素,也是數(shù)組的最后一個元素。與上面的指針結(jié)合,在遍歷數(shù)組時非常方便,比如reset和endAPI
  • arBuckets,包含bucket組成的雙向鏈表的數(shù)組,索引用key的哈希值和nTableMask做與運算生成
  • pDestructor,刪除哈希表中的元素使用的析構(gòu)函數(shù)
  • persistent,標(biāo)識內(nèi)存分配函數(shù),如果是TRUE,則使用操作系統(tǒng)本身的內(nèi)存分配函數(shù),否則使用PHP的內(nèi)存分配函數(shù)
  • nApplyCount,保存當(dāng)前bucket被遞歸訪問的次數(shù),防止多次遞歸
  • bApplyProtection,標(biāo)識哈希表是否要使用遞歸保護,默認是1,要使用

舉一個哈希與mask結(jié)合的例子:

例如,”foo”真正的哈希值(使用DJBX33A哈希函數(shù))是193491849。如果我們現(xiàn)在有64容量的哈希表,我們明顯不能使用它作為數(shù)組的下標(biāo)。取而代之的是通過應(yīng)用哈希表的mask,然后只取哈希表的低位。

hash           |        193491849  |     0b1011100010000111001110001001
& mask         | &             63  | &   0b0000000000000000000000111111
----------------------------------------------------------------------
= index        | = 9               | =   0b0000000000000000000000001001

因此,在哈希表中,foo是保存在arBuckets中下標(biāo)為9的bucket向量中。

bucket結(jié)構(gòu)體的定義

typedef struct bucket {
     ulong h;
     uint nKeyLength;
     void *pData;
     void *pDataPtr;
     struct bucket *pListNext;
     struct bucket *pListLast;
     struct bucket *pNext;
     struct bucket *pLast;
     const char *arKey;
} Bucket;
  • h,哈希值(或數(shù)字鍵值的key
  • nKeyLength,key的長度
  • pData,指向數(shù)據(jù)的指針
  • pDataPtr,指針數(shù)據(jù)
  • pListNext,指向HashTable中的arBuckets鏈表中的下一個元素
  • pListLast,指向HashTable中的arBuckets鏈表中的上一個元素
  • pNext,指向具有相同hash值的bucket鏈表中的下一個元素
  • pLast,指向具有相同hash值的bucket鏈表中的上一個元素
  • arKey,key的名稱

PHP中的HashTable是采用了向量加雙向鏈表的實現(xiàn)方式,向量在arBuckets變量保存,向量包含多個bucket的指針,每個指針指向由多個bucket組成的雙向鏈表,新元素的加入使用前插法,即新元素總是在bucket的第一個位置。由上面可以看到,PHP的哈希表實現(xiàn)相當(dāng)復(fù)雜。這是它使用超靈活的數(shù)組類型要付出的代價。

一個PHP中的HashTable的示例圖如下所示:

HashTable

HashTable相關(guān)API

  • zend_hash_init
  • zend_hash_add_or_update
  • zend_hash_find
  • zend_hash_del_key_or_index

zend_hash_init

函數(shù)執(zhí)行步驟

  • 設(shè)置哈希表大小
  • 設(shè)置結(jié)構(gòu)體其他成員變量的初始值 (包括釋放內(nèi)存用的析構(gòu)函數(shù)pDescructor)

詳細代碼注解點擊:zend_hash_init源碼

注:

1、pHashFunction在此處并沒有用到,php的哈希函數(shù)使用的是內(nèi)部的zend_inline_hash_func

2、zend_hash_init執(zhí)行之后并沒有真正地為arBuckets分配內(nèi)存和計算出nTableMask的大小,真正分配內(nèi)存和計算nTableMask是在插入元素時進行CHECK_INIT檢查初始化時進行。

zend_hash_add_or_update

函數(shù)執(zhí)行步驟

  • 檢查鍵的長度
  • 檢查初始化
  • 計算哈希值和下標(biāo)
  • 遍歷哈希值所在的bucket,如果找到相同的key且值需要更新,則更新數(shù)據(jù),否則繼續(xù)指向bucket的下一個元素,直到指向bucket的最后一個位置
  • 為新加入的元素分配bucket,設(shè)置新的bucket的屬性值,然后添加到哈希表中
  • 如果哈希表空間滿了,則重新調(diào)整哈希表的大小

函數(shù)執(zhí)行流程圖

 

CONNECT_TO_BUCKET_DLLIST是將新元素添加到具有相同hash值的bucket鏈表。

CONNECT_TO_GLOBAL_DLLIST是將新元素添加到HashTable的雙向鏈表。

詳細代碼和注解請點擊:zend_hash_add_or_update代碼注解

zend_hash_find

函數(shù)執(zhí)行步驟

  • 計算哈希值和下標(biāo)
  • 遍歷哈希值所在的bucket,如果找到key所在的bucket,則返回值,否則,指向下一個bucket,直到指向bucket鏈表中的最后一個位置

詳細代碼和注解請點擊:zend_hash_find代碼注解

zend_hash_del_key_or_index

函數(shù)執(zhí)行步驟

  • 計算key的哈希值和下標(biāo)
  • 遍歷哈希值所在的bucket,如果找到key所在的bucket,則進行第三步,否則,指向下一個bucket,直到指向bucket鏈表中的最后一個位置
  • 如果要刪除的是第一個元素,直接將arBucket[nIndex]指向第二個元素;其余的操作是將當(dāng)前指針的last的next執(zhí)行當(dāng)前的next
  • 調(diào)整相關(guān)指針
  • 釋放數(shù)據(jù)內(nèi)存和bucket結(jié)構(gòu)體內(nèi)存

詳細代碼和注解請點擊:zend_hash_del_key_or_index代碼注解

性能分析

PHP的哈希表的優(yōu)點:PHP的HashTable為數(shù)組的操作提供了很大的方便,無論是數(shù)組的創(chuàng)建和新增元素或刪除元素等操作,哈希表都提供了很好的性能,但其不足在數(shù)據(jù)量大的時候比較明顯,從時間復(fù)雜度和空間復(fù)雜度看看其不足。

不足如下:

  • 保存數(shù)據(jù)的結(jié)構(gòu)體zval需要單獨分配內(nèi)存,需要管理這個額外的內(nèi)存,每個zval占用了16bytes的內(nèi)存;
  • 在新增bucket時,bucket也是額外分配,也需要16bytes的內(nèi)存;
  • 為了能進行順序遍歷,使用雙向鏈表連接整個HashTable,多出了很多的指針,每個指針也要16bytes的內(nèi)存;
  • 在遍歷時,如果元素位于bucket鏈表的尾部,也需要遍歷完整個bucket鏈表才能找到所要查找的值

PHP的HashTable的不足主要是其雙向鏈表多出的指針及zval和bucket需要額外分配內(nèi)存,因此導(dǎo)致占用了很多內(nèi)存空間及查找時多出了不少時間的消耗。

后續(xù)

上面提到的不足,在PHP7中都很好地解決了,PHP7對內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)做了一個大改造,使得PHP的效率高了很多,因此,推薦PHP開發(fā)者都將開發(fā)和部署版本更新吧。看看下面這段PHP代碼:

<?php
$size = pow(2, 16); 
 
$startTime = microtime(true);
$array = array();
for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $maxKey; $key += $size) {
    $array[$key] = 0;
}
$endTime = microtime(true);
echo '插入 ', $size, ' 個惡意的元素需要 ', $endTime - $startTime, ' 秒', "\n";
 
$startTime = microtime(true);
$array = array();
for ($key = 0, $maxKey = $size - 1; $key <= $maxKey; ++$key) {
    $array[$key] = 0;
}
$endTime = microtime(true);
echo '插入 ', $size, ' 個普通元素需要 ', $endTime - $startTime, ' 秒', "\n";

上面這個demo是有多個hash沖突時和無沖突時的時間消耗比較。筆者在PHP5.4下運行這段代碼,結(jié)果如下

插入 65536 個惡意的元素需要 43.72204709053 秒

插入 65536 個普通元素需要 0.009843111038208 秒

而在PHP7上運行的結(jié)果:

插入 65536 個惡意的元素需要 4.4028408527374 秒

插入 65536 個普通元素需要 0.0018510818481445 秒

可見不論在有沖突和無沖突的數(shù)組操作,PHP7的性能都提升了不少,當(dāng)然,有沖突的性能提升更為明顯。至于為什么PHP7的性能提高了這么多,值得繼續(xù)深究。

最后再安利一下,筆者github上有一個簡易版的HashTable的實現(xiàn):HashTable實現(xiàn)

另外,我在github有對PHP源碼更詳細的注解。感興趣的可以圍觀一下,給個star。PHP5.4源碼注解。可以通過commit記錄查看已添加的注解。

原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬望告知。

如果本文對你有幫助,請點下推薦吧,謝謝^_^

參考文章:

PHP數(shù)組的Hash沖突實例

Understanding PHP's internal array implementation (PHP's Source Code for PHP Developers - Part 4)

責(zé)任編輯:張子龍 來源: 博客園
相關(guān)推薦

2016-12-21 10:35:55

PHP內(nèi)核PHP哈希表

2017-07-19 16:58:53

PHPFastCGI 內(nèi)核探索

2017-06-01 10:44:29

2010-11-24 13:58:11

mysql表

2017-03-01 20:08:36

PHP內(nèi)核分析

2014-11-11 15:25:30

PHPWeb

2010-11-24 10:05:20

mysql創(chuàng)建臨時表

2017-02-27 16:22:52

2011-05-11 17:40:30

PHP正則表達式

2011-07-19 11:12:36

PHPMySQL數(shù)據(jù)庫

2011-07-12 17:11:13

PHPSHELL

2015-09-16 15:01:30

PHP內(nèi)核

2011-07-07 10:41:07

php批量刪除

2011-02-22 14:10:25

PHPXML

2018-04-22 00:04:04

PHP C 代碼數(shù)據(jù)

2018-08-01 14:45:16

PHP編程語言

2011-07-14 15:05:54

PHP

2011-07-12 17:06:43

PHP

2014-08-18 09:31:15

2009-02-10 10:57:09

危險函數(shù)PHPCLI
點贊
收藏

51CTO技術(shù)棧公眾號

国产99精品| 直接在线观看的三级网址| 久久久久久9| 日韩有码片在线观看| 亚洲国产精品第一页| 忘忧草在线影院两性视频| 中文字幕av一区二区三区免费看| 亚洲最大福利网站| 欧美性猛交bbbbb精品| 日韩理论电影大全| 亚洲国产精品久久| 久久撸在线视频| 韩国成人免费视频| 欧美国产97人人爽人人喊| 成人午夜电影免费在线观看| 少妇无套内谢久久久久| 亚洲无线一线二线三线区别av| 久久嫩草精品久久久久| 国产日韩欧美综合| 免费在线不卡视频| 亚洲精品一二三区区别| 亚洲毛片在线观看.| 97人人模人人爽人人澡| 手机看片久久| 99久久99久久精品免费观看| 国产精品专区一| 成年人午夜视频| 国产精品福利在线观看播放| 亚洲美女激情视频| 麻豆tv在线观看| 人人玩人人添人人澡欧美| 天天综合天天综合色| 熟女视频一区二区三区| 国产最新视频在线| 91色在线porny| 岛国视频一区免费观看| 一级黄色片免费看| 日韩电影在线一区| 91av在线免费观看| 免费麻豆国产一区二区三区四区| av成人在线网站| 色一情一乱一乱一91av| 久色视频在线播放| 黄色大片在线| 亚洲一区二区欧美日韩| 亚洲色婷婷久久精品av蜜桃| 日本成a人片在线观看| 紧缚奴在线一区二区三区| 欧美诱惑福利视频| 日韩免费不卡视频| 136国产福利精品导航网址| 九九精品在线观看| 亚洲熟女www一区二区三区| 日韩在线精品| 日韩一区二区三区xxxx| 一二三四国产精品| 98精品视频| 中文字幕日韩av电影| 无码人妻aⅴ一区二区三区69岛| 久久视频在线观看| 日韩成人网免费视频| 玖草视频在线观看| 欧美精选视频一区二区| 五月激情六月综合| av免费播放网址| 这里有精品可以观看| 欧美午夜电影在线| 成人中文字幕av| 成人在线高清| 在线播放亚洲一区| 永久看看免费大片| 国产厕拍一区| 精品在线观看国产| 日韩毛片无码永久免费看| 日韩88av| 久99九色视频在线观看| 动漫精品一区一码二码三码四码| 99成人免费视频| 庆余年2免费日韩剧观看大牛| av片免费观看| 久久电影网电视剧免费观看| 51成人做爰www免费看网站| 亚洲乱码在线观看| 99综合电影在线视频| 国产美女精品视频免费观看| 一区二区国产欧美| 国产成人免费xxxxxxxx| 九9re精品视频在线观看re6 | 99精品免费视频| 热99精品只有里视频精品| 性色av一区二区三区四区| 激情成人午夜视频| 精品国产中文字幕| 岛国视频免费在线观看| 日本v片在线高清不卡在线观看| 国产精品爽黄69| 亚洲av无码乱码国产精品久久| 91影院在线免费观看| 亚洲一区二区自拍偷拍| 波多野结衣久久| 欧美日韩国产综合一区二区三区| 少妇极品熟妇人妻无码| 国产一区二区电影在线观看| 欧美成人自拍视频| 无码免费一区二区三区| 夫妻av一区二区| 午夜精品美女久久久久av福利| 高潮毛片7777777毛片| 26uuuu精品一区二区| 五月天男人天堂| 涩涩视频在线| 亚洲成人精品一区二区| 冲田杏梨av在线| 高清日韩中文字幕| 日韩中文字幕av| 亚洲国产成人精品激情在线| 久久99精品久久久久久动态图| 国产亚洲精品久久飘花| 国产美女在线观看| 在线观看成人小视频| 99久久久无码国产精品性波多 | 永久免费毛片在线播放不卡| 欧美三级在线免费观看| 免费日本视频一区| 久久国产手机看片| 日本片在线观看| 欧美日韩中文字幕一区| 一级黄色片大全| 国产精品久久久久久久久久妞妞| 亚洲xxxxx电影| 中文字幕在线观看日本| 欧美性xxxx极品高清hd直播 | 国产丝袜欧美中文另类| 分分操这里只有精品| 日韩欧美一起| 欧美三区在线观看| 国产综合精品在线| 免费亚洲视频| 久久99精品久久久久久三级| 91www在线| 欧美成人三级在线| 欧美黑人精品一区二区不卡| 国内精品伊人久久久久av一坑| 亚洲欧美日韩在线综合| 在线一区视频观看| 一本色道久久88亚洲综合88| 精品国产xxx| www国产精品av| av天堂永久资源网| 搜成人激情视频| 国产婷婷色综合av蜜臀av| 日韩美女一级片| 99久久精品国产观看| 欧美视频在线观看网站| 国偷自产av一区二区三区| 欧美日韩成人黄色| 人妻一区二区三区四区| 亚洲成在人线免费| 一级特黄a大片免费| 日韩电影在线视频| 国产精品第1页| 91激情在线| 欧美男男青年gay1069videost| 欧美性生给视频| 激情综合色综合久久综合| 五月天在线免费视频| 视频精品一区二区三区| 久久久久国产精品免费| 性xxxx18| 在线观看免费一区| 五月天婷婷色综合| 国产91在线|亚洲| 又粗又黑又大的吊av| 国产亚洲一区| 91丝袜美腿美女视频网站| 亚洲淫性视频| 亚洲精品久久久久中文字幕欢迎你 | 国外成人免费在线播放| 神马亚洲视频| 亚洲色图欧洲色图| 特黄特色免费视频| 国产精品入口66mio| 亚洲国产欧美日韩| 深夜福利一区| 国产高清在线不卡| 免费观看a视频| 日韩欧美一区二区在线| 色偷偷男人天堂| 国产麻豆91精品| 欧美日产一区二区三区在线观看| 精品网站在线| 欧美日韩福利在线观看| 人操人视频在线观看| 欧美男人的天堂一二区| 国产 欧美 日韩 在线| 欧美国产一区在线| 日本wwwwwww| 日本91福利区| 国产一二三在线视频| 大胆日韩av| 国产精品一码二码三码在线| 日韩漫画puputoon| 97精品国产97久久久久久春色| 最新97超碰在线| 亚洲精品久久在线| 国产亲伦免费视频播放| 91黄色小视频| 亚洲久久久久久久| 狠狠狠色丁香婷婷综合久久五月| 久久精品视频16| 忘忧草精品久久久久久久高清| 精品国产一区二区三区四区精华 | 国产精品一区二区免费看| 亚洲精品555| 77777亚洲午夜久久多人| 麻豆视频在线免费观看| 亚洲美女自拍视频| 亚洲国产一二三区| 6080日韩午夜伦伦午夜伦| 久久国产视频精品| 亚洲二区在线观看| www.av视频| 国产精品入口麻豆原神| 亚洲第一香蕉网| av不卡在线播放| 久久久久99人妻一区二区三区| 蜜桃av噜噜一区| 少妇人妻互换不带套| 亚洲毛片播放| 国产成人在线小视频| 婷婷色综合网| 中文视频一区视频二区视频三区| 国产一区二区三区四区五区| 久久66热这里只有精品| 精品视频自拍| 国产精品自拍首页| 69精品国产久热在线观看| 亚洲综合色激情五月| 91精品国产色综合久久不卡粉嫩| 国产精品一区二区久久久| 午夜欧美巨大性欧美巨大| 国产91精品不卡视频| 国产ktv在线视频| 国内精品小视频| 国产极品在线观看| 久久人人爽人人爽人人片av高清| 欧美videosex性欧美黑吊| 久久夜色撩人精品| 丰满人妻一区二区三区免费视频 | 欧美一区二区.| 黄在线观看免费网站ktv| 韩国三级电影久久久久久| 丁香花在线观看完整版电影| 久久久久女教师免费一区| 波多野结依一区| 2019中文在线观看| 电影一区二区三| 国产精品精品久久久| 成人免费在线观看视频| 91精品久久久久久综合乱菊| 亚洲精品aaa| 亚洲综合视频1区| 精品素人av| 日本一区二区三区视频免费看| 国产成人精品999在线观看| 色就是色欧美| 婷婷综合社区| 国产aaa免费视频| 亚洲永久字幕| 国产日韩成人内射视频| 蜜臀a∨国产成人精品| 伊人影院综合在线| 国产真实乱对白精彩久久| 波多野结衣家庭教师在线| 翔田千里一区二区| 亚洲欧美国产日韩综合| 激情欧美日韩一区二区| 国产精品偷伦视频免费观看了| 91丨九色丨蝌蚪富婆spa| 亚洲国产av一区| 综合电影一区二区三区 | 欧美日韩国产在线一区| 国产3p露脸普通话对白| 久久最新视频| 三级av免费看| 99re热这里只有精品免费视频| 亚洲а∨天堂久久精品2021| 综合av第一页| 在线观看黄网站| 欧美年轻男男videosbes| 成人免费公开视频| 国产一区二区三区日韩欧美| 亚洲aⅴ乱码精品成人区| 亚洲人线精品午夜| av小次郎在线| 日韩免费在线观看视频| 欧美成年网站| 亚洲成人第一| 亚洲第一黄网| 手机av在线免费| 99久久久无码国产精品| 少妇视频一区二区| 欧美网站在线观看| 精品人妻一区二区三区三区四区| 亚洲美女久久久| 色呦呦网站在线观看| 国产精品扒开腿做爽爽爽男男| 日本一区二区乱| 丝袜美腿玉足3d专区一区| 亚洲午夜久久久久久尤物 | 国产一区二区三区蝌蚪| aa一级黄色片| 洋洋av久久久久久久一区| 涩涩视频在线观看| 亚洲精品720p| 2021国产在线| 国产精品一区二区三区久久久| 欧美freesex8一10精品| 亚洲国产一二三精品无码| 蜜臀av在线播放一区二区三区 | 国产99久久九九精品无码免费| 亚洲欧美日韩直播| gogo高清午夜人体在线| 亚洲一区美女视频在线观看免费| 欧美在线电影| 国产l精品国产亚洲区久久| 国产99精品国产| 青青草手机在线视频| 欧美浪妇xxxx高跟鞋交| av大片在线看| 国产精品黄页免费高清在线观看| 日韩高清成人在线| 真人抽搐一进一出视频| 国产精品羞羞答答xxdd| 九九这里只有精品视频| 欧美系列亚洲系列| 成年人在线视频免费观看| 青青草原一区二区| 久草精品在线| 日本黄网站免费| 久久视频一区二区| 青青草免费观看视频| 日韩精品www| 特黄毛片在线观看| 精品国产乱码久久久久久88av| 精品999网站| 中文字幕精品视频在线| 五月天网站亚洲| 亚洲av激情无码专区在线播放| 88xx成人精品| 亚洲伊人春色| 人妻丰满熟妇av无码区app| 国产视频一区二区三区在线观看| 亚洲 日本 欧美 中文幕| 亚洲午夜色婷婷在线| 色成人免费网站| 亚洲资源视频| 国精产品一区一区三区mba桃花| 色欲人妻综合网| 日韩精品自拍偷拍| 高清视频在线观看三级| 欧美久久久久久久| 日本免费在线视频不卡一不卡二| 奇米网一区二区| 日韩一级片在线观看| 国产经典三级在线| 国产一区视频观看| 久久精品主播| 少妇高潮惨叫久久久久| 91精品国产全国免费观看| 深夜福利在线视频| 日韩av免费网站| 久久精品av| www.欧美com| 欧美视频免费在线观看| 狠狠狠综合7777久夜色撩人 | 亚洲天堂2021av| 久久不射电影网| 老司机精品视频在线播放| 免费午夜视频在线观看| 中文字幕在线播放不卡一区| 粉嫩aⅴ一区二区三区| 亚洲免费一在线| 婷婷精品久久久久久久久久不卡| 亚洲乱码日产精品bd在线观看| 91香蕉视频在线| 一区二区视频网站| 欧美激情在线观看视频| 免费成人结看片| 男女视频在线观看网站| 欧美日韩精品二区| 色综合久久影院| 狠狠色噜噜狠狠色综合久| 日韩精品高清不卡| 国产一级特黄视频| 亚洲欧美色图片| 秋霞一区二区| 免费一级特黄特色毛片久久看| 国产精品久久久久久亚洲毛片| 亚洲精品久久久久avwww潮水|