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

一篇學會Caffeine W-TinyLFU源碼分析

開發 前端
Caffeine使用一個ConcurrencyHashMap來保存所有數據,那它的過期淘汰策略采用什么方式與數據結構呢?其中寫過期是使用writeOrderDeque,這個比較簡單無需多說,而讀過期相對復雜很多,使用W-TinyLFU的結構與算法。

[[410834]]

本文轉載自微信公眾號「肌肉碼農」,作者肌肉碼農。轉載本文請聯系肌肉碼農公眾號。

Caffeine使用一個ConcurrencyHashMap來保存所有數據,那它的過期淘汰策略采用什么方式與數據結構呢?其中寫過期是使用writeOrderDeque,這個比較簡單無需多說,而讀過期相對復雜很多,使用W-TinyLFU的結構與算法。

網絡上有很多文章介紹W-TinyLFU結構的,大家可以去查一下,這里主要是從源碼來分析,總的來說它使用了三個雙端隊列:accessOrderEdenDeque,accessOrderProbationDeque,accessOrderProtectedDeque,使用雙端隊列的原因是支持LRU算法比較方便。

accessOrderEdenDeque屬于eden區,緩存1%的數據,其余的99%緩存在main區。

accessOrderProbationDeque屬于main區,緩存main內數據的20%,這部分是屬于冷數據,即將補淘汰。

accessOrderProtectedDeque屬于main區,緩存main內數據的80%,這部分是屬于熱數據,是整個緩存的主存區。

我們先看一下淘汰方法入口:

  1. void evictEntries() { 
  2.   if (!evicts()) { 
  3.     return
  4.   } 
  5.   //先從edn區淘汰 
  6.   int candidates = evictFromEden(); 
  7.   //eden淘汰后的數據進入main區,然后再從main區淘汰 
  8.   evictFromMain(candidates); 

accessOrderEdenDeque對應W-TinyLFU的W(window),這里保存的是最新寫入數據的引用,它使用LRU淘汰,這里面的數據主要是應對突發流量的問題,淘汰后的數據進入accessOrderProbationDeque.代碼如下:

  1. int evictFromEden() { 
  2.   int candidates = 0; 
  3.   Node<K, V> node = accessOrderEdenDeque().peek(); 
  4.   while (edenWeightedSize() > edenMaximum()) { 
  5.     // The pending operations will adjust the size to reflect the correct weight 
  6.     if (node == null) { 
  7.       break; 
  8.     } 
  9.  
  10.     Node<K, V> next = node.getNextInAccessOrder(); 
  11.     if (node.getWeight() != 0) { 
  12.       node.makeMainProbation(); 
  13.       //先從eden區移除 
  14.       accessOrderEdenDeque().remove(node); 
  15.       //移除的數據加入到main區的probation隊列 
  16.       accessOrderProbationDeque().add(node); 
  17.       candidates++; 
  18.  
  19.       lazySetEdenWeightedSize(edenWeightedSize() - node.getPolicyWeight()); 
  20.     } 
  21.     node = next
  22.   } 
  23.  
  24.   return candidates; 

數據進入probation隊列后,繼續執行以下代碼:

  1. void evictFromMain(int candidates) { 
  2.   int victimQueue = PROBATION; 
  3.   Node<K, V> victim = accessOrderProbationDeque().peekFirst(); 
  4.   Node<K, V> candidate = accessOrderProbationDeque().peekLast(); 
  5.   while (weightedSize() > maximum()) { 
  6.     // Stop trying to evict candidates and always prefer the victim 
  7.     if (candidates == 0) { 
  8.       candidate = null
  9.     } 
  10.  
  11.     // Try evicting from the protected and eden queues 
  12.     if ((candidate == null) && (victim == null)) { 
  13.       if (victimQueue == PROBATION) { 
  14.         victim = accessOrderProtectedDeque().peekFirst(); 
  15.         victimQueue = PROTECTED; 
  16.         continue
  17.       } else if (victimQueue == PROTECTED) { 
  18.         victim = accessOrderEdenDeque().peekFirst(); 
  19.         victimQueue = EDEN; 
  20.         continue
  21.       } 
  22.  
  23.       // The pending operations will adjust the size to reflect the correct weight 
  24.       break; 
  25.     } 
  26.  
  27.     // Skip over entries with zero weight 
  28.     if ((victim != null) && (victim.getPolicyWeight() == 0)) { 
  29.       victim = victim.getNextInAccessOrder(); 
  30.       continue
  31.     } else if ((candidate != null) && (candidate.getPolicyWeight() == 0)) { 
  32.       candidate = candidate.getPreviousInAccessOrder(); 
  33.       candidates--; 
  34.       continue
  35.     } 
  36.  
  37.     // Evict immediately if only one of the entries is present 
  38.     if (victim == null) { 
  39.       candidates--; 
  40.       Node<K, V> evict = candidate; 
  41.       candidate = candidate.getPreviousInAccessOrder(); 
  42.       evictEntry(evict, RemovalCause.SIZE, 0L); 
  43.       continue
  44.     } else if (candidate == null) { 
  45.       Node<K, V> evict = victim; 
  46.       victim = victim.getNextInAccessOrder(); 
  47.       evictEntry(evict, RemovalCause.SIZE, 0L); 
  48.       continue
  49.     } 
  50.  
  51.     // Evict immediately if an entry was collected 
  52.     K victimKey = victim.getKey(); 
  53.     K candidateKey = candidate.getKey(); 
  54.     if (victimKey == null) { 
  55.       Node<K, V> evict = victim; 
  56.       victim = victim.getNextInAccessOrder(); 
  57.       evictEntry(evict, RemovalCause.COLLECTED, 0L); 
  58.       continue
  59.     } else if (candidateKey == null) { 
  60.       candidates--; 
  61.       Node<K, V> evict = candidate; 
  62.       candidate = candidate.getPreviousInAccessOrder(); 
  63.       evictEntry(evict, RemovalCause.COLLECTED, 0L); 
  64.       continue
  65.     } 
  66.  
  67.     // Evict immediately if the candidate's weight exceeds the maximum 
  68.     if (candidate.getPolicyWeight() > maximum()) { 
  69.       candidates--; 
  70.       Node<K, V> evict = candidate; 
  71.       candidate = candidate.getPreviousInAccessOrder(); 
  72.       evictEntry(evict, RemovalCause.SIZE, 0L); 
  73.       continue
  74.     } 
  75.  
  76.     // Evict the entry with the lowest frequency 
  77.     candidates--; 
  78.     //最核心算法在這里:從probation的頭尾取出兩個node進行比較頻率,頻率更小者將被remove 
  79.     if (admit(candidateKey, victimKey)) { 
  80.       Node<K, V> evict = victim; 
  81.       victim = victim.getNextInAccessOrder(); 
  82.       evictEntry(evict, RemovalCause.SIZE, 0L); 
  83.       candidate = candidate.getPreviousInAccessOrder(); 
  84.     } else { 
  85.       Node<K, V> evict = candidate; 
  86.       candidate = candidate.getPreviousInAccessOrder(); 
  87.       evictEntry(evict, RemovalCause.SIZE, 0L); 
  88.     } 
  89.   } 

上面的代碼邏輯是從probation的頭尾取出兩個node進行比較頻率,頻率更小者將被remove,其中尾部元素就是上一部分從eden中淘汰出來的元素,如果將兩步邏輯合并起來講是這樣的:在eden隊列通過lru淘汰出來的”候選者“與probation隊列通過lru淘汰出來的“被驅逐者“進行頻率比較,失敗者將被從cache中真正移除。下面看一下它的比較邏輯admit:

  1. boolean admit(K candidateKey, K victimKey) { 
  2.   int victimFreq = frequencySketch().frequency(victimKey); 
  3.   int candidateFreq = frequencySketch().frequency(candidateKey); 
  4.   //如果候選者的頻率高就淘汰被驅逐者 
  5.   if (candidateFreq > victimFreq) { 
  6.     return true
  7.     //如果被驅逐者比候選者的頻率高,并且候選者頻率小于等于5則淘汰者 
  8.   } else if (candidateFreq <= 5) { 
  9.     // The maximum frequency is 15 and halved to 7 after a reset to age the history. An attack 
  10.     // exploits that a hot candidate is rejected in favor of a hot victim. The threshold of a warm 
  11.     // candidate reduces the number of random acceptances to minimize the impact on the hit rate. 
  12.     return false
  13.   } 
  14.   //隨機淘汰 
  15.   int random = ThreadLocalRandom.current().nextInt(); 
  16.   return ((random & 127) == 0); 

從frequencySketch取出候選者與被驅逐者的頻率,如果候選者的頻率高就淘汰被驅逐者,如果被驅逐者比候選者的頻率高,并且候選者頻率小于等于5則淘汰者,如果前面兩個條件都不滿足則隨機淘汰。

整個過程中你是不是發現protectedDeque并沒有什么作用,那它是怎么作為主存區來保存大部分數據的呢?

  1. //onAccess方法觸發該方法  
  2. void reorderProbation(Node<K, V> node) { 
  3.   if (!accessOrderProbationDeque().contains(node)) { 
  4.     // Ignore stale accesses for an entry that is no longer present 
  5.     return
  6.   } else if (node.getPolicyWeight() > mainProtectedMaximum()) { 
  7.     return
  8.   } 
  9.  
  10.   long mainProtectedWeightedSize = mainProtectedWeightedSize() + node.getPolicyWeight(); 
  11.  //先從probation中移除 
  12.  accessOrderProbationDeque().remove(node); 
  13. //加入到protected中 
  14.   accessOrderProtectedDeque().add(node); 
  15.   node.makeMainProtected(); 
  16.  
  17.   long mainProtectedMaximum = mainProtectedMaximum(); 
  18. //從protected中移除 
  19.   while (mainProtectedWeightedSize > mainProtectedMaximum) { 
  20.     Node<K, V> demoted = accessOrderProtectedDeque().pollFirst(); 
  21.     if (demoted == null) { 
  22.       break; 
  23.     } 
  24.     demoted.makeMainProbation(); 
  25.     //加入到probation中 
  26.     accessOrderProbationDeque().add(demoted); 
  27.     mainProtectedWeightedSize -= node.getPolicyWeight(); 
  28.   } 
  29.  
  30.   lazySetMainProtectedWeightedSize(mainProtectedWeightedSize); 

當數據被訪問時并且該數據在probation中,這個數據就會移動到protected中去,同時通過lru從protected中淘汰一個數據進入到probation中。

這樣數據流轉的邏輯全部通了:新數據都會進入到eden中,通過lru淘汰到probation,并與probation中通過lru淘汰的數據進行使用頻率pk,如果勝利了就繼續留在probation中,如果失敗了就會被直接淘汰,當這條數據被訪問了,則移動到protected。當其它數據被訪問了,則它可能會從protected中通過lru淘汰到probation中。

TinyLFU

傳統LFU一般使用key-value形式來記錄每個key的頻率,優點是數據結構非常簡單,并且能跟緩存本身的數據結構復用,增加一個屬性記錄頻率就行了,它的缺點也比較明顯就是頻率這個屬性會占用很大的空間,但如果改用壓縮方式存儲頻率呢? 頻率占用空間肯定可以減少,但會引出另外一個問題:怎么從壓縮后的數據里獲得對應key的頻率呢?

TinyLFU的解決方案是類似位圖的方法,將key取hash值獲得它的位下標,然后用這個下標來找頻率,但位圖只有0、1兩個值,那頻率明顯可能會非常大,這要怎么處理呢? 另外使用位圖需要預占非常大的空間,這個問題怎么解決呢?

TinyLFU根據最大數據量設置生成一個long數組,然后將頻率值保存在其中的四個long的4個bit位中(4個bit位不會大于15),取頻率值時則取四個中的最小一個。

Caffeine認為頻率大于15已經很高了,是屬于熱數據,所以它只需要4個bit位來保存,long有8個字節64位,這樣可以保存16個頻率。取hash值的后左移兩位,然后加上hash四次,這樣可以利用到16個中的13個,利用率挺高的,或許有更好的算法能將16個都利用到。

  1. public void increment(@Nonnull E e) { 
  2.     if (isNotInitialized()) { 
  3.       return
  4.     } 
  5.  
  6.     int hash = spread(e.hashCode()); 
  7.     int start = (hash & 3) << 2; 
  8.  
  9.     // Loop unrolling improves throughput by 5m ops/s 
  10.     int index0 = indexOf(hash, 0); //indexOf也是一種hash方法,不過會通過tableMask來限制范圍 
  11.     int index1 = indexOf(hash, 1); 
  12.     int index2 = indexOf(hash, 2); 
  13.     int index3 = indexOf(hash, 3); 
  14.  
  15.     boolean added = incrementAt(index0, start); 
  16.     added |= incrementAt(index1, start + 1); 
  17.     added |= incrementAt(index2, start + 2); 
  18.     added |= incrementAt(index3, start + 3); 
  19.  
  20.     //當數據寫入次數達到數據長度時就重置 
  21.     if (added && (++size == sampleSize)) { 
  22.       reset(); 
  23.     } 
  24.   } 

給對應位置的bit位四位的Int值加1:

  1. boolean incrementAt(int i, int j) { 
  2.   int offset = j << 2; 
  3.   long mask = (0xfL << offset); 
  4.   //當已達到15時,次數不再增加 
  5.   if ((table[i] & mask) != mask) { 
  6.     table[i] += (1L << offset); 
  7.     return true
  8.   } 
  9.   return false

獲得值的方法也是通過四次hash來獲得,然后取最小值:

  1. public int frequency(@Nonnull E e) { 
  2.   if (isNotInitialized()) { 
  3.     return 0; 
  4.   } 
  5.  
  6.   int hash = spread(e.hashCode()); 
  7.   int start = (hash & 3) << 2; 
  8.   int frequency = Integer.MAX_VALUE; 
  9.   //四次hash 
  10.   for (int i = 0; i < 4; i++) { 
  11.     int index = indexOf(hash, i); 
  12.     //獲得bit位四位的Int值 
  13.     int count = (int) ((table[index] >>> ((start + i) << 2)) & 0xfL); 
  14.     //取最小值 
  15.     frequency = Math.min(frequency, count); 
  16.   } 
  17.   return frequency; 

當數據寫入次數達到數據長度時就會將次數減半,一些冷數據在這個過程中將歸0,這樣會使hash沖突降低:

  1. void reset() { 
  2.   int count = 0; 
  3.   for (int i = 0; i < table.length; i++) { 
  4.     count += Long.bitCount(table[i] & ONE_MASK); 
  5.     table[i] = (table[i] >>> 1) & RESET_MASK; 
  6.   } 
  7.   size = (size >>> 1) - (count >>> 2); 

 

責任編輯:武曉燕 來源: 肌肉碼農
相關推薦

2021-11-08 11:21:18

redis 淘汰算法

2021-07-02 08:51:29

源碼參數Thread

2021-10-14 10:22:19

逃逸JVM性能

2022-01-02 08:43:46

Python

2022-02-07 11:01:23

ZooKeeper

2022-06-08 11:39:29

經營分析指標

2021-07-06 08:59:18

抽象工廠模式

2023-11-28 08:29:31

Rust內存布局

2023-01-03 08:31:54

Spring讀取器配置

2021-07-02 09:45:29

MySQL InnoDB數據

2021-07-05 22:11:38

MySQL體系架構

2022-08-23 08:00:59

磁盤性能網絡

2021-05-11 08:54:59

建造者模式設計

2022-08-26 09:29:01

Kubernetes策略Master

2022-04-12 08:30:52

回調函數代碼調試

2021-07-16 22:43:10

Go并發Golang

2021-04-29 10:18:18

循環依賴數組

2022-10-20 07:39:26

2023-11-01 09:07:01

Spring裝配源碼

2022-03-11 10:21:30

IO系統日志
點贊
收藏

51CTO技術棧公眾號

一区二区三区福利视频| 日本一级大毛片a一| 香蕉视频在线看| 精品午夜久久福利影院| 欧美激情图片区| 波多野结衣办公室33分钟| 国产第一精品| 亚洲综合精品自拍| 日本高清不卡一区二区三| 国产巨乳在线观看| 国产精品日本| 欧美成年人在线观看| 色婷婷精品久久二区二区密| 国产69精品久久| 亚洲二区在线视频| 伊人久久大香线蕉综合75| 天堂网在线中文| 麻豆精品一区二区综合av| 欧美日本国产在线| 亚洲色成人网站www永久四虎| 精品国产鲁一鲁****| 日韩欧美在线视频日韩欧美在线视频| 中文字幕精品—区二区日日骚| 性高潮久久久久久久久久| 国内精品免费**视频| 琪琪第一精品导航| 国产一级二级三级| 日本一区二区在线看| 亚洲精品福利在线观看| 伊人成人免费视频| 播放一区二区| 欧美日韩一二三四五区| 日韩精品视频在线观看视频| 老司机在线看片网av| 久久久国产午夜精品| 国产私拍一区| 性一交一乱一伧老太| 久久精品二区亚洲w码| 国产精品成人播放| 五月婷婷激情视频| 一本色道久久综合一区| 欧美激情视频在线观看| 国产suv一区二区三区| 日韩精品dvd| 亚洲热线99精品视频| 中文字字幕码一二三区| 玖玖玖免费嫩草在线影院一区| 日韩一区二区在线免费观看| 伊人色在线观看| 国产成人免费精品| 欧美妇女性影城| gai在线观看免费高清| 日韩成人亚洲| 在线观看国产91| 任你操这里只有精品| 美女福利一区二区| 日韩欧美黄色动漫| 黄色国产精品视频| 亚洲综合在线电影| 欧洲激情一区二区| 小明看看成人免费视频| 99久久久国产| 日韩欧美的一区二区| 91精品国产高清91久久久久久 | 亚洲一区二区三区四区精品| 色8久久久久| 欧美一区二区三区影视| 免费人成视频在线播放| 超碰cao国产精品一区二区| 精品国产一二三| 天堂久久久久久| 久久av影视| 综合欧美国产视频二区| 99久久婷婷国产综合| 一区在线观看| 日本一区二区在线播放| 五月婷婷丁香在线| 狠狠色综合日日| 国产精品区二区三区日本| 香港三日本三级少妇66| 国产免费久久精品| 九一免费在线观看| 在线天堂新版最新版在线8| 在线观看视频一区二区| 99日在线视频| 久久大胆人体视频| 一区二区三区亚洲| 国产女片a归国片aa| 亚洲一区二区免费看| 国产精品网址在线| 亚洲成人第一区| 2021中文字幕一区亚洲| 制服诱惑一区| yellow在线观看网址| 欧美视频中文字幕| 久久久久久久久久久久国产精品| 欧美极品在线观看| 欧美成人黄色小视频| 中文字幕视频网站| 久久精品国产成人一区二区三区| 国产一区二区精品免费| 99中文字幕一区| 亚洲mv大片欧洲mv大片精品| 国产又猛又黄的视频| 第一区第二区在线| 日韩网站免费观看高清| 久久久精品免费看| 国产精品一区一区| 五月婷婷一区| 小h片在线观看| 日韩欧美亚洲一区二区| 国产精品免费无码| 亚洲国产精品第一区二区| 国产精品一香蕉国产线看观看| 精品国产乱码久久久久久蜜臀网站| 久久综合色之久久综合| 国产一级大片免费看| 欧美色片在线观看| 日韩成人在线播放| 欧美日韩国产精品综合| 日韩在线一区二区| 九九九九九九精品| 超碰在线97国产| 欧美一区二区三区成人| www.99热| 久久青草久久| 久久综合婷婷综合| 91桃色在线观看| 日韩精品一区二区三区在线 | 一区二区三区欧美亚洲| 一区二区xxx| 伊人久久大香线蕉综合网蜜芽| 欧美激情一级精品国产| 国产乱人乱偷精品视频| 中文字幕av一区二区三区| 黄色免费视频大全| 红杏aⅴ成人免费视频| 欧美激情第三页| 精品人妻一区二区三区四区不卡 | www.欧美亚洲| 久久久久久av无码免费网站下载| 四虎国产精品免费久久5151| 在线日韩欧美视频| 中文字幕+乱码+中文乱码91| 久久久av毛片精品| 国产福利视频在线播放| 蜜桃a∨噜噜一区二区三区| 午夜免费在线观看精品视频| 蜜桃视频久久一区免费观看入口| 一区二区三区不卡在线观看| 被黑人猛躁10次高潮视频| 伊人色**天天综合婷婷| 亚洲在线视频观看| 欧美24videosex性欧美| 欧美变态tickle挠乳网站| 久久久久久免费观看| 丰满白嫩尤物一区二区| 婷婷无套内射影院| 六月丁香久久丫| 欧美一性一乱一交一视频| 秋霞av在线| 欧美亚洲高清一区| 日本 欧美 国产| 国产成人免费xxxxxxxx| 大陆av在线播放| 羞羞答答一区二区| 国产精品欧美激情| 国产区在线看| 亚洲成人免费网站| 国产中文字幕视频| 国产精品免费aⅴ片在线观看| 中文字幕第一页在线视频| 欧美国产三区| 久久婷婷国产综合尤物精品| 456成人影院在线观看| 北条麻妃99精品青青久久| 中文字幕无码乱码人妻日韩精品| 亚洲天堂网中文字| a天堂视频在线观看| 肉丝袜脚交视频一区二区| 在线国产伦理一区| gogo人体一区| 国产精品国产三级国产专播精品人 | 亚洲午夜天堂| 久久精品一偷一偷国产| 视频一区 中文字幕| 欧美综合色免费| 欧美日韩在线视频免费| 久久嫩草精品久久久精品一| 第一区免费在线观看| 亚洲福利专区| 亚洲一区3d动漫同人无遮挡| 91精品久久久久久综合五月天| 456亚洲影院| 久做在线视频免费观看| 日韩精品久久久久| 国产精品欧美综合亚洲| 天涯成人国产亚洲精品一区av| 性少妇xx生活| 99久久精品免费看国产免费软件| the porn av| 99视频在线精品国自产拍免费观看| 午夜精品美女久久久久av福利| 免费观看亚洲天堂| 国产精品久久久久久久久久免费| 人交獸av完整版在线观看| 伊人久久精品视频| 深爱激情五月婷婷| 欧美一区二区三区在| 国产性生活视频| 亚洲第一在线综合网站| www日韩在线| 国产亚洲福利社区一区| 亚洲欧美日韩偷拍| 国产乱码精品一区二区三区av| 激情视频综合网| 亚洲视频综合| xxxxxx在线观看| 日韩一区自拍| 日韩精品久久一区二区三区| 欧美国产不卡| 国产成人精品一区二区三区福利 | 丁香六月激情综合| 久久中文娱乐网| 你懂的在线观看网站| 国产不卡一区视频| 超碰91在线播放| 蜜芽一区二区三区| 久久黄色免费看| 久久一区国产| 97xxxxx| 亚洲一区二区三区高清| 国产美女在线一区| 激情文学一区| 99热久久这里只有精品| 综合天堂av久久久久久久| 一区二区三区在线视频111| 欧美限制电影| 五月婷婷综合色| 日韩综合网站| 一区二区国产日产| 色综合久久网| 最新av在线免费观看| 97偷自拍亚洲综合二区| 亚洲一区二区在线免费观看| 日韩在线欧美| 中文字幕一区二区三区四区五区 | 久久久av一区| www亚洲人| 中文字幕无线精品亚洲乱码一区 | 国产精品6699| 欧美aa视频| 国产精品久久久久久久久男| 怡红院成人在线| 国产精品xxxxx| 国产精品亚洲成在人线| 国产日韩精品在线观看| 亚洲精品66| 99在线观看| 国产一区二区在线视频你懂的| 狠狠色噜噜狠狠色综合久| 麻豆视频一区| 色姑娘综合网| 欧美第十八页| 男人天堂a在线| 在线亚洲成人| 美女喷白浆视频| 国内精品视频一区二区三区八戒| 又黄又色的网站| 久久嫩草精品久久久精品一| 日韩亚洲欧美中文字幕| 亚洲精品成人悠悠色影视| 国产无遮无挡120秒| 欧美性猛交xxxx久久久| 怡红院成永久免费人全部视频| 91精品国模一区二区三区| 蜜臀av中文字幕| 亚洲毛茸茸少妇高潮呻吟| 91九色在线porn| 久久99国产综合精品女同 | 国产一区二区在线免费视频| 日韩av综合| 欧美中日韩一区二区三区| 97精品国产| 黄色动漫网站入口| 久久99精品国产.久久久久久 | 中文字幕精品在线观看| 日韩欧美中文一区二区| 天堂av在线免费观看| 日韩少妇与小伙激情| 久久久男人天堂| 亚洲va久久久噜噜噜| 台湾亚洲精品一区二区tv| 三年中文高清在线观看第6集| 亚洲作爱视频| 天天摸天天舔天天操| 99久久夜色精品国产网站| 国产又黄又粗又猛又爽的| 香蕉乱码成人久久天堂爱免费| 中文字幕 自拍偷拍| 亚洲精品不卡在线| 国产黄色在线网站| 国产98色在线| 懂色av一区二区| 中文字幕一区二区三区四区五区| 久久电影一区| 麻豆短视频在线观看| 国产精品网友自拍| 日韩欧美在线观看免费| 精品国产91亚洲一区二区三区婷婷| 91在线品视觉盛宴免费| 26uuu亚洲国产精品| 日韩精品成人在线观看| 亚洲精品一区二区三区av| 国产精品外国| 污污免费在线观看| 亚洲精品久久久蜜桃| 中文字幕 人妻熟女| 日韩精品中文字幕在线| 美女精品视频| 亚洲影院色无极综合| 97精品一区二区| 奇米影音第四色| 久久久久国产精品麻豆ai换脸| 国产成人啪精品午夜在线观看| 91精品国产色综合久久不卡蜜臀| 91在线看黄| 国产精品中文字幕在线观看| 精品国产中文字幕第一页| 国产毛片视频网站| 国产.欧美.日韩| 欧美国产精品一二三| 欧美一区二区成人| 超鹏97在线| 91在线播放国产| 亚洲成人日韩| 在线视频观看一区二区| 中文字幕色av一区二区三区| 丰满人妻一区二区三区四区| 国产一区二区三区免费视频| 欧美色网一区| 日韩一区免费观看| 日本视频中文字幕一区二区三区| 美女洗澡无遮挡| 91久久久免费一区二区| 国产在线观看免费| 国产成人精品在线| 俺要去色综合狠狠| 中文字幕22页| 亚洲精品自拍动漫在线| 国产高清在线免费| 欧美放荡办公室videos4k| 国产调教精品| www黄色av| 国产欧美一区二区在线观看| 波多野结衣毛片| 日韩中文字幕在线免费观看| 高清久久一区| 国产传媒久久久| av亚洲产国偷v产偷v自拍| av大全在线观看| 亚洲天堂av在线免费| 一区在线影院| 国产91porn| 成人av第一页| 无码人妻av一区二区三区波多野| 在线观看日韩视频| 国产精品99久久免费| 成人免费观看在线| 久久美女高清视频| 亚洲视频一区二区三区四区| 超碰97人人做人人爱少妇| 国产精品99久久免费观看| 少妇性饥渴无码a区免费| 欧美国产禁国产网站cc| 国产成人精品一区二三区四区五区| 欧美精品久久久久久久久| 亚洲区小说区图片区qvod| 色啦啦av综合| 午夜伦欧美伦电影理论片| 精品欧美不卡一区二区在线观看| 成人h视频在线观看播放| 亚洲国产片色| 国产不卡在线观看视频| 亚洲成av人片在线观看香蕉| 成人va天堂| www国产无套内射com| 2020国产精品久久精品美国| 国产一区二区麻豆| 97久久精品国产| 欧美电影《睫毛膏》| 真人bbbbbbbbb毛片| 欧美精品一二三| 日韩精品av| wwwjizzjizzcom| 国产欧美日韩综合精品一区二区| 成 人片 黄 色 大 片| 国产精品69精品一区二区三区| 欧美日韩视频| 日本猛少妇色xxxxx免费网站|