国产无遮挡裸体免费直播视频,久久精品国产蜜臀av,动漫在线视频一区二区,欧亚日韩一区二区三区,久艹在线 免费视频,国产精品美女网站免费,正在播放 97超级视频在线观看,斗破苍穹年番在线观看免费,51最新乱码中文字幕

Go數(shù)據(jù)結(jié)構(gòu)之映射map方式

 更新時(shí)間:2025年06月11日 09:00:13   作者:大P哥阿豪  
這篇文章主要介紹了Go數(shù)據(jù)結(jié)構(gòu)之映射map方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Map作為Go原生支持的另一個(gè)主要的數(shù)據(jù)結(jié)構(gòu),其使用頻繁程度與切片有過之而無不及。用一句話描述map:存儲(chǔ)鍵-值對(duì)映射關(guān)系的無序數(shù)據(jù)結(jié)構(gòu),保證鍵的唯一性但不保證并發(fā)操作安全。

本文將介紹map的基本使用以及go 1.16版本其底層實(shí)現(xiàn)。

1 map的使用

1.1 map基本使用

聲明/初始化,一般有如下三種方式,

  • 使用var聲明一個(gè)map變量,需要指定鍵值對(duì)分別的類型,這種方式僅僅只是聲明,返回的是一個(gè)nil map,既沒有分配內(nèi)存,無法對(duì)其進(jìn)行寫入操作。如果要對(duì)其進(jìn)行寫入操作,則還需要為其分配內(nèi)存。
  • 比較常用的是直接使用make初始化,在初始化map類型時(shí),可以傳一個(gè)容量(通常是不傳這個(gè)參數(shù),因?yàn)閙ap底層有自動(dòng)擴(kuò)容機(jī)制,且無法準(zhǔn)確預(yù)估m(xù)ap所需的容量)。
  • 第三種方式就是直接在定義的同時(shí),對(duì)map進(jìn)行寫入操作,這種方式適用于確定部分需要寫入map的場景
// 聲明一個(gè)map變量,鍵是string類型,值是int類型
// 但此時(shí)m還是一個(gè)nil map,無法對(duì)其進(jìn)行寫入
var m map[string]int 
m["1"] = 1 // 報(bào)錯(cuò),nil map無法寫入

m = make(map[string]int) // 使用make為map分配內(nèi)存,此時(shí)可以正常寫入


// 可以將聲明和分配內(nèi)存合二為一,直接使用make函數(shù)為map分配內(nèi)存
// make函數(shù)第一個(gè)參數(shù)是map的類型,第二個(gè)參數(shù)可選,表示map的容量大小
m1 := make(map[string]int)

// 第三種方式就是在定義的時(shí)候,連帶著給map進(jìn)行賦值
m2 := map[string]int{
    "1": 1,
    "2": 2,
}

賦值,其實(shí)就比較簡單,直接將鍵放入中括號(hào),對(duì)應(yīng)的值放在等號(hào)右邊即可,如果鍵之間存在,則實(shí)現(xiàn)更新;不存在,則實(shí)現(xiàn)插入。這里需要特別注意的是

  • 對(duì)于nil map無法進(jìn)行賦值操作,如果對(duì)nil map進(jìn)行賦值,則會(huì)panic。
  • map中的value是不可尋址的,無法直接通過map值進(jìn)行更新操作,但有兩種例外,1)value為int類型,編譯器會(huì)通過語法糖進(jìn)行直接更新;2)value為指針類型時(shí),也能直接通過map值進(jìn)行更新操作。
m := make(map[string]int)
m["1"] = 1

type Person struct {
	name string
	age  int
}

m1 := map[string]Person{}
m1["Tom"].age++ // 錯(cuò)誤,因?yàn)閙ap的值是無法尋址的,這種情況需要接受舊值,將修改完后的值重新賦值

m2 := map[string]*Person{}
m2["Tom"].age++ // 正確,這種情況下沒有改變map中的value,而是通過指針找到對(duì)應(yīng)存儲(chǔ)的值進(jìn)行修改
  • 查找,map對(duì)于查詢的處理原則就是,如果key不存在,則返回value對(duì)應(yīng)的零值(nil map也能進(jìn)行查找,只是對(duì)于所有的查詢都返回value類型零值)。如果需要判斷key是否存在,則推薦使用v, ok := m["1"]的寫法,ok為true表示key存在于map中。
var m map[string]int
fmt.Println(m["1"]) // nil map可以進(jìn)行查找,返回的是value的默認(rèn)零值

// 如果需要判斷key是否存在于map中,則可以使用如下寫法
if _, ok := m["1"]; ok {
    fmt.Println("key存在")
} else {
    fmt.Println("key不存在")
}
  • 刪除,主要通過調(diào)用delete函數(shù)實(shí)現(xiàn)map中鍵值對(duì)的刪除操作,對(duì)于nil map也能執(zhí)行刪除操作,如果待刪除的key不存在,則不做任何處理。
var m map[string]int
delete(m ,"1")
  • 遍歷,只能通過for range進(jìn)行map的遍歷操作,而且遍歷是無序的,每次遍歷結(jié)果都不一樣,這樣做:一是為了讓使用者不依賴于map的遍歷順序,二也是與map的底層實(shí)現(xiàn)有很大關(guān)系。實(shí)際開發(fā)過程中,如果要確定的遍歷順序,往往需要借助切片保存順序,然后通過遍歷切片去map中取值。
m := map[string]int{
    "1": 1,
    "2": 2,
}

// 無序遍歷,每次遍歷的順序都不一樣
for k, v := range m {
    fmt.Println(k, v)
}

1.2 map注意事項(xiàng)

map是一種引用傳遞類型,其作為函數(shù)參數(shù)進(jìn)行傳遞時(shí),函數(shù)內(nèi)部修改會(huì)直接影響調(diào)用者。

map遍歷是無序的,即每次遍歷的結(jié)果都不一樣,可能是Go的設(shè)計(jì)者不想使用者依賴與map的遍歷順序性,個(gè)人認(rèn)為這個(gè)也是與其底層實(shí)現(xiàn)有關(guān),如果要保證有序,則需要維護(hù)額外的數(shù)據(jù)結(jié)構(gòu),與Go極簡的設(shè)計(jì)原則不符。

map的key必須是支持==、!=運(yùn)算的數(shù)據(jù)類型(map的key可以為float類型、chan類型自定義結(jié)構(gòu)體,但不能是func、map、slice,value則可以為任意數(shù)據(jù)類型)。

因內(nèi)存訪問安全和哈希算法等緣故,字典被設(shè)置成“not addressable”,故不能直接修改value的值(實(shí)際上就是不允許直接修改map中的值)。如果需要對(duì)value進(jìn)行修改,一般將需要將整個(gè)value返回,修改后再重新賦值,或直接將value設(shè)置成指針類型(指針能修改的原因是,通過指針修改原結(jié)構(gòu)體中的數(shù)據(jù),但沒有修改map中保存的數(shù)據(jù))。但是,如果map的value為int,那么可以直接修改value,例如:

m := map[string]int{"test":1}

m["test"]++  // 實(shí)際上是語法糖
/* 
temp := m["test"]
temp += 1
m["test"] = temp
*/

map并不是多線程讀寫安全的,在多線程開發(fā)中使用map需要特別小心,解決此問題一般可以使用sync.RWMutex進(jìn)行保護(hù)或直接使用sync.Map。

訪問不存在的主鍵,返回對(duì)應(yīng)key的零值,并不會(huì)panic。刪除不存在的鍵值,也不會(huì)引發(fā)錯(cuò)誤。

可對(duì)nil的字典進(jìn)行讀、刪除操作,但是寫會(huì)引發(fā)panic!即,從nil的字典中,讀出來的都是value的默認(rèn)值;對(duì)nil字典進(jìn)行刪除操作,實(shí)際不會(huì)產(chǎn)生任何效果。

2 map的底層數(shù)據(jù)結(jié)構(gòu)

在Go 1.16版本中,使用了hash table來實(shí)現(xiàn)map(Go 1.24版本已經(jīng)使用Swiss table作為map的底層實(shí)現(xiàn),后續(xù)有空研究下),其底層實(shí)現(xiàn)主要借助hmap、bmap,下面詳細(xì)介紹下這兩個(gè)數(shù)據(jù)。

2.1 bmap

bmap是Go map中bucket的抽象,為提高存儲(chǔ)效率,每一個(gè) bmap 都能存儲(chǔ) 8 個(gè)鍵值對(duì)。

當(dāng)哈希表中存儲(chǔ)的數(shù)據(jù)過多,單個(gè)桶已經(jīng)裝滿時(shí)就會(huì)使用 extra.nextOverflow 中桶存儲(chǔ)溢出的數(shù)據(jù)。上述兩種不同的桶在內(nèi)存中是連續(xù)存儲(chǔ)的,我們?cè)谶@里將它們分別稱為正常桶和溢出桶。

bucket的結(jié)構(gòu)體 bmap 在 Go 語言源代碼中的定義只包含一個(gè)簡單的 tophash 字段,tophash 存儲(chǔ)了鍵的哈希的高 8 位,通過比較不同鍵的哈希的高 8 位可以減少訪問鍵值對(duì)次數(shù)以提高性能。在運(yùn)行期間,bmap 結(jié)構(gòu)體其實(shí)不止包含 tophash 字段,因?yàn)楣1碇锌赡艽鎯?chǔ)不同類型的鍵值對(duì),而且 Go 語言也不支持泛型,所以鍵值對(duì)占據(jù)的內(nèi)存空間大小只能在編譯時(shí)進(jìn)行推導(dǎo)。runtime.bmap 中的其他字段在運(yùn)行時(shí)也都是通過計(jì)算內(nèi)存地址的方式訪問的,所以它的定義中就不包含這些字段,不過我們能根據(jù)編譯期間的 cmd/compile/internal/gc.bmap 函數(shù)重建它的結(jié)構(gòu):

type bmap struct {
    tophash [bucketCnt]uint8
}

// 利用../go/src/cmd/compile/internal/gc/reflect.go文件中的bmap函數(shù)反推
type bmap struct {
    topbits  [8]uint8
    keys     [8]keytype
    values   [8]valuetype
    overflow uintptr
}

桶和溢出桶

  • 桶(bucket): 每個(gè)桶包含固定數(shù)量的鍵值對(duì),Go 中每個(gè)桶默認(rèn)可以存儲(chǔ) 8 對(duì)鍵值對(duì)。
  • 溢出桶(overflow bucket): 當(dāng)一個(gè)桶已滿但仍需插入新的鍵值對(duì)時(shí),會(huì)創(chuàng)建一個(gè)新的桶作為當(dāng)前桶的溢出桶。

溢出桶的作用

解決哈希沖突:

  • 在理想情況下,每個(gè)鍵會(huì)被分配到不同的桶中。然而,在實(shí)際應(yīng)用中,由于哈希函數(shù)的特性,多個(gè)鍵可能會(huì)被分配到同一個(gè)桶中(即哈希沖突)。
  • 當(dāng)一個(gè)桶已滿且仍然需要存儲(chǔ)新的鍵值對(duì)時(shí),Go 會(huì)創(chuàng)建一個(gè)新的桶作為當(dāng)前桶的溢出桶,并將新鍵值對(duì)存儲(chǔ)在這個(gè)溢出桶中。

管理存儲(chǔ)空間:

  • 溢出桶允許動(dòng)態(tài)擴(kuò)展 map 的存儲(chǔ)容量。通過使用鏈表結(jié)構(gòu)(由多個(gè)溢出桶組成),可以有效地管理超過初始桶容量的數(shù)據(jù)。
  • 這種機(jī)制避免了頻繁地重新分配和復(fù)制整個(gè)哈希表,從而提高了性能。

高效查找:

  • 即使存在多個(gè)溢出桶,Go 的 map 實(shí)現(xiàn)仍然能夠高效地進(jìn)行鍵值對(duì)的查找。通過遍歷主桶及其關(guān)聯(lián)的溢出桶,可以快速找到所需的鍵值對(duì)。
  • 溢出桶的設(shè)計(jì)確保了查找操作在平均情況下仍然是 O(1) 時(shí)間復(fù)雜度。

2.2 hmap

hmap是Go實(shí)現(xiàn)map的底層數(shù)據(jù)結(jié)構(gòu),主要用于管理bucket的擴(kuò)容、元素的查找/刪除等,其具體結(jié)構(gòu)如下:

 type hmap struct {
   count       int        // 元素個(gè)數(shù),調(diào)用 len(map) 時(shí),直接返回此值
   flags       uint8      // 標(biāo)記,對(duì)應(yīng) const 中 '// flags' 下的幾個(gè)狀態(tài)
   B           uint8      // buckets 的對(duì)數(shù) log_2
   noverflow   uint16     // overflow 的 bucket 近似數(shù)
   hash0       uint32     // 計(jì)算 key 的哈希的時(shí)候會(huì)傳入哈希函數(shù)
   buckets     unsafe.Pointer    // 指向 buckets 數(shù)組,大小為 2^B。如果元素個(gè)數(shù)為0,就為 nil
                                 // 擴(kuò)容的時(shí)候,buckets 長度會(huì)是 oldbuckets 的兩倍
   oldbuckets unsafe.Pointer     // 指向擴(kuò)容前的數(shù)組(漸進(jìn)式擴(kuò)容)
   nevacuate  uintptr            // 指示擴(kuò)容進(jìn)度,小于此地址的 buckets 遷移完成
   extra      *mapextra          //保存溢出桶的信息
}


type mapextra struct {
   // 如果 key 和 value 都不包含指針,并且可以被 inline(<=128 字節(jié))
   // 使用 extra 來存儲(chǔ) overflow bucket,這樣可以避免 GC 掃描整個(gè) map
   // 然而 bmap.overflow 也是個(gè)指針。這時(shí)候我們只能把這些 overflow 的指針
   // 都放在 hmap.extra.overflow 和 hmap.extra.oldoverflow 中了
   overflow    *[]*bmap // overflow 包含的是 hmap.buckets 的 overflow 的 bucket
   oldoverflow *[]*bmap // oldoverflow 包含擴(kuò)容時(shí)的 hmap.oldbuckets 的 overflow 的 bucket

   nextOverflow *bmap // 指向空閑的 overflow bucket 的指針
}

3 map實(shí)現(xiàn)源碼

3.1 map的初始化

使用make函數(shù)創(chuàng)建map:

make(map[k]v, hint)

在 hint <= 8(鍵值對(duì)的個(gè)數(shù)) 時(shí),會(huì)調(diào)用 makemap_small 來進(jìn)行初始化,如果 hint > 8,則調(diào)用 makemap。在預(yù)估待插入的元素個(gè)數(shù)小于8或者需要的bucket為0時(shí),Go編譯器會(huì)采用延遲分配策略,只有在真正往map中寫入數(shù)據(jù)時(shí), 才會(huì)分配bucket。

makemap函數(shù)主要流程如下:

  • 內(nèi)存安全檢查:通過計(jì)算預(yù)估內(nèi)存 = 元素?cái)?shù)量(hint) × 單個(gè)桶大小(t.bucket.size),防止內(nèi)存溢出攻擊和無效分配,若檢測失敗,將 hint 重置為 0(后續(xù)按最小分配處理)
  • 初始化 hmap 結(jié)構(gòu)體:若傳入 h 為 nil,新建 hmap 結(jié)構(gòu)(map 的底層表示);隨后h.hash0 = fastrand():生成隨機(jī)哈希種子,用于增加哈希隨機(jī)性,防止哈希碰撞攻擊,相同 key 在不同 map 中產(chǎn)生不同哈希值
  • 計(jì)算桶數(shù)量指數(shù) B:根據(jù)負(fù)載因子確定合適的桶數(shù)量(2^B 個(gè)桶),循環(huán)增加 B 直到滿足:6.5 * 2^B >= hint
  • 分配桶數(shù)組:若 B == 0(hint=0),延后到首次寫入時(shí)分配;其他情況,調(diào)用makeBucketArray 分配主桶數(shù)組(長度為 2^B),如果 B >= 4 額外預(yù)分配溢出桶(減少運(yùn)行時(shí)分配開銷,這里也說明正常桶與溢出桶是內(nèi)存地址連續(xù)的數(shù)組)
  • 溢出桶管理:若存在預(yù)分配溢出桶(nextOverflow != nil),初始化 h.extra 結(jié)構(gòu),記錄可用溢出桶鏈表。最后一個(gè)溢出桶的overflow指針會(huì)指向第一個(gè)正常桶,以此形成一個(gè)環(huán)。
func makemap_small() *hmap {
   h := new(hmap)
   h.hash0 = fastrand()
   return h
}

func makemap(t *maptype, hint int, h *hmap) *hmap {
   // 進(jìn)行內(nèi)存大小的檢查,如果溢出或者內(nèi)存超出最大內(nèi)存空間,將hint(元素個(gè)數(shù))設(shè)置為0
   mem, overflow := math.MulUintptr(uintptr(hint), t.bucket.size)
   if overflow || mem > maxAlloc {
      hint = 0
   }

   // 初始化 Hmap,即如果當(dāng)前Hamp為空,則new hmap
   // 設(shè)置map的哈希計(jì)算種子隨機(jī)數(shù)hash0
   if h == nil {
      h = new(hmap)
   }
   h.hash0 = fastrand()

   // Find the size parameter B which will hold the requested # of elements.
   // For hint < 0 overLoadFactor returns false since hint < bucketCnt.
   // 按照提供的元素個(gè)數(shù),根據(jù)負(fù)載因子計(jì)算合理的 B 值,以確保 6.5 * 2 ^ B >= hint
   B := uint8(0)
   for overLoadFactor(hint, B) {
      B++
   }
   h.B = B

   // allocate initial hash table
   // if B == 0, the buckets field is allocated lazily later (in mapassign)
   // If hint is large zeroing this memory could take a while.
   // 初始化 hash table
   // 如果 B 等于 0,那么 buckets 就會(huì)在賦值( mapassign )的時(shí)候再分配
   // 如果長度比較大,分配內(nèi)存會(huì)花費(fèi)長一點(diǎn)
   if h.B != 0 {
      var nextOverflow *bmap
      h.buckets, nextOverflow = makeBucketArray(t, h.B, nil)
      if nextOverflow != nil {
         h.extra = new(mapextra)
         h.extra.nextOverflow = nextOverflow
      }
   }

   return h
}

func makeBucketArray(t *maptype, b uint8, dirtyalloc unsafe.Pointer) (buckets unsafe.Pointer, nextOverflow *bmap) {
   // uintptr(1) << ( b & (sys.PtrSize*8-1))  2^b
   base := bucketShift(b)
   nbuckets := base

   // 當(dāng)桶的數(shù)量小于2^4 時(shí),由于數(shù)據(jù)較少、使用溢出桶的可能性較低,
   // 這時(shí)就會(huì)省略創(chuàng)建溢出桶的過程以減少額外開銷
   if b >= 4 {
      // 當(dāng)桶的數(shù)量多于2^4時(shí),就會(huì)額外創(chuàng)建 2^(b-4)個(gè)溢出桶
      // 根據(jù)內(nèi)存的分配規(guī)則,計(jì)算出合適的內(nèi)存大小,并確定桶的數(shù)量
      nbuckets += bucketShift(b - 4)
      sz := t.bucket.size * nbuckets
      up := roundupsize(sz)
      if up != sz {
         nbuckets = up / t.bucket.size
      }
   }

   // 如果桶之前沒有分配內(nèi)存,就初始化一個(gè)數(shù)組
   // 反之,直接沿用之前的,并清理掉本次初始化所需要內(nèi)存大小的內(nèi)存,備用
   if dirtyalloc == nil {
      buckets = newarray(t.bucket, int(nbuckets))
   } else {
      // dirtyalloc was previously generated by
      // the above newarray(t.bucket, int(nbuckets))
      // but may not be empty.
      buckets = dirtyalloc
      size := t.bucket.size * nbuckets
      if t.bucket.ptrdata != 0 {
         memclrHasPointers(buckets, size)
      } else {
         memclrNoHeapPointers(buckets, size)
      }
   }

   // 如果創(chuàng)建的桶數(shù)量不等于2^b,說明分配了額外的溢出桶
   if base != nbuckets {
      // 2^b個(gè)桶后面就是溢出桶
      nextOverflow = (*bmap)(add(buckets, base*uintptr(t.bucketsize)))

      // 取nextOverflow 里面的最后一個(gè)元素,并把最后一個(gè)buckets 的末尾偏移的指針指向空閑的bucket (目前就是第一個(gè)buckets了)
      last := (*bmap)(add(buckets, (nbuckets-1)*uintptr(t.bucketsize)))
      last.setoverflow(t, (*bmap)(buckets))
   }
   return buckets, nextOverflow
}

下圖是不同B值時(shí),初始化得到的map,如果B小于4,則編譯器不會(huì)為map分配溢出桶(認(rèn)為map的規(guī)模比較小,需要使用到溢出桶的概率不大);只有在B大于等于4時(shí),才會(huì)為map分配 2^(B-4)個(gè)溢出桶,需要注意的是正常桶與溢出桶在底層是一個(gè)內(nèi)存地址連續(xù)的數(shù)組!

3.2 map的賦值

map的賦值操作核心是:通過hash函數(shù),找到key插入到bmap數(shù)據(jù)的下標(biāo)索引,然后就需要遍歷該下標(biāo)包含的所有bucket,尋找第一個(gè)能插入的位置或者尋找該key是否已經(jīng)存在。hash值在這里的主要作用有兩個(gè):

  • tophash:由于一個(gè)bucket存儲(chǔ)了8個(gè)鍵值對(duì),為了快速比較key,編譯器會(huì)將hash值的前8位(64位操作系統(tǒng))存儲(chǔ)到bucket到tophash數(shù)組。
  • 確定bmap的索引:hash值與map的B值進(jìn)行mask操作,確定該key存儲(chǔ)的下標(biāo)位置。

賦值操作底層mapassign函數(shù)的主要流程:

1. 安全檢查和初始化

  • 空 map 檢查:對(duì) nil map 賦值會(huì) panic
  • 并發(fā)寫檢查:檢測到其他 goroutine 正在寫 map 時(shí)拋出異常(Go map 非并發(fā)安全)
  • 哈希計(jì)算:使用類型特定的哈希函數(shù)計(jì)算鍵的哈希值
  • 標(biāo)記寫操作:設(shè)置 hashWriting 標(biāo)志位(防止并發(fā)寫)
  • 延遲初始化:若桶數(shù)組未分配,分配一個(gè)桶(最小化空 map 開銷)

2. 定位桶和搜索鍵

雙層循環(huán)搜索:外層遍歷對(duì)應(yīng)index下所有的bucket,內(nèi)層循環(huán)處理每個(gè)桶的 8 個(gè)槽。

  • 遍歷時(shí),需要記錄第一個(gè)可以插入的位置。
  • 同時(shí),需要遍歷完全插入位置下,所有的bucket。如果遇到tophash相等,進(jìn)一步判斷key是否一致,key也相等,則更新key的信息并結(jié)束循環(huán)。
  • 遇到 emptyRest(后續(xù)全空)時(shí),提前終止搜索。

3. 鍵不存在時(shí)的處理

  • 擴(kuò)容條件:負(fù)載因子超標(biāo)(count/(2^B) > 6.5);溢出桶過多(noverflow >= 2^min(B, 15))。
  • 擴(kuò)容后重試:桶布局改變需重新定位
  • 分配新溢出桶:當(dāng)所有桶都無空閑槽時(shí),則申請(qǐng)一個(gè)溢出桶

4. 收尾工作

  • 返回值的存儲(chǔ)位置:調(diào)用方通過此指針寫入值
  • 間接值處理:若值類型為指針,返回實(shí)際值地址
/*
 t *maptype:map 的類型信息
 h *hmap:map 的底層結(jié)構(gòu)
 key unsafe.Pointer:要插入或更新的鍵
 返回:指向值存儲(chǔ)位置的指針(寫入值需通過此指針)
*/
func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
   // 對(duì)于nil的map不能進(jìn)行寫操作,直接panic
   if h == nil {
      panic(plainError("assignment to entry in nil map"))
   }
   if raceenabled {
      callerpc := getcallerpc()
      pc := funcPC(mapassign)
      racewritepc(unsafe.Pointer(h), callerpc, pc)
      raceReadObjectPC(t.key, key, callerpc, pc)
   }
   if msanenabled {
      msanread(key, t.key.size)
   }

   // 如果有別的goroutine正在寫此map,即發(fā)生了并發(fā)寫,直接異常退出
   if h.flags&hashWriting != 0 {
      throw("concurrent map writes")
   }
   // 計(jì)算需要寫入的key的hash值
   hash := t.hasher(key, uintptr(h.hash0))

   // 調(diào)用hasher函數(shù)時(shí),可能發(fā)生paninc,因此沒法完成一次寫操作
   // 如果hasher沒有發(fā)生panic,那么將flags設(shè)置成flags += 4
   h.flags ^= hashWriting

   // 如果bucket沒有被分配內(nèi)存,則分配一個(gè)bucket(延遲初始化)
   if h.buckets == nil {
      h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
   }

again:
   //  計(jì)算低 8 位 hash,根據(jù)計(jì)算出的 bucketMask 選擇對(duì)應(yīng)的 bucket 編號(hào)
   bucket := hash & bucketMask(h.B)
   //  如果map正在擴(kuò)容,則完成搬遷工作
   if h.growing() {
      growWork(t, h, bucket)
   }
   // 計(jì)算key對(duì)應(yīng)桶編號(hào)的地址,以及hash值的高8位
   b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
   top := tophash(hash)

   var inserti *uint8            //  需要寫入tophash數(shù)組的下標(biāo)
   var insertk unsafe.Pointer    //  寫入key的對(duì)象指針(地址)
   var elem unsafe.Pointer       //  寫入value的對(duì)象指針(地址),即返回值
bucketloop:
   //  開啟雙層循環(huán),外層遍歷bucket的所有overflow桶,內(nèi)層遍歷每個(gè)bucket的cell
   //  目的:找到空的cell(key不存在),或者top所在的位置(key已存在)
   for {
      for i := uintptr(0); i < bucketCnt; i++ {
         if b.tophash[i] != top { // 當(dāng)前top不一致,繼續(xù)比對(duì)下一個(gè)
            // 找到第一個(gè)空的cell,并保存下表以及地址信息
            if isEmpty(b.tophash[i]) && inserti == nil {
               inserti = &b.tophash[i]
               insertk = add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
               elem = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
            }
            // 此cell為空且后面也都是空cell,那么inserti必定已不為空。
            // 這種情況直接退出bucket cell的遍歷
            if b.tophash[i] == emptyRest {
               break bucketloop
            }
            continue
         }

         // 如果b.tophash[i] == top,計(jì)算key對(duì)應(yīng)的地址
         // k是指針對(duì)象,解引用
         k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
         if t.indirectkey() {
            k = *((*unsafe.Pointer)(k))
         }

         // 如果相同的 hash 位置的 key 和要插入的 key 字面上不相等
         // 如果兩個(gè) key 的首八位后最后八位哈希值一樣,就會(huì)進(jìn)行其值比較,算是一種哈希碰撞吧
         if !t.key.equal(key, k) {
            continue
         }
         // map已經(jīng)有此key存在了,那么直接更新
         if t.needkeyupdate() {
            typedmemmove(t.key, k, key)
         }
         elem = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
         goto done
      }

      //  bucket 的 8 個(gè)槽沒有滿足條件的能插入或者能更新的,去 overflow 里繼續(xù)找
      //  overflow 為 nil,說明到了 overflow 鏈表的末端了,退出外層循環(huán)
      ovf := b.overflow(t)
      if ovf == nil {
         break
      }
      // 賦值為鏈表的下一個(gè)元素,繼續(xù)循環(huán)
      b = ovf
   }

   // 沒有找到 key,分配新的空間
   // 如果觸發(fā)了最大的 load factor,或者已經(jīng)有太多 overflow buckets
   // 并且這個(gè)時(shí)刻沒有在進(jìn)行 growing 的途中,那么就開始 growing
   if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
      hashGrow(t, h)
      goto again // Growing the table invalidates everything, so try again
   }

   if inserti == nil {
      // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
      // 前面在桶里找的時(shí)候,沒有找到能塞這個(gè) tophash 的位置
      // 說明當(dāng)前所有 buckets 都是滿的,分配一個(gè)新的 bucket
      newb := h.newoverflow(t, b)
      inserti = &newb.tophash[0]
      insertk = add(unsafe.Pointer(newb), dataOffset)
      elem = add(insertk, bucketCnt*uintptr(t.keysize))
   }

   // store new key/elem at insert position
   if t.indirectkey() { // 如果鍵的比較大,則直接使用指針存儲(chǔ)
      kmem := newobject(t.key)
      // 二級(jí)指針,insertk看作是指向指針的指針
      *(*unsafe.Pointer)(insertk) = kmem
      insertk = kmem
   }
   if t.indirectelem() {
      vmem := newobject(t.elem)
      *(*unsafe.Pointer)(elem) = vmem
   }
   typedmemmove(t.key, insertk, key)
   *inserti = top
   h.count++

done:
   // 禁止并發(fā)寫
   if h.flags&hashWriting == 0 {
      throw("concurrent map writes")
   }
   // flags對(duì)hashWriting按位置0,'^='表示按右邊hashWriting二進(jìn)制為1的位置,置0
   // 還原寫操作之前的flags
   h.flags &^= hashWriting
   if t.indirectelem() {
      // 如果value是個(gè)大對(duì)象,則bucket中存儲(chǔ)的是對(duì)象地址unsafe.Pointer,取出存放value對(duì)象的地址
      elem = *((*unsafe.Pointer)(elem))
   }
   return elem
}

3.3 map的查找

mapaccess1、mapaccess2、mapaccessk是常用的map查找函數(shù),三個(gè)函數(shù)的主要實(shí)現(xiàn)基本類似,主要區(qū)別在于函數(shù)的返回值不同。

  • mapaccess1只有一個(gè)value的返回值,v := m[k]時(shí)調(diào)用,如果k不存在,返回的是value類型對(duì)應(yīng)的零值
  • mapaccess2返回value,bool,v, ok := m[k]時(shí)調(diào)用,如果k不存在,返回是value類型對(duì)應(yīng)的零值,false
  • mapaccessk返回key,value,如果k不存在,返回nil,nil

下面主要分析下mapaccess2函數(shù)的實(shí)現(xiàn):

安全性檢查

  • 空 map 處理:如果 map 為 nil 或元素?cái)?shù)為 0,直接返回零值和 false
  • 特殊處理:如果鍵類型可能引發(fā) panic(如函數(shù)類型),調(diào)用哈希函數(shù)觸發(fā) panic
  • 讀寫沖突檢測:當(dāng)其他 goroutine 正在寫 map 時(shí)拋出異常(Go map 非并發(fā)安全)

計(jì)算哈希和定位桶

  • bucketMask(h.B):生成用于取模的掩碼(如 B=3 時(shí),mask=0b111)
  • 桶定位公式:桶地址 = buckets起始地址 + (hash & mask) * 桶大小

擴(kuò)容期間的特殊處理:當(dāng) map 正在擴(kuò)容時(shí),數(shù)據(jù)可能存在于新舊桶中(擴(kuò)容有等量擴(kuò)容與雙倍擴(kuò)容兩種,詳細(xì)解釋見3.4節(jié)),如果是雙倍擴(kuò)容,且該下標(biāo)還沒有遷移完成,則在老桶中查找

雙層循環(huán)搜索鍵值對(duì)

  • tophash 比較:先比較哈希高8位,快速過濾不匹配項(xiàng)
  • emptyRest 優(yōu)化:遇到標(biāo)記為 emptyRest 的槽位,表示后續(xù)全部為空,直接跳出循環(huán)

鍵值定位

  • 鍵位置:桶地址 + 數(shù)據(jù)偏移 + 索引 * 鍵大小
  • 值位置:桶地址 + 數(shù)據(jù)偏移 + 8*鍵大小 + 索引 * 值大小
  • 間接存儲(chǔ)處理:若鍵或值為指針類型,需解引用獲取實(shí)際數(shù)據(jù)
  • 未找到處理:返回預(yù)定義的零值地址和 false
/*
    t *maptype:map 的類型信息
    h *hmap:map 的底層結(jié)構(gòu)
    key unsafe.Pointer:要查找的鍵
    返回值:
        unsafe.Pointer:指向值的指針(未找到時(shí)指向零值)
        bool:表示鍵是否存在
*/
func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
   if raceenabled && h != nil {
      callerpc := getcallerpc()
      pc := funcPC(mapaccess2)
      racereadpc(unsafe.Pointer(h), callerpc, pc)
      raceReadObjectPC(t.key, key, callerpc, pc)
   }
   if msanenabled && h != nil {
      msanread(key, t.key.size)
   }

   // 如果map為空,或者元素個(gè)數(shù)為零,直接返回零值
   if h == nil || h.count == 0 {
      if t.hashMightPanic() {
         t.hasher(key, 0)
      }
      return unsafe.Pointer(&zeroVal[0]), false
   }

   // 讀、寫沖突
   if h.flags&hashWriting != 0 {
      throw("concurrent map read and map write")
   }

   // 計(jì)算哈希值,并且加入 hash0 引入隨機(jī)性
   hash := t.hasher(key, uintptr(h.hash0))
   // 如果 B = 3,那么結(jié)果用二進(jìn)制表示就是 111,2^B-1
   m := bucketMask(h.B)
   // b 就是存儲(chǔ)key所在的 bucket 的地址
   b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))

   // h.oldbuckets != nil時(shí),說明 map 發(fā)生了擴(kuò)容。這時(shí)候,新的 buckets 里可能還沒有老的內(nèi)容,
   // 所以一定要在老的里面找,否則有可能發(fā)生“消失”的詭異現(xiàn)象
   if c := h.oldbuckets; c != nil {
      if !h.sameSizeGrow() {
         // 如果不是等量擴(kuò)容,新bucket的數(shù)量是老bucket的兩倍
         m >>= 1
      }
      // 求出 key 在老的 map 中的 bucket 位置
      oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&m)*uintptr(t.bucketsize)))
      // 如果oldb 沒有搬遷到新的 bucket,那就在老的 bucket 中尋找
      if !evacuated(oldb) {
         b = oldb
      }
   }
   // 計(jì)算高 8 位的 hash,相當(dāng)于右移 56 位,只取高8位
   top := tophash(hash)
bucketloop:
   // 兩層循環(huán),第一層遍歷bucket后面所有的溢出桶
   //         第二層遍歷每個(gè)桶內(nèi)部的8個(gè)key位置               
   for ; b != nil; b = b.overflow(t) {
      for i := uintptr(0); i < bucketCnt; i++ {
         // 如果top不匹配
         if b.tophash[i] != top {
            // emptyRest標(biāo)記此cell后面所有的key(包括overflow桶)都為空,此時(shí)直接跳出循環(huán)
            if b.tophash[i] == emptyRest {
               break bucketloop
            }
            continue
         }

         // 通過 bmap的地址+dataOffset+i*keysize 定位key的位置
         dataOffset = unsafe.Offsetof(struct{
            b bmap // bmap理解為[bucketCnt]uint8
            v int64
         }{}.v)
         
         k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
         if t.indirectkey() {  // 如果key是指針,那么解引用
            k = *((*unsafe.Pointer)(k)) // 先將k轉(zhuǎn)化為*unsafe.Pointer類型,然后取出該地址存儲(chǔ)的值
         }
         // 如果key相等,定位value的位置,在map中找到了key-value,然后返回
         if t.key.equal(key, k) {
            e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
            if t.indirectelem() { // 如果value是指針,那么解引用
               e = *((*unsafe.Pointer)(e))
            }
            return e, true
         }
      }
   }
   // 如果遍歷完所有的bucket(包括溢出桶),還沒找到,則返回零值
   return unsafe.Pointer(&zeroVal[0]), false
}

3.4 map的擴(kuò)容

擴(kuò)容是hash table中比較常見的一種操作,主要用于提高查詢效率。Go map的擴(kuò)容觸發(fā)條件如下:

是不是已經(jīng)到了 load factor 的臨界點(diǎn),即元素個(gè)數(shù) >= 桶個(gè)數(shù)*6.5,這時(shí)候說明大部分的桶可能都快滿了,如果插入新元素,有大概率需要掛在 overflow 的桶上。

overflow 的桶是不是太多了,

當(dāng) bucket 總數(shù) < 2 ^ 15 時(shí),overflow 的 bucket 總數(shù) >= bucket 的總數(shù)

當(dāng) bucket 總數(shù) >= 2 ^ 15 時(shí),overflow 的 bucket >= 2 ^ 15

滿足上述兩種情況時(shí),就被認(rèn)為溢出桶太多了。為啥會(huì)導(dǎo)致這種情況呢?是因?yàn)槲覀儗?duì) map 一邊插入,一邊刪除,會(huì)導(dǎo)致其中很多桶出現(xiàn)空洞,這樣使得 bucket 使用率不高,值存儲(chǔ)得比較稀疏。在查找時(shí)效率會(huì)下降。

// 裝載因子超過 6.5
func overLoadFactor(count int64, B uint8) bool {
   return count >= bucketCnt && float32(count) > loadFactorNum*(bucketShift(B)/loadFactorDen)
}

// overflow buckets 太多
func tooManyOverflowBuckets(noverflow uint16, B uint8) bool {
   if B > 15 {
      B = 15
   }
   // The compiler doesn't see here that B < 16; mask B to generate shorter shift code.
   return noverflow >= uint16(1)<<(B&15)
}

針對(duì)上述兩種情況,采用了不同的解決方法:

  • 針對(duì) 1,將 B + 1,進(jìn)而 hmap 的 bucket 數(shù)組擴(kuò)容一倍;
  • 針對(duì) 2,通過移動(dòng) bucket 內(nèi)容,使其傾向于緊密排列從而提高 bucket 利用率(等量擴(kuò)容)。

3.4.1 hashGrow函數(shù)

hashGrow函數(shù)只有在往map中新插入一個(gè)值,且需要觸發(fā)擴(kuò)容時(shí)才會(huì)被調(diào)用。該函數(shù)主要根據(jù)擴(kuò)容條件判斷需要執(zhí)行哪一種擴(kuò)容,然后申請(qǐng)新的bucket內(nèi)存,更新bucket、oldbucket的信息,具體的遷移工作是由growWork 和 evacuate函數(shù)中完成的。Go map的擴(kuò)容也采用的漸進(jìn)式遷移,每一次賦值、刪除操作時(shí),如果map處于擴(kuò)容狀態(tài),則會(huì)保證key對(duì)應(yīng)的索引完全遷移(這樣,后續(xù)的操作只需要在h.bucket中完成即可),同時(shí)將h.nevacuate指示的下標(biāo)索引對(duì)應(yīng)的所有bucket也完成遷移。

func hashGrow(t *maptype, h *hmap) {
   // If we've hit the load factor, get bigger.
   // Otherwise, there are too many overflow buckets, so keep the same number of buckets and "grow" laterally.
   // 如果 load factor 超過了閾值,那么需要對(duì) map 進(jìn)行擴(kuò)容,即 B = B + 1,bucket 總數(shù)會(huì)變?yōu)樵瓉淼亩?
   // 如果還沒到閾值,那么只需要保持相同數(shù)量的 bucket,橫向拍平就行了(等量擴(kuò)容)
   bigger := uint8(1)
   if !overLoadFactor(h.count+1, h.B) {
      bigger = 0
      h.flags |= sameSizeGrow // 如果flags原先的值小于sameSizeGrow,h.flags += sameSizeGrow
   }

   // 將原先的bucket分給oldbuckets,然后申請(qǐng)新的bucket內(nèi)存
   oldbuckets := h.buckets
   newbuckets, nextOverflow := makeBucketArray(t, h.B+bigger, nil)

   // 先把 h.flags 中 iterator 和 oldIterator 對(duì)應(yīng)位清 0,然后如果發(fā)現(xiàn) iterator 位為 1,那就把它轉(zhuǎn)接到 oldIterator 位,使得 oldIterator 標(biāo)志位變成 1。
   // 潛臺(tái)詞就是:buckets 現(xiàn)在掛到了 oldBuckets 名下了,對(duì)應(yīng)的標(biāo)志位也轉(zhuǎn)接過去吧。
   flags := h.flags &^ (iterator | oldIterator)
   if h.flags&iterator != 0 {
      flags |= oldIterator
   }

   // 更新map的信息
   h.B += bigger
   h.flags = flags
   h.oldbuckets = oldbuckets
   h.buckets = newbuckets
   h.nevacuate = 0
   h.noverflow = 0

   // 將原先的overflow搬到oldoverflow
   if h.extra != nil && h.extra.overflow != nil {
      // Promote current overflow buckets to the old generation.
      if h.extra.oldoverflow != nil {
         throw("oldoverflow is not nil")
      }
      h.extra.oldoverflow = h.extra.overflow
      h.extra.overflow = nil
   }
   // 如果新的bucket有overflow bucket,賦值給nextOverflow
   if nextOverflow != nil {
      if h.extra == nil {
         h.extra = new(mapextra)
      }
      h.extra.nextOverflow = nextOverflow
   }

   // the actual copying of the hash table data is done incrementally by growWork() and evacuate().
   // 實(shí)際的哈希表元素的拷貝工作是在 growWork 和 evacuate 中增量慢慢地進(jìn)行的
}

3.4.3 evacuate函數(shù)

evacuate函數(shù)實(shí)現(xiàn)遷移的核心點(diǎn)在于:

  • evacDst 結(jié)構(gòu):跟蹤遷移目標(biāo)位置

等量擴(kuò)容:只使用 x(相同索引位置,平行遷移)

翻倍擴(kuò)容:使用 xy 兩個(gè)目標(biāo),將原來一個(gè)索引下的bucket內(nèi)容分配到新bmap數(shù)組的兩個(gè)相關(guān)索引下:

  • x:新桶數(shù)組低位(索引 = oldbucket
  • y:新桶數(shù)組高位(索引 = oldbucket + newbit

在翻倍擴(kuò)容的時(shí)候,雖然鍵的哈希值沒有變化,但通過精妙的遷移策略和新索引計(jì)算機(jī)制,仍然能確保鍵的正確查找!翻倍擴(kuò)容時(shí),新掩碼(newbit) = 1 << B(B 是舊桶數(shù)量的指數(shù)),遷移到新桶數(shù)組到高位或地位,決定于hash & newbit。然后在查找時(shí),使用新掩碼計(jì)算索引,在不改變hash函數(shù)的情況完美解決查找問題。(新舊mask的區(qū)別就是:新mask比舊值多了 B+1 bit位的判斷,后 B bit位還是保持一致,所以可以利用hash的第 B+1位值來確定key遷移到低位還是高位)

新索引 = {
舊索引 (當(dāng) hash & newbit == 0 時(shí))
舊索引 + newbit (當(dāng) hash & newbit != 0 時(shí))
} ======> 新索引 = hash & (newMask),新mask的第 B+1 bit位的值 == 2^B
newMask = (1 << (B+1)) - 1 = (1 << B) * 2 - 1 = newbit*2 - 1

假設(shè):

  • 舊 B=2 (4個(gè)桶,掩碼 0b11)
  • 新 B=3 (8個(gè)桶,掩碼 0b111)
  • newbit = 1<<2 = 4 (0b100)
  • 鍵哈希值:h = 13 (二進(jìn)制 0b1101)
階段計(jì)算過程結(jié)果
舊索引h & 0b11 = 0b1101 & 0b00111 (0b01)
遷移決策h & newbit = 0b1101 & 0b01004 (非0) → 遷移到高位
新索引h & 0b111 = 0b1101 & 0b01115 (0b101)
驗(yàn)證舊索引(1) + newbit(4)5

// evacDst is an evacuation destination.
type evacDst struct {
   b *bmap          // current destination bucket
   i int            // key/elem index into b
   k unsafe.Pointer // pointer to current key storage
   e unsafe.Pointer // pointer to current elem storage
}

// 該函數(shù)用于實(shí)現(xiàn)hmap擴(kuò)容時(shí),數(shù)據(jù)的搬遷工作
// 如果是等量擴(kuò)容,那么就初始化一個(gè)evacDst
// 如果是翻倍擴(kuò)容,那么就初始化兩個(gè)evacDst
func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
   // 定位舊bucket的地址以及擴(kuò)容前map的容量
   b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
   newbit := h.noldbuckets()
   // 如果 b 沒有被搬遷過
   if !evacuated(b) {
      // xy contains the x and y (low and high) evacuation destinations.
      // xy 包含的是移動(dòng)的目標(biāo)
      // x 表示新 bucket 數(shù)組的前(low)半部分,y 表示新 bucket 數(shù)組的后(high)半部分
      var xy [2]evacDst
      x := &xy[0]
      x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
      x.k = add(unsafe.Pointer(x.b), dataOffset)
      x.e = add(x.k, bucketCnt*uintptr(t.keysize))

      if !h.sameSizeGrow() {
         // Only calculate y pointers if we're growing bigger.
         // Otherwise GC can see bad pointers.
         // 如果不是等 size 擴(kuò)容,前后 bucket 序號(hào)有變,使用 y 來進(jìn)行搬遷
         // 擴(kuò)容后的map bucket數(shù)量是原先的兩倍,x,y分別各占一半,數(shù)量與擴(kuò)容前一樣
         // y部分桶的編號(hào): oldbucket+newbit
         y := &xy[1]
         y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
         y.k = add(unsafe.Pointer(y.b), dataOffset)
         y.e = add(y.k, bucketCnt*uintptr(t.keysize))
      }

      // 遍歷所有的 bucket,包括 overflow buckets,b 是老的 bucket 地址
      for ; b != nil; b = b.overflow(t) {
         // 從oldbucket的第一個(gè)cell開始
         k := add(unsafe.Pointer(b), dataOffset)
         e := add(k, bucketCnt*uintptr(t.keysize))
         // 遍歷 bucket 中的所有 cell
         for i := 0; i < bucketCnt; i, k, e = i+1, add(k, uintptr(t.keysize)), add(e, uintptr(t.elemsize)) {
            // 當(dāng)前 cell 的 top hash 值
            top := b.tophash[i]
            // 如果 cell 為空,即沒有 key
            if isEmpty(top) {
               // 那就標(biāo)志它被"搬遷"過,繼續(xù)下一個(gè)cell
               b.tophash[i] = evacuatedEmpty
               continue
            }

            // 正常不會(huì)出現(xiàn)這種情況
            // 未被搬遷的 cell 只可能是 empty 或是正常的 top hash(大于 minTopHash)
            if top < minTopHash {
               throw("bad map state")
            }
            k2 := k
            if t.indirectkey() {
               k2 = *((*unsafe.Pointer)(k2))
            }

            var useY uint8
            if !h.sameSizeGrow() {
               // Compute hash to make our evacuation decision (whether we need
               // to send this key/elem to bucket x or bucket y).
               // 計(jì)算哈希,以判斷我們的數(shù)據(jù)要轉(zhuǎn)移到哪一部分的 bucket,
               // 可能是 x 部分,也可能是 y 部分
               hash := t.hasher(k2, uintptr(h.hash0))
               if h.flags&iterator != 0 && !t.reflexivekey() && !t.key.equal(k2, k2) {
                  // If key != key (NaNs), then the hash could be (and probably
                  // will be) entirely different from the old hash. Moreover,
                  // it isn't reproducible. Reproducibility is required in the
                  // presence of iterators, as our evacuation decision must
                  // match whatever decision the iterator made.
                  // Fortunately, we have the freedom to send these keys either
                  // way. Also, tophash is meaningless for these kinds of keys.
                  // We let the low bit of tophash drive the evacuation decision.
                  // We recompute a new random tophash for the next level so
                  // these keys will get evenly distributed across all buckets
                  // after multiple grows.
                  useY = top & 1
                  top = tophash(hash)
               } else {
                  // 根據(jù)hash & newbit 來確定新bucket的索引,確保遷移完成之后,
                  // 使用原先的hash值 & 新的mask 還能找到正確的索引
                  if hash&newbit != 0 {
                     useY = 1
                  }
               }
            }

            if evacuatedX+1 != evacuatedY || evacuatedX^1 != evacuatedY {
               throw("bad evacuatedN")
            }

            // 在oldbucket對(duì)應(yīng)的cell中標(biāo)記top的搬遷狀態(tài)
            b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY
            dst := &xy[useY]                 // evacuation destination

            // 當(dāng)前bucket中已經(jīng)放滿了元素,需要使用overflow bucket
            if dst.i == bucketCnt {
               dst.b = h.newoverflow(t, dst.b)
               dst.i = 0
               dst.k = add(unsafe.Pointer(dst.b), dataOffset)
               dst.e = add(dst.k, bucketCnt*uintptr(t.keysize))
            }
            dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
            if t.indirectkey() {
               *(*unsafe.Pointer)(dst.k) = k2 // copy pointer
            } else {
               typedmemmove(t.key, dst.k, k) // copy elem
            }
            if t.indirectelem() {
               *(*unsafe.Pointer)(dst.e) = *(*unsafe.Pointer)(e)
            } else {
               typedmemmove(t.elem, dst.e, e)
            }
            dst.i++
            // These updates might push these pointers past the end of the
            // key or elem arrays.  That's ok, as we have the overflow pointer
            // at the end of the bucket to protect against pointing past the
            // end of the bucket.
            dst.k = add(dst.k, uintptr(t.keysize))
            dst.e = add(dst.e, uintptr(t.elemsize))
         }
      }
      // Unlink the overflow buckets & clear key/elem to help GC.
      // 如果沒有協(xié)程在使用老的 buckets,就把老 buckets 清除掉,幫助gc
      if h.flags&oldIterator == 0 && t.bucket.ptrdata != 0 {
         b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
         // Preserve b.tophash because the evacuation state is maintained there.
         // 只清除bucket 的 key,value 部分,保留 top hash 部分,指示搬遷狀態(tài)
         ptr := add(b, dataOffset)
         n := uintptr(t.bucketsize) - dataOffset
         memclrHasPointers(ptr, n)
      }
   }

   // 更新搬遷進(jìn)度,如果此次搬遷的 bucket 等于當(dāng)前進(jìn)度
   if oldbucket == h.nevacuate {
      advanceEvacuationMark(h, t, newbit)
   }
}

3.5 map的刪除

map的刪除主要流程就是需要在key所在的索引bmap鏈表中查找到對(duì)應(yīng)的值,進(jìn)行內(nèi)容的刪除釋放。這里需要特別注意的是,為了提升查找效率,有一個(gè)emptyRest前向傳播機(jī)制:如果被刪除的key后續(xù)位置都是emptyRest,則需要將其前面標(biāo)記為emptyOne的cell升級(jí)為emptyRest,表示從這個(gè)cell往后不再有數(shù)據(jù)。

func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {

   if raceenabled && h != nil  {
      callerpc := getcallerpc()
      pc := funcPC(mapdelete)
      racewritepc(unsafe.Pointer(h), callerpc, pc)
      raceReadObjectPC(t.key, key, callerpc, pc)
   }
   if msanenabled && h != nil{
      msanread(key, t.key.size)
   }

   // 如果map為空,或者元素個(gè)數(shù)為零,直接返回
   if h == nil || h.count == 0 {
      if t.hashMightPanic() {
         t.hasher(key, 0)
      }
      return
   }

   // 有g(shù)oroutine在寫map時(shí),無法完成刪除操作
   if h.flags&hashWriting != 0 {
      throw("concurrent map writes")
   }
   // 計(jì)算需要寫入的key的hash值
   hash := t.hasher(key, uintptr(h.hash0))

   // 調(diào)用hasher函數(shù)時(shí),可能發(fā)生paninc,因此沒法完成一次寫操作
   // 如果hasher沒有發(fā)生panic,那么將flags設(shè)置成flags += 4
   h.flags ^= hashWriting

   //  計(jì)算低 8 位 hash,根據(jù)計(jì)算出的 bucketMask 選擇對(duì)應(yīng)的 bucket 編號(hào)
   bucket := hash & bucketMask(h.B)
   //  如果map正在擴(kuò)容,則完成搬遷工作
   if h.growing() {
      growWork(t, h, bucket)
   }
   // 計(jì)算key對(duì)應(yīng)桶編號(hào)的地址,以及hash值的高8位
   b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
   bOrig := b
   top := tophash(hash)
search:
   // 兩層循環(huán),第一層遍歷bucket后面所有的溢出桶
   //         第二層遍歷每個(gè)桶內(nèi)部的8個(gè)key位置               
   for ; b != nil; b = b.overflow(t) {
      for i := uintptr(0); i < bucketCnt; i++ {
         // 如果top不匹配
         if b.tophash[i] != top {
            // emptyRest標(biāo)記此cell后面所有的key(包括overflow桶)都為空,此時(shí)直接跳出循環(huán)
            if b.tophash[i] == emptyRest {
               break search
            }
            continue
         }

         // 如果b.tophash[i] == top,計(jì)算key對(duì)應(yīng)的地址
         // k是指針對(duì)象,解引用
         k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
         // 為了保存key的原始類型,便于后續(xù)的清理
         k2 := k
         if t.indirectkey() {
            k2 = *((*unsafe.Pointer)(k2))
         }

         // 如果相同的 hash 位置的 key 和要插入的 key 字面上不相等
         // 如果兩個(gè) key 的首八位后最后八位哈希值一樣,就會(huì)進(jìn)行其值比較,算是一種哈希碰撞
         if !t.key.equal(key, k2) {
            continue
         }

         // Only clear key if there are pointers in it.
         if t.indirectkey() {
            *(*unsafe.Pointer)(k) = nil
         } else if t.key.ptrdata != 0 {
            memclrHasPointers(k, t.key.size)
         }
         e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
         if t.indirectelem() {
            *(*unsafe.Pointer)(e) = nil
         } else if t.elem.ptrdata  != 0 {
            memclrHasPointers(e, t.elem.size)
         } else {
            memclrNoHeapPointers(e, t.elem.size)
         }

         // 標(biāo)記tophash的狀態(tài)
         b.tophash[i] = emptyOne
         // If the bucket now ends in a bunch of emptyOne states, change those to emptyRest states.
         // It would be nice to make this a separate function, but for loops are not currently inlineable.
         if i == bucketCnt-1 { // 刪除的key位于bucket的尾巴
            // 如果后續(xù)還有overflow桶,且桶內(nèi)部還有元素,那么直接跳到notLast
            // 將此tophash標(biāo)記為emptyOne即可
            if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
               goto notLast
            }
         } else {
            // 如果key不是最后一個(gè),且后續(xù)cell還有元素,也直接跳到notLast
            if b.tophash[i+1] != emptyRest {
               goto notLast
            }
         }
         for {
            // 刪除的key后面不再有元素,需要將tophash標(biāo)記為emptyRest
            // 同時(shí)往前尋找,并將前面tophash為emptyOne的位置標(biāo)記為emptyRest
            b.tophash[i] = emptyRest
            if i == 0 {
               if b == bOrig {
                  break // beginning of initial bucket, we're done.
               }
               // Find previous bucket, continue at its last entry.
               c := b
               // 從key的bucket開始,查找當(dāng)前bucket的前一個(gè)桶地址
               for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
               }
               // bucket內(nèi)部從最后一個(gè)cell開始查找tophash為emptyOne的cell
               i = bucketCnt - 1
            } else {
               i--
            }
            // 查找到一個(gè)有內(nèi)容的tophash,結(jié)束循環(huán)
            if b.tophash[i] != emptyOne {
               break
            }
         }
      notLast:
         h.count--
         // Reset the hash seed to make it more difficult for attackers to
         // repeatedly trigger hash collisions. See issue 25237.
         if h.count == 0 {
            h.hash0 = fastrand()
         }
         break search
      }
   }

   // 禁止并發(fā)寫
   if h.flags&hashWriting == 0 {
      throw("concurrent map writes")
   }
   // flags對(duì)hashWriting按位置0,
   // '^='表示按右邊hashWriting二進(jìn)制為1的位置,置0,其他位置與flags保持一致
   // 還原寫操作之前的flags
   h.flags &^= hashWriting
}

3.6 map的遍歷

3.6.1 hiter結(jié)構(gòu)體

在對(duì)map進(jìn)行遍歷時(shí),會(huì)借助迭代器hiter輔助完成整個(gè)map的循環(huán)遍歷,其中startBucket標(biāo)記此次遍歷的起始位置,wrapped標(biāo)記遍歷是否從頭開始,checkBucket則是用于擴(kuò)容中進(jìn)行遍歷時(shí),堅(jiān)持oldBucket中的數(shù)據(jù)。

type hiter struct {
        // key 指針,保存此次遍歷得到的key
        key         unsafe.Pointer
        // value 指針,保存此次遍歷得到的value
        value       unsafe.Pointer
        // map 類型,包含如 key size 大小等
        t           *maptype
        // map header
        h           *hmap
        // 初始化時(shí)指向的 bucket
        buckets     unsafe.Pointer
        // 當(dāng)前遍歷到的 bmap
        bptr        *bmap
        overflow    [2]*[]*bmap
        // 起始遍歷的 bucet 編號(hào)
        startBucket uintptr
        // 遍歷開始時(shí) cell 的編號(hào)(每個(gè) bucket 中有 8 個(gè) cell)
        offset      uint8
        // 是否從頭遍歷了
        wrapped     bool
        // B 的大小
        B           uint8
        // 指示當(dāng)前 cell 序號(hào)
        i           uint8
        // 指向當(dāng)前的 bucket
        bucket      uintptr
        // 因?yàn)閿U(kuò)容,需要檢查的 bucket
        checkBucket uintptr
}

3.6.2 mapiternext函數(shù)

對(duì)map進(jìn)行遍歷時(shí),首先會(huì)調(diào)用mapiterinit函數(shù),初始化hiter,該函數(shù)邏輯比較簡單,主要就是隨機(jī)確定遍歷起始位置,這里的起始位置包括:bmap的數(shù)組的起始下標(biāo)、bmap bucket內(nèi)部cell的起始點(diǎn)。隨后調(diào)用mapiternext函數(shù)開始執(zhí)行具體的遍歷操作(每調(diào)用一次mapiternext函數(shù)獲取一個(gè)map中的鍵值對(duì)),該過程的主要流程如下:

1. 首先檢查是否有并發(fā)寫操作,如果有則拋出異常。

2. 獲取迭代器當(dāng)前的狀態(tài)(當(dāng)前遍歷的bucket,當(dāng)前bucket內(nèi)的位置i,當(dāng)前bucket指針b等)。

3. 如果當(dāng)前bucket(b)為nil,說明需要處理下一個(gè)bucket或者已經(jīng)遍歷完一圈。

  • 如果當(dāng)前bucket序號(hào)(bucket)等于起始bucket(it.startBucket)且已經(jīng)標(biāo)記為繞回(wrapped),說明已經(jīng)遍歷完所有bucket,設(shè)置key和elem為nil并返回。
  • 如果map正在擴(kuò)容且迭代器開始時(shí)的B(it.B)等于當(dāng)前map的B(h.B),說明迭代開始后擴(kuò)容未完成,需要處理舊桶:
  • 計(jì)算對(duì)應(yīng)的舊桶(oldbucket)地址。
  • 如果該舊桶尚未遷移(evacuated),則設(shè)置checkBucket為當(dāng)前bucket(用于后續(xù)判斷鍵是否屬于當(dāng)前新桶),并繼續(xù)遍歷舊桶。
  • 如果已經(jīng)遷移,則直接遍歷新桶中對(duì)應(yīng)位置的桶,并將checkBucket設(shè)置為noCheck。
  • 否則,直接遍歷新桶中當(dāng)前bucket位置的桶。
  • 然后bucket序號(hào)加1,如果達(dá)到bucket總數(shù)(2^B),則重置為0并標(biāo)記wrapped為true(表示已經(jīng)繞回一圈)。
  • 重置i為0,開始遍歷新桶。

4. 遍歷當(dāng)前bucket(b)的8個(gè)cell(槽位),注意這里不是從0開始,而是根據(jù)it.offset進(jìn)行偏移(使用offi = (i+it.offset) & (bucketCnt-1))以實(shí)現(xiàn)隨機(jī)開始。

  • 如果tophash[offi]為空(emptyOne或evacuatedEmpty)則跳過。
  • 獲取鍵k和值e的地址。
  • 如果checkBucket不為noCheck(說明在擴(kuò)容過程中且當(dāng)前遍歷的是舊桶),則需要判斷該鍵是否屬于當(dāng)前迭代的新桶(checkBucket):
  • 對(duì)于正常鍵(非NaN),計(jì)算其哈希值并判斷它是否屬于checkBucket,如果不屬于則跳過。
  • 對(duì)于NaN(k!=k),使用tophash的低位來決定它應(yīng)該去哪個(gè)桶,如果與checkBucket的高位不匹配則跳過。
  • 如果鍵值有效,則判斷該槽位是否已經(jīng)被遷移(evacuatedX或evacuatedY)且鍵是正常的(可比較且相等):
  • 如果未被遷移,或者鍵是NaN(不可比較),則直接使用當(dāng)前找到的鍵值對(duì)(因?yàn)榇藭r(shí)數(shù)據(jù)還未遷移或無法比較,所以認(rèn)為有效)。
  • 否則,說明在迭代過程中map已經(jīng)擴(kuò)容完成,該鍵可能已經(jīng)被遷移,需要從新map中查找(調(diào)用mapaccessK):如果返回的鍵為nil,說明該鍵已被刪除,跳過;否則使用返回的鍵值對(duì)。

5. 設(shè)置迭代器的狀態(tài)(key, elem, bucket, bptr, i, checkBucket)并返回。

6. 如果當(dāng)前bucket的8個(gè)cell都遍歷完了,則跳到overflow bucket(如果有),重置i為0,然后跳轉(zhuǎn)到next標(biāo)簽繼續(xù)處理。

func mapiternext(it *hiter) {
   h := it.h
   if raceenabled {
      callerpc := getcallerpc()
      racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapiternext))
   }

   // 如果有g(shù)oroutine正在寫,拋出異常
   if h.flags&hashWriting != 0 {
      throw("concurrent map iteration and writes")
   }

   t := it.t
   bucket := it.bucket
   b := it.bptr
   i := it.i
   checkBucket := it.checkBucket

next:
   // 后續(xù)沒有overflow bucket需要遍歷
   if b == nil {
      // 當(dāng)前遍歷的bucket=startBucket,即完成循環(huán)回到最初的位置
      // 且該bucket已經(jīng)從頭到尾遍歷完了,map的遍歷結(jié)束
      if bucket == it.startBucket && it.wrapped {
         // end of iteration
         it.key = nil
         it.elem = nil
         return
      }

      // 如果map正處于擴(kuò)容狀態(tài),還需要遍歷oldbucket
      if h.growing() && it.B == h.B {
         // Iterator was started in the middle of a grow, and the grow isn't done yet.
         // If the bucket we're looking at hasn't been filled in yet (i.e. the old
         // bucket hasn't been evacuated) then we need to iterate through the old
         // bucket and only return the ones that will be migrated to this bucket.
         oldbucket := bucket & it.h.oldbucketmask()
         // 根據(jù)bucket num在oldbucket的編號(hào)位置,計(jì)算bucket的地址
         b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
         if !evacuated(b) {
            // 如果oldbucket中此編號(hào)的bucket沒有完成搬遷,那么標(biāo)記check
            checkBucket = bucket
         } else {
            // 如果oldbucket中此編號(hào)的bucket完成了搬遷,直接遍歷newbucket中對(duì)應(yīng)位置的bucket
            b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
            checkBucket = noCheck
         }
      } else {
         b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
         checkBucket = noCheck
      }
      // 指向下一個(gè)bucket
      bucket++
      // 判斷是否已經(jīng)遍歷到了末尾,如果是,則需要從頭重新開始遍歷,
      // 直至bucket == startbucket,標(biāo)記一次完整的遍歷
      if bucket == bucketShift(it.B) {
         bucket = 0
         it.wrapped = true
      }
      i = 0
   }

   // 遍歷bucket的8個(gè)cell,但不是從頭開始遍歷的
   for ; i < bucketCnt; i++ {
      offi := (i + it.offset) & (bucketCnt - 1)
      // 如果tophash為空,即沒有數(shù)據(jù),直接檢查下一個(gè)
      if isEmpty(b.tophash[offi]) || b.tophash[offi] == evacuatedEmpty {
         // TODO: emptyRest is hard to use here, as we start iterating
         // in the middle of a bucket. It's feasible, just tricky.
         continue
      }
      k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
      if t.indirectkey() {
         k = *((*unsafe.Pointer)(k))
      }

      e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.elemsize))
      if checkBucket != noCheck && !h.sameSizeGrow() {
         // Special case: iterator was started during a grow to a larger size
         // and the grow is not done yet. We're working on a bucket whose
         // oldbucket has not been evacuated yet. Or at least, it wasn't
         // evacuated when we started the bucket. So we're iterating
         // through the oldbucket, skipping any keys that will go
         // to the other new bucket (each oldbucket expands to two buckets during a grow).
         if t.reflexivekey() || t.key.equal(k, k) {
            // If the item in the oldbucket is not destined for the current new bucket in the iteration, skip it.
            hash := t.hasher(k, uintptr(h.hash0))
            if hash&bucketMask(it.B) != checkBucket {
               continue
            }
         } else {
            // Hash isn't repeatable if k != k (NaNs).  We need a
            // repeatable and randomish choice of which direction
            // to send NaNs during evacuation. We'll use the low
            // bit of tophash to decide which way NaNs go.
            // NOTE: this case is why we need two evacuate tophash
            // values, evacuatedX and evacuatedY, that differ in their low bit.
            if checkBucket>>(it.B-1) != uintptr(b.tophash[offi]&1) {
               continue
            }
         }
      }
      if (b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY) ||
         !(t.reflexivekey() || t.key.equal(k, k)) {
         // This is the golden data, we can return it.
         // OR
         // key!=key, so the entry can't be deleted or updated, so we can just return it.
         // That's lucky for us because when key!=key we can't look it up successfully.
         it.key = k
         if t.indirectelem() {
            e = *((*unsafe.Pointer)(e))
         }
         it.elem = e
      } else {
         // The hash table has grown since the iterator was started.
         // The golden data for this key is now somewhere else.
         // Check the current hash table for the data.
         // This code handles the case where the key has been deleted, updated, or deleted and reinserted.
         // NOTE: we need to regrab the key as it has potentially been
         // updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
         rk, re := mapaccessK(t, h, k)
         if rk == nil {
            continue // key has been deleted
         }
         it.key = rk
         it.elem = re
      }
      it.bucket = bucket
      if it.bptr != b { // avoid unnecessary write barrier; see issue 14921
         it.bptr = b
      }
      it.i = i + 1
      it.checkBucket = checkBucket
      return
   }

   // 通過it.i走到此處,遍歷overflow bucket
   b = b.overflow(t)
   i = 0
   goto next
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Golang限流器time/rate設(shè)計(jì)與實(shí)現(xiàn)詳解

    Golang限流器time/rate設(shè)計(jì)與實(shí)現(xiàn)詳解

    在?Golang?庫中官方給我們提供了限流器的實(shí)現(xiàn)golang.org/x/time/rate,它是基于令牌桶算法(Token?Bucket)設(shè)計(jì)實(shí)現(xiàn)的,下面我們就來看看他的具體使用吧
    2024-03-03
  • Golang?中判斷兩個(gè)結(jié)構(gòu)體相等的方法

    Golang?中判斷兩個(gè)結(jié)構(gòu)體相等的方法

    這篇文章主要介紹了Golang?中如何判斷兩個(gè)結(jié)構(gòu)體相等,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Go語言并發(fā)編程基礎(chǔ)上下文概念詳解

    Go語言并發(fā)編程基礎(chǔ)上下文概念詳解

    這篇文章主要為大家介紹了Go語言并發(fā)編程基礎(chǔ)上下文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • golang對(duì)自定義類型進(jìn)行排序的解決方法

    golang對(duì)自定義類型進(jìn)行排序的解決方法

    學(xué)習(xí)一門編程語言,要掌握原子數(shù)據(jù)類型,還需要掌握自定義數(shù)據(jù)類型。下面這篇文章主要給大家介紹了關(guān)于golang如何對(duì)自定義類型進(jìn)行排序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-12-12
  • Golang中日志使用詳解

    Golang中日志使用詳解

    這篇文章記錄了Golang項(xiàng)目中日志使用,以及結(jié)合Gin框架記錄請(qǐng)求日志,文中通過代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • etcd通信接口之客戶端API核心方法實(shí)戰(zhàn)

    etcd通信接口之客戶端API核心方法實(shí)戰(zhàn)

    這篇文章主要為大家介紹了etcd通信接口之客戶端API核心方法實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 使用Go語言實(shí)現(xiàn)在項(xiàng)目中隱藏敏感信息

    使用Go語言實(shí)現(xiàn)在項(xiàng)目中隱藏敏感信息

    在開發(fā)項(xiàng)目是,用戶信息管理是一個(gè)非常常見的場景,特別是當(dāng)我們需要存儲(chǔ)和處理敏感信息時(shí),本文主要介紹了如何使用Go語言實(shí)現(xiàn)隱藏敏感信息,需要的可以參考下
    2024-11-11
  • 使用golang編寫一個(gè)并發(fā)工作隊(duì)列

    使用golang編寫一個(gè)并發(fā)工作隊(duì)列

    這篇文章主要介紹了使用golang編寫一個(gè)并發(fā)工作隊(duì)列的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 用Go寫一個(gè)輕量級(jí)的ssh批量操作工具的方法

    用Go寫一個(gè)輕量級(jí)的ssh批量操作工具的方法

    這篇文章主要介紹了用Go寫一個(gè)輕量級(jí)的ssh批量操作工具的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • Go routine使用方法講解

    Go routine使用方法講解

    goroutine是Go語言提供的語言級(jí)別的輕量級(jí)線程,在我們需要使用并發(fā)時(shí),我們只需要通過go關(guān)鍵字來開啟goroutine即可。這篇文章主要介紹了GoLang并發(fā)機(jī)制goroutine原理,感興趣的可以了解一下
    2023-01-01

最新評(píng)論

色秀欧美视频第一页| 日本xx片在线观看| 色婷婷久久久久swag精品| 人妻久久久精品69系列| 最新国产精品拍在线观看| 午夜久久香蕉电影网| 99国内精品永久免费视频| 大香蕉玖玖一区2区| 青青青青青青青青青青草青青| rct470中文字幕在线| 国产精品久久久黄网站| 99re久久这里都是精品视频| 18禁免费av网站| 亚洲精品ww久久久久久| 抽查舔水白紧大视频| 又色又爽又黄又刺激av网站 | 国产女人露脸高潮对白视频| 大香蕉日本伊人中文在线| 国产av福利网址大全| 免费观看成年人视频在线观看 | 欧美日韩情色在线观看| 黄色黄色黄片78在线| 国产91久久精品一区二区字幕 | 2018最新中文字幕在线观看| 国产精品女邻居小骚货| 班长撕开乳罩揉我胸好爽| 日本乱人一区二区三区| 年轻的人妻被夫上司侵犯| 亚洲成人精品女人久久久| 亚洲男人在线天堂网| 任你操任你干精品在线视频| 99精品亚洲av无码国产另类| 66久久久久久久久久久| 欧洲欧美日韩国产在线| 天天操天天操天天碰| 五色婷婷综合狠狠爱| 日本乱人一区二区三区| av中文字幕福利网| 亚洲综合一区二区精品久久| 夜色17s精品人妻熟女| www日韩毛片av| 亚洲精品ww久久久久久| 国产janese在线播放| 国内自拍第一页在线观看| 国产欧美日韩在线观看不卡| 老有所依在线观看完整版| 极品性荡少妇一区二区色欲| 欧美视频综合第一页| 国产自拍黄片在线观看| 激情色图一区二区三区| 99精品视频之69精品视频 | 国产精彩福利精品视频| 日辽宁老肥女在线观看视频| 日韩精品中文字幕播放| 99热这里只有精品中文| 亚洲图片偷拍自拍区| 欧美一区二区三区高清不卡tv| 国产亚洲精品品视频在线| 久久永久免费精品人妻专区 | 91精品啪在线免费| 亚洲伊人av天堂有码在线| 欧美一区二区三区久久久aaa| 亚洲av可乐操首页| 欧美亚洲自偷自拍 在线| 97人妻人人澡爽人人精品| 日韩人妻xxxxx| 91福利在线视频免费观看| 青青草原色片网站在线观看| 欧美在线精品一区二区三区视频| av完全免费在线观看av| 一区国内二区日韩三区欧美| 蜜桃精品久久久一区二区| 大香蕉福利在线观看| huangse网站在线观看| 久久久久国产成人精品亚洲午夜| huangse网站在线观看| 欧美日韩熟女一区二区三区| 国产精品人妻一区二区三区网站 | 一个人免费在线观看ww视频| 孕妇奶水仑乱A级毛片免费看| 国产在线一区二区三区麻酥酥| 狠狠躁夜夜躁人人爽天天天天97| av亚洲中文天堂字幕网| 午夜av一区二区三区| 一区二区视频视频视频| 日韩精品激情在线观看| 午夜婷婷在线观看视频| 久久久精品欧洲亚洲av| 日韩三级黄色片网站| 亚洲高清视频在线不卡| 午夜在线一区二区免费| 一区二区三区麻豆福利视频| 青娱乐最新视频在线| 日韩欧美一级精品在线观看| 亚洲中文精品人人免费| 日韩视频一区二区免费观看| 黄色三级网站免费下载| 国产视频一区二区午夜| 亚洲免费av在线视频| 91极品新人『兔兔』精品新作| 中文字幕免费福利视频6| 老司机午夜精品视频资源| 国产亚洲视频在线二区| 福利视频广场一区二区| 免费手机黄页网址大全| 人人爱人人妻人人澡39| 一级黄色av在线观看| 四川乱子伦视频国产vip| 亚洲在线一区二区欧美| 在线观看亚洲人成免费网址| 日本少妇在线视频大香蕉在线观看| 自拍偷拍一区二区三区图片| 久久久久久久久久久久久97| 国产视频网站国产视频| 扒开让我视频在线观看| 人妻熟女在线一区二区| 色在线观看视频免费的| 91欧美在线免费观看| 日本又色又爽又黄又粗| 国产成人小视频在线观看无遮挡| 国产 在线 免费 精品| 人妻丝袜精品中文字幕| 青青青青青青青青青青草青青| 欧美在线一二三视频| 夜夜骑夜夜操夜夜奸| 亚洲av自拍天堂网| 中文字幕中文字幕人妻| 国产精品国产三级国产午| 97年大学生大白天操逼| 国产精品视频男人的天堂| 日本一区精品视频在线观看| 热久久只有这里有精品| 亚洲欧美清纯唯美另类| 无忧传媒在线观看视频| 搡老妇人老女人老熟女| 青青色国产视频在线| 青青尤物在线观看视频网站| 午夜精品久久久久麻豆影视| 成人sm视频在线观看| 欧洲黄页网免费观看| 大鸡巴操娇小玲珑的女孩逼| 久久三久久三久久三久久| 国产美女一区在线观看| 欧美亚洲国产成人免费在线 | 色婷婷精品大在线观看| 精品日产卡一卡二卡国色天香| 欧美日韩情色在线观看| 神马午夜在线观看视频| 日本午夜久久女同精女女| 国产变态另类在线观看| 一区二区三区美女毛片| 亚洲区美熟妇久久久久| 视频一区二区综合精品| 国产av自拍偷拍盛宴| 久久99久久99精品影院| 免费黄页网站4188| 日本少妇人妻xxxxxhd| 日本裸体熟妇区二区欧美| 啊啊啊想要被插进去视频| 操日韩美女视频在线免费看| 漂亮 人妻被中出中文| 国产三级影院在线观看| av天堂加勒比在线| 91国内视频在线观看| 超级碰碰在线视频免费观看| 97青青青手机在线视频| 日本xx片在线观看| 国产精品女邻居小骚货| 日韩亚洲高清在线观看| 国产精品福利小视频a| 欧美伊人久久大香线蕉综合| 日本一道二三区视频久久| 性欧美日本大妈母与子| 91精品啪在线免费| 把腿张开让我插进去视频 | 成年人免费看在线视频| 视频一区 视频二区 视频| 在线观看一区二区三级| 91国内视频在线观看| 熟女人妻在线中出观看完整版| 91麻豆精品久久久久| 99精品久久久久久久91蜜桃| 久久精品美女免费视频| 国产又色又刺激在线视频| 亚洲成人熟妇一区二区三区 | 午夜成午夜成年片在线观看| 亚洲高清一区二区三区视频在线| 韩国黄色一级二级三级| 国产 在线 免费 精品| 日韩中文字幕在线播放第二页| 激情小视频国产在线| 老司机深夜免费福利视频在线观看| AV无码一区二区三区不卡| 一区二区三区 自拍偷拍| 在线免费观看国产精品黄色| 亚洲午夜高清在线观看| 欧美日韩一区二区电影在线观看| 哥哥姐姐综合激情小说| 国产精品自偷自拍啪啪啪| 亚洲人妻30pwc| 婷婷综合亚洲爱久久| 日本人妻少妇18—xx| 国产激情av网站在线观看| 97色视频在线观看| 日韩一区二区三区三州| 天天操夜夜操天天操天天操| 色哟哟国产精品入口| av在线播放国产不卡| 在线观看黄色成年人网站| 2019av在线视频| 久久农村老妇乱69系列| 黄色黄色黄片78在线| 日本一本午夜在线播放| 在线免费观看日本片| 二区中出在线观看老师| 精品一区二区三区在线观看| 日本福利午夜电影在线观看| 亚洲午夜精品小视频| 啊用力插好舒服视频| 99精品国产自在现线观看| 在线可以看的视频你懂的 | 在线可以看的视频你懂的| 久久午夜夜伦痒痒想咳嗽P| 欧亚日韩一区二区三区观看视频| 男女啪啪啪啪啪的网站| 国产高清在线观看1区2区| 岳太深了紧紧的中文字幕| 久久机热/这里只有| 午夜福利资源综合激情午夜福利资| 狠狠的往里顶撞h百合| 九色视频在线观看免费| 国产精品手机在线看片| 55夜色66夜色国产精品站| 日本少妇人妻xxxxxhd| 在线观看视频一区麻豆| 亚洲av可乐操首页| 天天射夜夜操狠狠干| 自拍偷拍日韩欧美一区二区| 91自产国产精品视频| 91桃色成人网络在线观看| 国产精品久久综合久久| 国产变态另类在线观看| 大陆精品一区二区三区久久| 中文亚洲欧美日韩无线码| 欧美成人一二三在线网| mm131美女午夜爽爽爽| 黑人大几巴狂插日本少妇| 自拍偷拍vs一区二区三区| 日韩成人免费电影二区| 又黄又刺激的午夜小视频| 日日摸夜夜添夜夜添毛片性色av| 在线免费观看国产精品黄色| 成人免费公开视频无毒| 天天日天天日天天射天天干| 国产成人精品一区在线观看 | 欧美日韩高清午夜蜜桃大香蕉| 成人影片高清在线观看| 午夜精品在线视频一区| 人妻另类专区欧美制服| 亚洲成人国产综合一区| 青青青青视频在线播放| 专门看国产熟妇的网站| 做爰视频毛片下载蜜桃视频1| 亚洲少妇高潮免费观看| 超级福利视频在线观看| 亚洲推理片免费看网站| 大胆亚洲av日韩av| 国产真实乱子伦a视频| 中文字幕av第1页中文字幕| 国产中文字幕四区在线观看| caoporn蜜桃视频| 日视频免费在线观看| 国产大鸡巴大鸡巴操小骚逼小骚逼| 特级欧美插插插插插bbbbb| 一区二区免费高清黄色视频| 久久久极品久久蜜桃| 一区二区三区日韩久久| 99久久激情婷婷综合五月天| 1区2区3区4区视频在线观看| 一区二区三区四区视频在线播放 | 亚洲男人的天堂a在线| 日本一区美女福利视频| 黄色录像鸡巴插进去| 欧美第一页在线免费观看视频| 国产精彩福利精品视频| 红杏久久av人妻一区| 夫妻在线观看视频91| 91麻豆精品秘密入口在线观看| 日本少妇的秘密免费视频| 婷婷色中文亚洲网68| 最新国产精品拍在线观看| 日韩不卡中文在线视频网站| 最近的中文字幕在线mv视频| 日本少妇人妻xxxxxhd| 超碰公开大香蕉97| 2o22av在线视频| 端庄人妻堕落挣扎沉沦| 人妻少妇性色欲欧美日韩| 亚洲一区二区人妻av| 大黑人性xxxxbbbb| 漂亮 人妻被中出中文| 亚洲综合一区成人在线| 青青青艹视频在线观看| 97超碰人人搞人人| 天天躁日日躁狠狠躁躁欧美av| 中文字幕—97超碰网| 国产亚洲欧美视频网站| 丁香花免费在线观看中文字幕| 五十路熟女人妻一区二区9933 | 黄色av网站免费在线| 福利午夜视频在线合集| 日本免费一级黄色录像| 女同互舔一区二区三区| 欧美地区一二三专区| 日韩美av高清在线| 极品丝袜一区二区三区| 午夜影院在线观看视频羞羞羞| 国产熟妇乱妇熟色T区| 亚洲成人av在线一区二区| av中文在线天堂精品| 爆乳骚货内射骚货内射在线| 大白屁股精品视频国产| 亚洲在线一区二区欧美| 久久精品亚洲国产av香蕉| 高潮喷水在线视频观看| 天堂女人av一区二区| 亚洲精品亚洲人成在线导航| 风流唐伯虎电视剧在线观看| 亚洲Av无码国产综合色区| 日本熟妇丰满厨房55| 97人人妻人人澡人人爽人人精品| 自拍 日韩 欧美激情| 成人动漫大肉棒插进去视频| av在线免费资源站| 亚洲福利精品视频在线免费观看| 成人av在线资源网站| aiss午夜免费视频| 二区中出在线观看老师| 欧美老鸡巴日小嫩逼| 国产精品大陆在线2019不卡| 特级无码毛片免费视频播放| 超鹏97历史在线观看| 热久久只有这里有精品| 精品国产高潮中文字幕| 亚洲 中文 自拍 另类 欧美| 亚洲va国产va欧美精品88| 国产精彩福利精品视频| 黄色黄色黄片78在线| 精品国产成人亚洲午夜| 日韩美av高清在线| 97人妻夜夜爽二区欧美极品| 99精品国自产在线人| 亚洲 人妻 激情 中文| 高清成人av一区三区| 色婷婷综合激情五月免费观看| 国产伦精品一区二区三区竹菊| 蜜桃专区一区二区在线观看| 亚洲中文精品字幕在线观看| 成人福利视频免费在线| 一区国内二区日韩三区欧美| 亚洲自拍偷拍综合色| 黄色中文字幕在线播放| 日韩美女福利视频网| 日韩二区视频一线天婷婷五| 92福利视频午夜1000看| 亚洲成高清a人片在线观看| 97国产在线av精品| 色婷婷综合激情五月免费观看| 强行扒开双腿猛烈进入免费版| 黑人解禁人妻叶爱071| 黑人借宿ntr人妻的沦陷2| 青青草人人妻人人妻| 国产麻豆91在线视频| 国产大学生援交正在播放| 午夜福利人人妻人人澡人人爽| 人妻3p真实偷拍一二区| 唐人色亚洲av嫩草| 青青草人人妻人人妻| 一级黄片大鸡巴插入美女| 亚洲av无乱一区二区三区性色| 中文字幕一区的人妻欧美日韩| 伊人成人在线综合网| 黄色录像鸡巴插进去| 成熟熟女国产精品一区| 在线观看免费视频网| 激情五月婷婷综合色啪| 99久久超碰人妻国产| 久久久久久国产精品| 中文字幕第一页国产在线| 新97超碰在线观看| 天堂va蜜桃一区入口| 又粗又长 明星操逼小视频| 自拍偷拍日韩欧美一区二区| 女生自摸在线观看一区二区三区| 性色av一区二区三区久久久 | 免费在线黄色观看网站| 国产日本欧美亚洲精品视| 亚洲国产免费av一区二区三区| 欧美日韩v中文在线| 18禁无翼鸟成人在线| 亚洲 自拍 色综合图| av亚洲中文天堂字幕网| 色呦呦视频在线观看视频| 国产激情av网站在线观看| 日韩视频一区二区免费观看| 人妻丰满熟妇综合网| 国产精品日韩欧美一区二区| 女同性ⅹxx女同hd| 国产成人精品福利短视频| 91国偷自产一区二区三区精品| 大胆亚洲av日韩av| 天天干天天搞天天摸| 中文字幕在线第一页成人| 亚洲一区二区三区久久受| 都市家庭人妻激情自拍视频| av在线播放国产不卡| 色婷婷精品大在线观看| 日本欧美视频在线观看三区| 黄工厂精品视频在线观看| 欧美中国日韩久久精品| 91大神福利视频网| 欧美女同性恋免费a| 亚洲天堂有码中文字幕视频| 亚洲国产欧美国产综合在线| 亚洲av色图18p| 国产janese在线播放| 精品人妻一二三区久久| 精品国产在线手机在线| 亚洲视频在线视频看视频在线| 久久久久久9999久久久久| 丰满的子国产在线观看| 亚洲综合一区二区精品久久| 日本av在线一区二区三区| 亚洲无码一区在线影院| 欧美va不卡视频在线观看| 免费在线观看污污视频网站| 免费看国产av网站| 日本精品美女在线观看| 久久艹在线观看视频| 无码精品一区二区三区人| 白嫩白嫩美女极品国产在线观看| yy96视频在线观看| 国产一区二区欧美三区| 视频一区二区三区高清在线| 宅男噜噜噜666国产| 天天射夜夜操综合网| 日本午夜爽爽爽爽爽视频在线观看| 国产精品自拍在线视频| AV天堂一区二区免费试看| 在线观看视频网站麻豆| 亚洲精品乱码久久久本| 亚洲精品成人网久久久久久小说| 国产亚洲精品品视频在线| 一级A一级a爰片免费免会员| 果冻传媒av一区二区三区 | 久久精品国产亚洲精品166m| 亚洲高清国产自产av| 伊人综合aⅴ在线网| 久久午夜夜伦痒痒想咳嗽P| 国产精品人久久久久久| 欧美精品国产综合久久| 亚洲成av人无码不卡影片一| 97精品综合久久在线| 999九九久久久精品| 1000部国产精品成人观看视频 | 国产av福利网址大全| 久久久久久久久久久久久97| 久久久噜噜噜久久熟女av| 粉嫩av懂色av蜜臀av| 黄色资源视频网站日韩| 欧洲精品第一页欧洲精品亚洲| 青青青青青青青青青青草青青| 在线可以看的视频你懂的| 不戴胸罩引我诱的隔壁的人妻| 免费在线播放a级片| 国产精品久久综合久久| 国产白袜脚足J棉袜在线观看| 欧美精品 日韩国产| 天堂资源网av中文字幕| 少妇露脸深喉口爆吞精| 亚洲最大黄了色网站| 日本丰满熟妇大屁股久久| 久久人人做人人妻人人玩精品vr| 久久久久久97三级| 一二三中文乱码亚洲乱码one | 97精品成人一区二区三区| 免费一级黄色av网站| 绝顶痉挛大潮喷高潮无码| 国产精品视频资源在线播放| free性日本少妇| 亚洲一区二区三区五区| 色婷婷精品大在线观看| 一色桃子人妻一区二区三区| 欧美一区二区三区乱码在线播放| 亚洲成高清a人片在线观看| 亚洲一区二区三区精品视频在线| 久久精品亚洲国产av香蕉| 成熟熟女国产精品一区| 国产精品福利小视频a| 欧美亚洲少妇福利视频| 色综合色综合色综合色| 中文字幕人妻一区二区视频 | 国产性色生活片毛片春晓精品| 成人av久久精品一区二区| 亚洲精品福利网站图片| 午夜精品在线视频一区| av男人天堂狠狠干| 超级av免费观看一区二区三区| caoporn蜜桃视频| 一级黄片大鸡巴插入美女| 日本少妇在线视频大香蕉在线观看| 欧美日本在线观看一区二区| 在线观看的黄色免费网站| 国产精品中文av在线播放| 91中文字幕最新合集| 不卡一区一区三区在线| 亚洲美女美妇久久字幕组| 日韩欧美国产一区不卡| 特级欧美插插插插插bbbbb| 欧美精产国品一二三区| 农村胖女人操逼视频| 久久久久久久精品老熟妇| 亚洲男人在线天堂网| 黄色录像鸡巴插进去| 岛国黄色大片在线观看| 亚洲欧美成人综合在线观看| 亚洲欧美激情中文字幕| 欧洲精品第一页欧洲精品亚洲| 狠狠躁狠狠爱网站视频| 最新中文字幕免费视频| 在线视频免费观看网| 成熟熟女国产精品一区| 啪啪啪18禁一区二区三区| 日韩av中文在线免费观看| 开心 色 六月 婷婷| 后入美女人妻高清在线| 日本后入视频在线观看| 欧美特色aaa大片| 亚洲中文精品人人免费| 欧美亚洲免费视频观看| 日本熟妇喷水xxx| 欧美成人黄片一区二区三区 | 一区二区熟女人妻视频| 日辽宁老肥女在线观看视频| 欧美男同性恋69视频| 精品91高清在线观看| 成人sm视频在线观看| 888欧美视频在线| 在线观看视频污一区| 国产亚州色婷婷久久99精品| 成年人的在线免费视频| 亚洲成人国产综合一区| 久精品人妻一区二区三区| 日本后入视频在线观看| 午夜精品久久久久久99热| 国产成人一区二区三区电影网站 | 97精品成人一区二区三区 | 中文字幕欧美日韩射射一| 亚洲av无硬久久精品蜜桃| 视频久久久久久久人妻| 亚洲区美熟妇久久久久| 欧美视频中文一区二区三区| 欧美在线精品一区二区三区视频 | 午夜91一区二区三区| 啊用力插好舒服视频| 偷拍3456eee| 亚洲午夜高清在线观看| 男人的天堂一区二区在线观看| 又黄又刺激的午夜小视频| 强行扒开双腿猛烈进入免费版| 91精品国产91青青碰| 国产在线91观看免费观看| 最近中文2019年在线看| 97欧洲一区二区精品免费| 最近的中文字幕在线mv视频| 午夜极品美女福利视频| 中文字幕乱码av资源| 亚洲丝袜老师诱惑在线观看| 日韩中文字幕在线播放第二页| 国产aⅴ一线在线观看| 一区二区三区四区中文| 五十路老熟女码av| 天天射夜夜操狠狠干| 亚洲成高清a人片在线观看| 国产亚洲视频在线观看| 人妻3p真实偷拍一二区| 国产福利在线视频一区| 女蜜桃臀紧身瑜伽裤| chinese国产盗摄一区二区| 亚洲特黄aaaa片| 97精品人妻一区二区三区精品| av高潮迭起在线观看| 一区二区三区的久久的蜜桃的视频 | 超碰97人人澡人人| 国产在线观看免费人成短视频| 在线免费视频 自拍| av黄色成人在线观看| 超pen在线观看视频公开97| 中文字幕亚洲中文字幕| 日韩三级电影华丽的外出| brazzers欧熟精品系列| 久久香蕉国产免费天天| 欧美成人精品在线观看| 视频 一区二区在线观看| 成年人免费看在线视频| 亚洲第一伊人天堂网| 2021天天色天天干| 传媒在线播放国产精品一区| 55夜色66夜色国产精品站| 激情综合治理六月婷婷| 午夜精品一区二区三区4| 午夜在线一区二区免费| 日韩黄色片在线观看网站| 五十路熟女人妻一区二区9933| 人人在线视频一区二区| 男人的天堂在线黄色| 日韩写真福利视频在线观看| 国产麻豆剧传媒精品国产av蜜桃| 九九视频在线精品播放| 777奇米久久精品一区| 天堂av中文在线最新版| 婷婷久久久久深爱网| 91久久国产成人免费网站| 99视频精品全部15| 久久久久久97三级| 喷水视频在线观看这里只有精品| 四川乱子伦视频国产vip| 水蜜桃国产一区二区三区| 色爱av一区二区三区| caoporn蜜桃视频| 午夜影院在线观看视频羞羞羞| 啊啊啊想要被插进去视频| 国产亚洲四十路五十路| av黄色成人在线观看| 天天干天天操天天插天天日| 一区二区三区 自拍偷拍| 亚洲美女高潮喷浆视频| 啪啪啪啪啪啪啪啪啪啪黄色| 动漫黑丝美女的鸡巴| 青青青视频手机在线观看| 亚洲国产成人无码麻豆艾秋| 沈阳熟妇28厘米大战黑人| 欧洲亚洲欧美日韩综合| 在线亚洲天堂色播av电影| 99精品免费观看视频| 337p日本大胆欧美人| 超级av免费观看一区二区三区| 亚洲免费va在线播放| 欧美精产国品一二三区| 成人影片高清在线观看| 在线观看视频污一区| 精品av国产一区二区三区四区| 日本性感美女写真视频| 午夜毛片不卡免费观看视频| 中文字幕在线视频一区二区三区| 1769国产精品视频免费观看| 又粗又硬又猛又黄免费30| 岛国av高清在线成人在线| 中文字幕高清免费在线人妻| 绝顶痉挛大潮喷高潮无码| 天天干夜夜操啊啊啊| 99精品久久久久久久91蜜桃| 黑人3p华裔熟女普通话| 99精品视频之69精品视频| 人妻3p真实偷拍一二区| 亚洲天堂有码中文字幕视频| 国产成人自拍视频播放| 国产在线91观看免费观看| 好男人视频在线免费观看网站| 老司机在线精品福利视频| 九九热99视频在线观看97| 特大黑人巨大xxxx| 国产成人一区二区三区电影网站| 2022国产精品视频| 日本人竟这样玩学生妹| 国产精品亚洲а∨天堂免| 日本后入视频在线观看| 3D动漫精品啪啪一区二区下载| 青青青青在线视频免费观看| 亚洲av日韩av网站| 少妇系列一区二区三区视频| 精品少妇一二三视频在线| 91试看福利一分钟| 香蕉aⅴ一区二区三区| 国产麻豆乱子伦午夜视频观看| 欧美精品免费aaaaaa| 亚洲欧美激情人妻偷拍| 国产又粗又猛又爽又黄的视频在线| 激情人妻校园春色亚洲欧美| 亚洲国产精品免费在线观看| 国产精品亚洲а∨天堂免| 亚洲精品成人网久久久久久小说| 黄色片一级美女黄色片| 97年大学生大白天操逼| 一级黄片大鸡巴插入美女| 我想看操逼黄色大片| 国产九色91在线观看精品| 亚洲伊人色一综合网| 精品一区二区三区三区色爱| 国产自拍黄片在线观看| 亚洲最大免费在线观看| 久久久久久国产精品| 丝袜肉丝一区二区三区四区在线| 日本人妻少妇18—xx| 中国熟女@视频91| 中文字幕国产专区欧美激情| 老司机午夜精品视频资源| 成人在线欧美日韩国产| 日本av熟女在线视频| 自拍 日韩 欧美激情| 亚洲免费视频欧洲免费视频 | 久久久超爽一二三av| 中文字幕中文字幕 亚洲国产| av欧美网站在线观看| 欧美3p在线观看一区二区三区| 好了av中文字幕在线| 天天日天天干天天插舔舔| 久久国产精品精品美女| 懂色av之国产精品| 婷婷久久一区二区字幕网址你懂得| 天天日天天添天天爽| 久草福利电影在线观看| 中文字幕中文字幕人妻| 成熟丰满熟妇高潮xx×xx | 97人人妻人人澡人人爽人人精品| 无码日韩人妻精品久久| 高清成人av一区三区| 青青青青在线视频免费观看| 中文字幕一区二区三区人妻大片| 丝袜长腿第一页在线| 天天日天天操天天摸天天舔| 日美女屁股黄邑视频| 熟女人妻在线中出观看完整版| av中文字幕在线观看第三页| 天堂av中文在线最新版| 综合页自拍视频在线播放| 久久久久久性虐视频| 高潮喷水在线视频观看| 在线视频国产欧美日韩| 在线观看视频 你懂的| 国产男女视频在线播放| 女生自摸在线观看一区二区三区| 丁香花免费在线观看中文字幕| 国产在线免费观看成人| 成人激情文学网人妻| 国内资源最丰富的网站| 精品视频一区二区三区四区五区| 男人在床上插女人视频| 99热色原网这里只有精品| 一区二区三区的久久的蜜桃的视频 | 青青青aaaa免费| 欧美日韩高清午夜蜜桃大香蕉| heyzo蜜桃熟女人妻| 日本少妇高清视频xxxxx| 好男人视频在线免费观看网站| 亚洲一区二区三区精品乱码| 欧美激情电影免费在线| 亚洲卡1卡2卡三卡四老狼| aⅴ精产国品一二三产品| 91精品激情五月婷婷在线| 日韩欧美亚洲熟女人妻| 欧美一级片免费在线成人观看| 偷拍美女一区二区三区| 国产精品久久久久网| 大胆亚洲av日韩av| 女生被男生插的视频网站| 成人av在线资源网站| 色综合色综合色综合色| 78色精品一区二区三区| 伊人开心婷婷国产av| 宅男噜噜噜666国产| 亚洲欧美清纯唯美另类 | a v欧美一区=区三区| 亚洲精品欧美日韩在线播放| 亚洲熟色妇av日韩熟色妇在线 | 97精品人妻一区二区三区精品| av高潮迭起在线观看| 亚洲综合另类精品小说| 日日夜夜大香蕉伊人| 欧美黑人与人妻精品| 日韩欧美国产一区ab| 区一区二区三国产中文字幕| 看一级特黄a大片日本片黑人| av在线资源中文字幕| 天天摸天天干天天操科普| 亚洲av自拍天堂网| 一区二区三区另类在线 | 在线国产中文字幕视频| 天天日天天添天天爽| 国产黄色大片在线免费播放 | 99精品国自产在线人| 国产精品女邻居小骚货| 欧美国品一二三产区区别| 精品视频中文字幕在线播放| 日本福利午夜电影在线观看| 丝袜美腿视频诱惑亚洲无| 日韩av免费观看一区| 欧美精品激情在线最新观看视频| 国产精品欧美日韩区二区| 国产97视频在线精品| 绝顶痉挛大潮喷高潮无码| 日韩加勒比东京热二区| 国产精品黄页网站视频| 最新国产精品拍在线观看| 免费av岛国天堂网站| 国产又粗又硬又大视频| 班长撕开乳罩揉我胸好爽| 日本高清撒尿pissing| 99精品视频之69精品视频| brazzers欧熟精品系列| 一区国内二区日韩三区欧美| 极品性荡少妇一区二区色欲| 日韩影片一区二区三区不卡免费| 亚洲另类伦春色综合小| 亚洲欧美激情国产综合久久久| 国产极品精品免费视频 | 班长撕开乳罩揉我胸好爽| 天天操天天干天天日狠狠插| 丝袜肉丝一区二区三区四区在线看| 亚洲精品ww久久久久久| 黄色片一级美女黄色片| 男人的网址你懂的亚洲欧洲av| 黑人乱偷人妻中文字幕| 国产女人被做到高潮免费视频| 无套猛戳丰满少妇人妻| 天美传媒mv视频在线观看| 国产精品自拍偷拍a| 欧美激情精品在线观看| 三级黄色亚洲成人av| 在线观看911精品国产| 国产一区二区神马久久| 中文字幕中文字幕人妻| 九九热99视频在线观看97| 91国产在线视频免费观看| 高潮喷水在线视频观看| 日韩精品激情在线观看| 国产精品污污污久久| 一区二区三区激情在线| 国产使劲操在线播放| 亚洲最大免费在线观看| 国产在线拍揄自揄视频网站| 97超碰国语国产97超碰| 欧美va不卡视频在线观看| 一二三中文乱码亚洲乱码one| 日本一二三中文字幕| 中文字幕免费福利视频6| 亚洲av天堂在线播放| 日韩av中文在线免费观看| 亚洲国产在线精品国偷产拍| 欧美日韩中文字幕欧美| 国产综合精品久久久久蜜臀| 亚洲av可乐操首页| 夏目彩春在线中文字幕| 大尺度激情四射网站| 中文字幕日韩91人妻在线| 国产精品3p和黑人大战| 摧残蹂躏av一二三区| 中文字幕日韩91人妻在线| av天堂中文免费在线| av在线免费中文字幕| 一区二区三区激情在线| 亚洲高清国产一区二区三区| 欧美亚洲一二三区蜜臀| 硬鸡巴动态操女人逼视频| 日日夜夜大香蕉伊人| 制服丝袜在线人妻中文字幕| 91人妻精品久久久久久久网站| 国产精品午夜国产小视频| 中文亚洲欧美日韩无线码| 三级av中文字幕在线观看| 2020av天堂网在线观看| 亚洲国产欧美国产综合在线 | 亚洲免费av在线视频| 77久久久久国产精产品| 国产又粗又猛又爽又黄的视频在线| 人妻丰满熟妇综合网| 视频一区二区综合精品| 国产又粗又硬又大视频| 欧美国品一二三产区区别| 国产精品亚洲а∨天堂免| 93精品视频在线观看| 97人妻夜夜爽二区欧美极品| 黄色男人的天堂视频| 最新97国产在线视频| 亚洲免费国产在线日韩| 偷拍自拍福利视频在线观看| 久久丁香花五月天色婷婷| 欧美亚洲免费视频观看| 日韩美女综合中文字幕pp| 熟女妇女老妇一二三区| 天天色天天操天天透| 午夜蜜桃一区二区三区| 人妻3p真实偷拍一二区| 一区二区三区四区五区性感视频 | 最新97国产在线视频| 中文字幕一区二区自拍| 水蜜桃国产一区二区三区| 极品丝袜一区二区三区| 国产精品3p和黑人大战| 一区二区三区另类在线 | 青青擦在线视频国产在线| 91www一区二区三区| 日本少妇的秘密免费视频| 1000小视频在线| 青草青永久在线视频18| av乱码一区二区三区| 成人久久精品一区二区三区| 100%美女蜜桃视频| 日韩美女综合中文字幕pp| 亚洲午夜电影在线观看| 在线视频免费观看网| 亚洲青青操骚货在线视频| 欧美精品 日韩国产| 亚洲欧美成人综合视频| 亚洲欧美国产麻豆综合| 2019av在线视频| 天天色天天爱天天爽| 婷婷色国产黑丝少妇勾搭AV| 亚洲精品久久视频婷婷| 夜夜骑夜夜操夜夜奸| 男人的天堂一区二区在线观看| 日韩欧美中文国产在线 | 免费观看理论片完整版| 日本美女成人在线视频| 成人乱码一区二区三区av| 色吉吉影音天天干天天操| 狠狠躁夜夜躁人人爽天天天天97| jiujiure精品视频在线| 亚洲av自拍偷拍综合| 精品91高清在线观看| 巨乳人妻日下部加奈被邻居中出 | 不卡精品视频在线观看| v888av在线观看视频| 成人高清在线观看视频| 大陆av手机在线观看| 男女啪啪啪啪啪的网站| 国产乱子伦一二三区| 超级av免费观看一区二区三区| 91破解版永久免费| 制服丝袜在线人妻中文字幕| 真实国产乱子伦一区二区| 在线观看av2025| 狍和女人的王色毛片| 一区国内二区日韩三区欧美| 韩国爱爱视频中文字幕| 新婚人妻聚会被中出| 91久久综合男人天堂| 国产视频一区二区午夜| 91大屁股国产一区二区| 亚洲欧美另类手机在线| 免费成人va在线观看| 天天操天天干天天插| 亚洲精品无码久久久久不卡| 亚洲福利精品福利精品福利| 边摸边做超爽毛片18禁色戒| 综合激情网激情五月五月婷婷| 国产免费高清视频视频| 国产丰满熟女成人视频| 熟女人妻在线观看视频| 天天日天天天天天天天天天天| 熟女人妻一区二区精品视频| 综合国产成人在线观看| 秋霞午夜av福利经典影视| 91人妻精品久久久久久久网站| 黄色片黄色片wyaa| 在线国产日韩欧美视频| 日韩a级黄色小视频| 五十路熟女人妻一区二| 亚洲图片欧美校园春色| 动漫美女的小穴视频| 欧美韩国日本国产亚洲| 精品国产在线手机在线| 日韩三级电影华丽的外出| 亚洲免费在线视频网站| 天天日天天日天天擦| 黄色在线观看免费观看在线| 色97视频在线播放| aⅴ精产国品一二三产品| 国产aⅴ一线在线观看| 亚洲熟妇x久久av久久| 久久久极品久久蜜桃| 国产日韩一区二区在线看| 亚洲图片偷拍自拍区| 久久这里有免费精品| 日韩av有码中文字幕| 国产亚洲视频在线观看| 中文字幕一区二 区二三区四区| 国产va在线观看精品| av久久精品北条麻妃av观看| 午夜蜜桃一区二区三区| 日本成人不卡一区二区| 欧美精品 日韩国产| av资源中文字幕在线观看| 久久丁香婷婷六月天| 91小伙伴中女熟女高潮| 欲乱人妻少妇在线视频裸| 亚洲最大黄了色网站| 久久美欧人妻少妇一区二区三区| 亚洲最大黄 嗯色 操 啊| 91色秘乱一区二区三区| 日本阿v视频在线免费观看| 欧美视频综合第一页| 2018在线福利视频| 中文字幕日韩91人妻在线| 水蜜桃国产一区二区三区| 欧美黑人与人妻精品| 免费啪啪啪在线观看视频| 国产一区二区久久久裸臀| 最新中文字幕免费视频| 亚洲精品国品乱码久久久久| 超碰在线中文字幕一区二区| 亚洲 欧美 精品 激情 偷拍| 久久久久久久精品成人热| 人人爽亚洲av人人爽av| 2019av在线视频| 精品久久久久久高潮| 天天操天天射天天操天天天| 色噜噜噜噜18禁止观看| 91精品国产91青青碰| 亚洲第一伊人天堂网| 天天插天天色天天日| 国产一区二区久久久裸臀| 日本特级片中文字幕| 92福利视频午夜1000看 | 福利午夜视频在线观看| 色秀欧美视频第一页| 青青青青青手机视频| 久久这里有免费精品| 国产精品精品精品999| 国产午夜福利av导航| 伊人情人综合成人久久网小说| 日本人妻欲求不满中文字幕| 最新国产亚洲精品中文在线| 一区二区三区蜜臀在线| 日本午夜爽爽爽爽爽视频在线观看| 亚洲成人av一区在线| 伊人综合aⅴ在线网| 欧美aa一级一区三区四区| 国产视频在线视频播放| 青青伊人一精品视频| 婷婷色中文亚洲网68| 亚洲欧美国产麻豆综合| 日本www中文字幕| 熟女国产一区亚洲中文字幕| 国产成人精品一区在线观看 | 一色桃子久久精品亚洲| 老熟妇xxxhd老熟女| 日本韩国亚洲综合日韩欧美国产 | 精产国品久久一二三产区区别 | 性感美女高潮视频久久久| 日韩欧美亚洲熟女人妻| 亚洲成人av一区久久| 少妇被强干到高潮视频在线观看| 国产成人自拍视频在线免费观看| 日美女屁股黄邑视频| 91精品国产综合久久久蜜| 亚洲图片偷拍自拍区| 亚洲av天堂在线播放| 91亚洲精品干熟女蜜桃频道| 人妻素人精油按摩中出| 天天干天天操天天玩天天射| 视频二区在线视频观看| 婷婷色国产黑丝少妇勾搭AV| 日本裸体熟妇区二区欧美| 同居了嫂子在线播高清中文| 欧美精品亚洲精品日韩在线| 欧美viboss性丰满| 人妻激情图片视频小说| 中文字幕一区二区自拍| 98视频精品在线观看| 日日夜夜狠狠干视频| 欧美国产亚洲中英文字幕| 成人av电影免费版| 欧美日韩中文字幕欧美| 激情小视频国产在线| 热思思国产99re| 天天日天天日天天擦| 亚洲老熟妇日本老妇| 欧美特色aaa大片| 亚洲日本一区二区三区| 亚洲人妻30pwc| 在线免费观看亚洲精品电影 | 韩国男女黄色在线观看| 成年人中文字幕在线观看| 人人妻人人爽人人澡人人精品| 国产精品黄页网站视频| 男女之间激情网午夜在线| 国产精品久久久久久久精品视频| 任你操视频免费在线观看| 五色婷婷综合狠狠爱| 婷婷色国产黑丝少妇勾搭AV| 精品区一区二区三区四区人妻 | 日本精品视频不卡一二三| 特大黑人巨大xxxx| 男人天堂av天天操| 国产精品入口麻豆啊啊啊| 成年午夜影片国产片| 在线视频自拍第三页| 精品美女福利在线观看| 国产精品3p和黑人大战| 沈阳熟妇28厘米大战黑人| 又黄又刺激的午夜小视频| 激情国产小视频在线| 人妻熟女在线一区二区| 免费黄页网站4188| 日韩国产乱码中文字幕| caoporn蜜桃视频| 97国产在线av精品| huangse网站在线观看| 亚洲嫩模一区二区三区| 91片黄在线观看喷潮| 天天艹天天干天天操| 午夜精品在线视频一区| 人妻熟女在线一区二区| 美女 午夜 在线视频| 女人精品内射国产99| 色综合色综合色综合色| 亚洲蜜臀av一区二区三区九色 | 十八禁在线观看地址免费| 红桃av成人在线观看| 久久这里只有精彩视频免费| 欧美精品免费aaaaaa| av黄色成人在线观看| 久久久制服丝袜中文字幕| 国产视频在线视频播放| 国内精品在线播放第一页| 美女吃鸡巴操逼高潮视频| 在线观看视频 你懂的| 最新国产亚洲精品中文在线| 亚洲一区二区三区久久午夜| 又色又爽又黄的美女裸体| 国产精品人妻熟女毛片av久| 亚洲天堂精品久久久| 亚洲成人av一区久久| 91精品国产麻豆国产| 国产大学生援交正在播放| 777奇米久久精品一区| 天天日夜夜操天天摸| 啪啪啪啪啪啪啪免费视频| 手机看片福利盒子日韩在线播放| 人妻久久久精品69系列| 精品国产高潮中文字幕| 色婷婷六月亚洲综合香蕉| 自拍偷拍日韩欧美一区二区| 亚洲成人av一区在线| 日本阿v视频在线免费观看| 强行扒开双腿猛烈进入免费版| 日本阿v视频在线免费观看| 开心 色 六月 婷婷| 老司机午夜精品视频资源| 亚洲粉嫩av一区二区三区| 天天操天天干天天艹| 午夜精品一区二区三区更新| 久久这里只有精品热视频| 特级无码毛片免费视频播放| 亚洲免费av在线视频| 青青草视频手机免费在线观看| 狠狠嗨日韩综合久久| 精品亚洲中文字幕av| 伊人成人综合开心网| 亚洲美女美妇久久字幕组| 视频啪啪啪免费观看| 偷拍美女一区二区三区| 一区二区三区久久久91| 美日韩在线视频免费看| 天天日天天透天天操| 中文字幕一区二区亚洲一区| 亚洲人妻视频在线网| 久久这里只有精彩视频免费| 91精品国产综合久久久蜜| 51国产偷自视频在线播放| 国产精品视频欧美一区二区| 国产性感美女福利视频| av一区二区三区人妻| 国产视频一区二区午夜| 亚洲精品欧美日韩在线播放| 日日爽天天干夜夜操| av天堂中文免费在线| 日本av在线一区二区三区| 精品一区二区三区三区88| 天堂av在线官网中文| 337p日本大胆欧美人| 国产av国片精品一区二区| 亚洲中文精品字幕在线观看| 国产熟妇乱妇熟色T区| 乱亲女秽乱长久久久| 亚洲天堂精品福利成人av| 国产免费高清视频视频| 天天色天天操天天舔| 啪啪啪18禁一区二区三区| 黄色三级网站免费下载| 最新激情中文字幕视频| 成人30分钟免费视频| 国产成人自拍视频在线免费观看| 欧美特级特黄a大片免费| 黄色三级网站免费下载| 国产福利小视频二区| 91免费观看国产免费| 护士特殊服务久久久久久久| 欧美精品中文字幕久久二区| 含骚鸡巴玩逼逼视频| 91在线免费观看成人| 精品一区二区三区欧美| 精品人妻一二三区久久| 久久www免费人成一看片| 家庭女教师中文字幕在线播放| 国产精品一二三不卡带免费视频 | 爱爱免费在线观看视频| 国产91嫩草久久成人在线视频| 久久精品亚洲成在人线a| 中文字幕中文字幕 亚洲国产| 超级av免费观看一区二区三区| 18禁无翼鸟成人在线| asmr福利视频在线观看| 91麻豆精品传媒国产黄色片| 色综合久久久久久久久中文| wwwxxx一级黄色片| 美日韩在线视频免费看| 中文字幕在线乱码一区二区| 五月婷婷在线观看视频免费| 福利国产视频在线观看| 青青青艹视频在线观看| 久久久精品欧洲亚洲av| 天天射夜夜操综合网| 久久久精品999精品日本| 欧美日韩精品永久免费网址| 亚洲图片偷拍自拍区| 把腿张开让我插进去视频| 亚洲熟色妇av日韩熟色妇在线| 人妻丝袜精品中文字幕| 欧美香蕉人妻精品一区二区| 自拍偷拍亚洲精品第2页| 91中文字幕免费在线观看| 亚洲高清一区二区三区视频在线| 免费人成黄页网站在线观看国产| 婷婷午夜国产精品久久久| 青青青艹视频在线观看| 亚洲蜜臀av一区二区三区九色 | 国产精品sm调教视频| 天天色天天操天天透| 18禁美女羞羞免费网站| 亚洲国产成人av在线一区| 日日摸夜夜添夜夜添毛片性色av| 欧美特级特黄a大片免费| 亚洲国产40页第21页| 特黄老太婆aa毛毛片| 日本午夜久久女同精女女| 亚洲 自拍 色综合图| 中文字幕网站你懂的| 欧美精产国品一二三产品价格| 不戴胸罩引我诱的隔壁的人妻 | 亚洲另类伦春色综合小| 国产一区二区神马久久| 一级黄色av在线观看| av网址国产在线观看| 亚洲av极品精品在线观看| 亚洲av黄色在线网站| 懂色av之国产精品| 全国亚洲男人的天堂| 国产精品国色综合久久| 午夜蜜桃一区二区三区| 91福利视频免费在线观看| 国产av国片精品一区二区| 97黄网站在线观看| 摧残蹂躏av一二三区| 欧美黑人巨大性xxxxx猛交| 一区二区久久成人网| 一个人免费在线观看ww视频| aⅴ五十路av熟女中出| 看一级特黄a大片日本片黑人| 一二三中文乱码亚洲乱码one| 亚洲中文精品字幕在线观看| 久久三久久三久久三久久| av中文字幕在线观看第三页| 涩涩的视频在线观看视频| 日韩美女精品视频在线观看网站| 丝袜国产专区在线观看| 亚洲一区二区人妻av| 五十路老熟女码av| 国产一区二区久久久裸臀| 免费观看丰满少妇做受| 日韩av熟妇在线观看| 人妻丝袜诱惑我操她视频| 国产成人自拍视频在线免费观看| 日韩在线视频观看有码在线| 视频 一区二区在线观看| 日韩精品中文字幕在线| 含骚鸡巴玩逼逼视频| 一区二区麻豆传媒黄片| 91精品激情五月婷婷在线| 亚洲第17页国产精品| 激情五月婷婷免费视频| 国产午夜无码福利在线看| 日本少妇精品免费视频| 久久久精品国产亚洲AV一| 涩爱综合久久五月蜜臀| 午夜场射精嗯嗯啊啊视频| 亚洲人一区二区中文字幕| 男人的天堂av日韩亚洲| 在线不卡成人黄色精品| 国产日韩精品一二三区久久久| 国产免费av一区二区凹凸四季| 亚洲国产美女一区二区三区软件| 日本真人性生活视频免费看| 男生舔女生逼逼视频| 新婚人妻聚会被中出| 40道精品招牌菜特色| 色秀欧美视频第一页| 中文字幕日韩精品就在这里| 天天插天天狠天天操| 人人妻人人爽人人澡人人精品| 亚洲综合另类精品小说| 5528327男人天堂| 美女av色播在线播放| av中文字幕在线导航| 97色视频在线观看| 在线观看欧美黄片一区二区三区| 亚洲成人午夜电影在线观看| 日韩欧美一级黄片亚洲| 午夜毛片不卡免费观看视频| 黄色录像鸡巴插进去| 丝袜美腿视频诱惑亚洲无| 3D动漫精品啪啪一区二区下载 | 91精品国产黑色丝袜| 亚洲 欧美 自拍 偷拍 在线| 精品少妇一二三视频在线| 888亚洲欧美国产va在线播放| 97色视频在线观看| 播放日本一区二区三区电影| 唐人色亚洲av嫩草| 91国产资源在线视频| 亚洲码av无色中文| 亚洲图片偷拍自拍区| 人妻少妇av在线观看| 国产使劲操在线播放| 大鸡巴后入爆操大屁股美女| 亚洲日本一区二区久久久精品| 国产亚洲欧美另类在线观看| 国产视频一区二区午夜| 亚洲色偷偷综合亚洲AV伊人| 天天摸天天亲天天舔天天操天天爽 | 国产91嫩草久久成人在线视频| 2018最新中文字幕在线观看| 女警官打开双腿沦为性奴| 成人高潮aa毛片免费| 国产精品污污污久久| 91亚洲国产成人精品性色| 日本午夜久久女同精女女| 2o22av在线视频| 中出中文字幕在线观看| 国产露脸对白在线观看| 亚洲日本一区二区三区 | 55夜色66夜色国产精品站| www,久久久,com| 久久农村老妇乱69系列| 国产亚洲成人免费在线观看| 夜女神免费福利视频| 青青青青草手机在线视频免费看| 在线观看一区二区三级| 2019av在线视频| 天码人妻一区二区三区在线看| 抽查舔水白紧大视频| 午夜精品福利91av| 无码中文字幕波多野不卡| 亚洲av极品精品在线观看| 亚洲免费va在线播放| 丝袜长腿第一页在线| 2019av在线视频| 亚洲欧美成人综合视频| 99热99这里精品6国产| 亚洲1区2区3区精华液| 美女大bxxxx内射| 在线观看的a站 最新| yy96视频在线观看| 人妻久久久精品69系列| 国产精品久久久久久久精品视频| xxx日本hd高清| 无码日韩人妻精品久久| 久久免费看少妇高潮完整版| 久草福利电影在线观看| 欧美视频综合第一页| 国产成人小视频在线观看无遮挡| 69精品视频一区二区在线观看| 亚洲激情唯美亚洲激情图片| 日韩a级精品一区二区| 精品久久婷婷免费视频| 国产精品久久9999| 亚洲午夜高清在线观看| 中文字幕乱码av资源| 97资源人妻免费在线视频| 88成人免费av网站| 国产一区二区神马久久| 又粗又硬又猛又爽又黄的| 人妻久久无码中文成人| 91综合久久亚洲综合| 国产精品sm调教视频| 性感美女诱惑福利视频| 哥哥姐姐综合激情小说| 99精品视频在线观看免费播放| 亚洲无线观看国产高清在线| 亚洲第17页国产精品| 爱有来生高清在线中文字幕| 91老熟女连续高潮对白| 精品人妻一二三区久久| 久久永久免费精品人妻专区 | 日本最新一二三区不卡在线| 亚洲精品无码久久久久不卡 | 美味人妻2在线播放| 人人爱人人妻人人澡39| 精品av国产一区二区三区四区| 少妇被强干到高潮视频在线观看| 最近中文2019年在线看| rct470中文字幕在线| 国产在线观看黄色视频| 大白屁股精品视频国产| 亚洲欧美清纯唯美另类| 亚洲欧美成人综合视频| 黄色录像鸡巴插进去| 伊人网中文字幕在线视频| 中文字幕人妻三级在线观看| 岛国黄色大片在线观看| 99久久99久国产黄毛片| 麻豆性色视频在线观看| 亚洲一区二区三区久久受 | 午夜dv内射一区区| 中文字幕亚洲久久久| 国产在线拍揄自揄视频网站| 欧美成人综合视频一区二区 | 极品粉嫩小泬白浆20p主播| 好男人视频在线免费观看网站| 92福利视频午夜1000看| 亚洲中文字幕人妻一区| 2021天天色天天干| 国产精品视频男人的天堂| 亚洲精品成人网久久久久久小说| 亚洲 国产 成人 在线| 超黄超污网站在线观看| 蝴蝶伊人久久中文娱乐网| 久久精品国产999| 国产日韩欧美视频在线导航| 熟女91pooyn熟女| 亚洲老熟妇日本老妇| 婷婷综合亚洲爱久久| 亚洲精品国产久久久久久| 午夜精品亚洲精品五月色| 啊啊啊视频试看人妻| 老师啊太大了啊啊啊尻视频| 亚洲综合一区二区精品久久| 欧美一区二区三区久久久aaa| 绯色av蜜臀vs少妇| 又色又爽又黄又刺激av网站| 在线免费视频 自拍| 欧美va不卡视频在线观看| 人人超碰国字幕观看97| 粉嫩av蜜乳av蜜臀| 国产午夜无码福利在线看| 国产精品人妻一区二区三区网站| 国产精品一区二区久久久av| 成人蜜桃美臀九一一区二区三区| 夜色17s精品人妻熟女| 国产精品成久久久久三级蜜臀av | 日本黄在免费看视频| 欧美偷拍自拍色图片| 专门看国产熟妇的网站| 视频一区二区三区高清在线| 制服丝袜在线人妻中文字幕| 黄色的网站在线免费看| 日韩美av高清在线| 99一区二区在线观看| 国产一区二区在线欧美| 伊人成人综合开心网| 在线国产日韩欧美视频| 极品粉嫩小泬白浆20p主播| 国产精品一区二区久久久av| 视频一区 视频二区 视频| 亚洲国产欧美一区二区三区久久 | 亚洲综合在线观看免费| 亚洲美女高潮喷浆视频| 三级黄色亚洲成人av| 亚洲欧美综合另类13p| 天天干天天操天天玩天天射| 熟女91pooyn熟女| 亚洲av成人免费网站| 亚洲精品国产在线电影| 女生自摸在线观看一区二区三区| 中文字幕奴隷色的舞台50| 男人插女人视频网站| 大香蕉伊人国产在线| 亚洲人妻av毛片在线| 精品成人啪啪18免费蜜臀| 91免费黄片可看视频| 婷婷久久久久深爱网| 好吊操视频这里只有精品| 国产在线一区二区三区麻酥酥| 99re久久这里都是精品视频| 91国产在线视频免费观看| 大香蕉玖玖一区2区| 91高清成人在线视频| 中文字幕高清在线免费播放| 快插进小逼里大鸡吧视频| 亚洲va天堂va国产va久| 国产亚洲视频在线二区| 国产男女视频在线播放| 97精品视频在线观看| 亚洲 欧美 精品 激情 偷拍| 在线免费观看欧美小视频| 欧美精品一二三视频| 精品一区二区三区在线观看| 狠狠操操操操操操操操操| 人妻久久无码中文成人| 中文字幕欧美日韩射射一| 精品久久婷婷免费视频| 人人妻人人爽人人澡人人精品| 日韩国产乱码中文字幕| 福利视频网久久91| 精品国产污污免费网站入口自| 2019av在线视频| 91www一区二区三区| 老有所依在线观看完整版| 在线观看的a站 最新| 亚洲一区二区三区uij| 91人妻人人做人人爽在线| 国产高清精品一区二区三区| 久久香蕉国产免费天天| 久久久久久久久久久免费女人| 无套猛戳丰满少妇人妻| 青青社区2国产视频| 亚洲人人妻一区二区三区| 在线成人日韩av电影| 国产aⅴ一线在线观看| 久久丁香花五月天色婷婷| 全国亚洲男人的天堂| 不卡日韩av在线观看| 久久久精品999精品日本| 国产精品视频男人的天堂| 熟妇一区二区三区高清版| 韩国女主播精品视频网站| 丰满熟女午夜福利视频| 久久www免费人成一看片| 成人蜜桃美臀九一一区二区三区 | 北条麻妃肉色丝袜视频| 日视频免费在线观看| 国产高清在线在线视频| 欧美成人一二三在线网| 亚洲精品欧美日韩在线播放| 99热久久极品热亚洲| 亚洲超碰97人人做人人爱| 欧美日本在线视频一区| 91成人在线观看免费视频| 亚洲精品无码久久久久不卡| 成人综合亚洲欧美一区 | 欲乱人妻少妇在线视频裸| 亚洲欧美清纯唯美另类| 女生被男生插的视频网站| 动漫美女的小穴视频| 亚洲成人午夜电影在线观看| 精品老妇女久久9g国产| 欧美成人综合视频一区二区| 中文字幕人妻av在线观看| 晚上一个人看操B片| 中文字幕在线一区精品| 丝袜美腿视频诱惑亚洲无| gogo国模私拍视频| 中文亚洲欧美日韩无线码| 自拍偷拍 国产资源| 老司机深夜免费福利视频在线观看| 免费观看成年人视频在线观看 | 亚洲人妻国产精品综合| 在线观看av2025| 肏插流水妹子在线乐播下载| 日本熟妇一区二区x x| 亚洲午夜电影在线观看| 国产亚洲国产av网站在线| 精品av国产一区二区三区四区| 日本欧美视频在线观看三区| a v欧美一区=区三区| 99的爱精品免费视频| 亚洲最大免费在线观看| 极品性荡少妇一区二区色欲| 日视频免费在线观看| 91精品一区二区三区站长推荐| 亚洲另类图片蜜臀av| 天天干天天操天天扣| 91成人在线观看免费视频| 美女福利视频导航网站| 国产一区自拍黄视频免费观看| 亚洲va欧美va人人爽3p| 亚洲1区2区3区精华液| 中文字幕高清免费在线人妻 | 欧美日本aⅴ免费视频| 夜夜骑夜夜操夜夜奸| 阿v天堂2014 一区亚洲| 亚洲 中文 自拍 无码| 巨乳人妻日下部加奈被邻居中出| 国产精彩对白一区二区三区 | 天天日天天添天天爽| 精品一区二区三区三区88| 熟女人妻一区二区精品视频| 日本一区二区三区免费小视频| 成人乱码一区二区三区av| 大黑人性xxxxbbbb| 人人妻人人爱人人草| 青青青青操在线观看免费| 91av精品视频在线| 亚洲 中文字幕在线 日韩| 中国视频一区二区三区| 动漫精品视频在线观看| 亚洲免费视频欧洲免费视频| 五十路在线观看完整版| 一区二区三区日本伦理| 亚洲免费va在线播放| 家庭女教师中文字幕在线播放| 521精品视频在线观看| 国产成人精品久久二区91| 91国产资源在线视频| 亚洲av在线观看尤物| 午夜精品一区二区三区城中村| 综合页自拍视频在线播放| 欧美一级色视频美日韩| 亚洲精品乱码久久久久久密桃明| 亚洲精品午夜久久久久| 日本高清在线不卡一区二区| 2012中文字幕在线高清| 亚洲av在线观看尤物| 欧美精品黑人性xxxx| 懂色av之国产精品| 男女之间激情网午夜在线| 亚洲中文字幕国产日韩| 国产亚洲视频在线二区| 水蜜桃一区二区三区在线观看视频 | 在线观看911精品国产| 啊啊啊视频试看人妻| 男生舔女生逼逼的视频| 亚洲少妇高潮免费观看| 91片黄在线观看喷潮| 日日夜夜大香蕉伊人| 成人久久精品一区二区三区| 国产成人精品亚洲男人的天堂| 亚洲国产成人最新资源| 免费男阳茎伸入女阳道视频| 欧美80老妇人性视频| 欧美爆乳肉感大码在线观看| 精品91自产拍在线观看一区| 午夜精品久久久久麻豆影视| 亚洲男人在线天堂网| www,久久久,com| 97精品视频在线观看| 丝袜长腿第一页在线| 欧美亚洲自偷自拍 在线| 国产超码片内射在线| 午夜精品福利一区二区三区p| 亚洲在线观看中文字幕av| 国产 在线 免费 精品| 最近中文2019年在线看| 青青草视频手机免费在线观看| 都市激情校园春色狠狠| 女生被男生插的视频网站| 国产一区二区欧美三区| 日韩美av高清在线| 精彩视频99免费在线| 亚洲av日韩av第一区二区三区| 岳太深了紧紧的中文字幕| 色伦色伦777国产精品| 五十路熟女人妻一区二区9933| 亚洲成人三级在线播放| 欧洲精品第一页欧洲精品亚洲| 日韩美av高清在线| 青娱乐最新视频在线| 亚洲成人熟妇一区二区三区| 黄网十四区丁香社区激情五月天| 99热这里只有国产精品6| 天堂av在线播放免费| 日本韩国免费一区二区三区视频 | 免费在线播放a级片| 国产精品三级三级三级| 日韩剧情片电影在线收看| 福利视频一区二区三区筱慧| av网站色偷偷婷婷网男人的天堂| 午夜的视频在线观看| 91久久国产成人免费网站| 亚洲精品ww久久久久久| 成年人该看的视频黄免费| jul—619中文字幕在线| 直接观看免费黄网站| 亚洲国产最大av综合| 美女日逼视频免费观看| 成年女人免费播放视频| 亚洲精品 日韩电影| 久久一区二区三区人妻欧美| 亚洲国产精品免费在线观看| 最新的中文字幕 亚洲| 粗大的内捧猛烈进出爽大牛汉子| 成人综合亚洲欧美一区| 日韩少妇人妻精品无码专区| 国产高清精品一区二区三区| 又粗又长 明星操逼小视频| 国产成人自拍视频播放| 国产夫妻视频在线观看免费 | 中文字幕日韩精品就在这里| 欧美中国日韩久久精品| 一区二区三区国产精选在线播放| av新中文天堂在线网址| 超碰在线中文字幕一区二区| 天堂av在线播放免费| 免费观看丰满少妇做受| 欧美亚洲牲夜夜综合久久| av在线播放国产不卡| 黄色男人的天堂视频| 91色秘乱一区二区三区| 亚洲国产第一页在线观看| 中文字幕免费福利视频6| 大香蕉日本伊人中文在线| 久久久久久久精品老熟妇| 亚洲综合图片20p| av在线播放国产不卡| 日本免费视频午夜福利视频| 成人亚洲国产综合精品| 中文字幕在线欧美精品| 亚洲精品av在线观看| 亚洲av色图18p| 欧美另类一区二区视频| 视频一区 二区 三区 综合| 欧美偷拍亚洲一区二区| 久久久麻豆精亚洲av麻花| 91she九色精品国产| 夜夜骑夜夜操夜夜奸| 亚洲国产精品美女在线观看| 黄色中文字幕在线播放| 国产亚洲视频在线二区| 2022天天干天天操| 91破解版永久免费| av一区二区三区人妻| 国产成人精品一区在线观看| 91免费观看在线网站| 青草久久视频在线观看| 欧美地区一二三专区| 我想看操逼黄色大片| 亚洲区美熟妇久久久久| 欧美精品国产综合久久| 国产黄色a级三级三级三级| 天天日天天干天天插舔舔| 五十路熟女av天堂| 成人久久精品一区二区三区| 丝袜美腿视频诱惑亚洲无| 人妻熟女在线一区二区| 大骚逼91抽插出水视频| 狠狠躁狠狠爱网站视频| 一个人免费在线观看ww视频| 国产成人精品一区在线观看 | 色偷偷伊人大杳蕉综合网| 亚洲av色香蕉一区二区三区| 五十路息与子猛烈交尾视频| 欧美性受xx黑人性猛交| 日韩二区视频一线天婷婷五| 玖玖一区二区在线观看| 扒开腿挺进肉嫩小18禁视频| 亚洲欧美综合在线探花| 涩爱综合久久五月蜜臀| 国产一区二区在线欧美| 日本在线不卡免费视频| chinese国产盗摄一区二区 | 人妻3p真实偷拍一二区| 一本久久精品一区二区| 天天射夜夜操狠狠干| 亚洲男人让女人爽的视频| 日韩av免费观看一区| 日韩精品中文字幕福利| 午夜婷婷在线观看视频| 免费岛国喷水视频在线观看| japanese日本熟妇另类| 午夜福利资源综合激情午夜福利资| 天天艹天天干天天操| 91福利在线视频免费观看| 美女少妇亚洲精选av| 色97视频在线播放| 久久久久久久精品老熟妇| 九色视频在线观看免费| 亚洲成人国产av在线| 国产精品视频欧美一区二区| 自拍偷拍一区二区三区图片| 岛国黄色大片在线观看| 国产超码片内射在线| 欧美美女人体视频一区| av在线播放国产不卡| 午夜精品一区二区三区4| 亚洲激情av一区二区| 亚洲精品国产综合久久久久久久久| 啊慢点鸡巴太大了啊舒服视频| 亚洲 人妻 激情 中文| 91久久人澡人人添人人爽乱| 五月精品丁香久久久久福利社 | 国产 在线 免费 精品| 国产高清精品极品美女| 黄色中文字幕在线播放| 5528327男人天堂| 亚洲欧美激情人妻偷拍| 中文字幕国产专区欧美激情| 中文字幕一区二 区二三区四区| 美女被肏内射视频网站| 国产黄色a级三级三级三级| 色av色婷婷人妻久久久精品高清| 欧美一级片免费在线成人观看| 任我爽精品视频在线播放| 精品一区二区三区欧美| 99国内小视频在现欢看| 久久99久久99精品影院| 无码精品一区二区三区人| 国产又粗又硬又大视频| 亚洲一区二区人妻av| 欧美另类重口味极品在线观看| 亚洲熟妇x久久av久久| 91国语爽死我了不卡| 国产激情av网站在线观看| av中文在线天堂精品| 91免费观看在线网站| 91精品视频在线观看免费| 日本少妇高清视频xxxxx| 亚洲av琪琪男人的天堂| 一色桃子人妻一区二区三区| 激情小视频国产在线| 新婚人妻聚会被中出| 蜜桃精品久久久一区二区| 国产福利小视频二区| 成熟熟女国产精品一区| 免费男阳茎伸入女阳道视频 | 久久机热/这里只有| 日本黄色特一级视频| 亚洲精品乱码久久久本| 免费费一级特黄真人片| 99的爱精品免费视频| 91人妻精品久久久久久久网站| 亚洲精品国品乱码久久久久| 欧美黄色录像免费看的| 精品人妻每日一部精品| v888av在线观看视频| 天天操天天爽天天干| 性感美女高潮视频久久久 | 青青青爽视频在线播放| 国产真实乱子伦a视频 | 国产内射中出在线观看| 日本午夜爽爽爽爽爽视频在线观看| 97人人妻人人澡人人爽人人精品| 视频 国产 精品 熟女 | 18禁网站一区二区三区四区| 亚洲码av无色中文| 一区二区三区久久中文字幕| 欧美一级视频一区二区| 国产精品手机在线看片| 青青青爽视频在线播放| 国产实拍勾搭女技师av在线| 91免费福利网91麻豆国产精品 | 精品一区二区亚洲欧美| 国产又色又刺激在线视频| 亚洲av日韩av网站| 偷拍自拍国产在线视频| 91桃色成人网络在线观看| 日韩伦理短片在线观看| 丝袜肉丝一区二区三区四区在线| 欧美精产国品一二三产品价格| 夜夜嗨av一区二区三区中文字幕| 老师啊太大了啊啊啊尻视频| 中文字幕亚洲久久久| 精品日产卡一卡二卡国色天香 | 久久久久久国产精品| 黑人性生活视频免费看| 亚洲天堂第一页中文字幕| 国产夫妻视频在线观看免费| 2022国产综合在线干| 亚洲 欧美 精品 激情 偷拍| 97a片免费在线观看| 2022国产综合在线干| 新97超碰在线观看| 香蕉91一区二区三区| 91 亚洲视频在线观看| 97a片免费在线观看| 日本五十路熟新垣里子| 成人精品视频99第一页| 在线观看的黄色免费网站| 老司机福利精品免费视频一区二区| 久久久超爽一二三av| 午夜久久久久久久99| 护士特殊服务久久久久久久| 女警官打开双腿沦为性奴| 久久一区二区三区人妻欧美| 免费一级黄色av网站| 少妇被强干到高潮视频在线观看| 亚洲激情偷拍一区二区| 亚洲av人人澡人人爽人人爱| 91综合久久亚洲综合| 亚洲成人激情av在线| 欧美女同性恋免费a| 动漫黑丝美女的鸡巴| 青青青青青手机视频| 亚洲中文字幕国产日韩| 五月天色婷婷在线观看视频免费| 在线观看免费岛国av| 国产黄色高清资源在线免费观看| 香蕉aⅴ一区二区三区| 开心 色 六月 婷婷| 日韩人妻xxxxx| 中文字幕高清在线免费播放| 亚洲 国产 成人 在线| 北条麻妃高跟丝袜啪啪| av新中文天堂在线网址| 99精品亚洲av无码国产另类| 青青伊人一精品视频| 免费在线观看污污视频网站| 99热色原网这里只有精品| 亚洲老熟妇日本老妇| 亚洲精品一区二区三区老狼| 一区二区三区美女毛片| 国产视频在线视频播放| 亚洲成人av一区在线| 少妇深喉口爆吞精韩国| 93精品视频在线观看| 色哟哟在线网站入口| 91精品高清一区二区三区| 深田咏美亚洲一区二区| 在线视频国产欧美日韩| 久久h视频在线观看| 美女av色播在线播放| 国产一区二区视频观看| 欧美 亚洲 另类综合| 青青在线视频性感少妇和隔壁黑丝 | 国产精品熟女久久久久浪潮| 好男人视频在线免费观看网站| 精品国产乱码一区二区三区乱| 人人爽亚洲av人人爽av| av在线shipin| 啊啊好大好爽啊啊操我啊啊视频 | 欧美精产国品一二三产品价格| 国产亚洲欧美另类在线观看| 93精品视频在线观看| 日本人竟这样玩学生妹| 欧美一区二区三区高清不卡tv| 国产麻豆剧果冻传媒app| 国产精品人妻一区二区三区网站| av中文字幕网址在线| 亚洲高清国产拍青青草原| 天天日天天干天天要| 国产日韩一区二区在线看| 久久www免费人成一看片| 大鸡巴操娇小玲珑的女孩逼| 日韩二区视频一线天婷婷五| 特级无码毛片免费视频播放| 大肉大捧一进一出好爽在线视频| 91九色porny国产蝌蚪视频| 五十路熟女人妻一区二| 欧美特级特黄a大片免费| 亚洲图片偷拍自拍区| 亚洲av午夜免费观看| av乱码一区二区三区| 国产九色91在线视频| 国产实拍勾搭女技师av在线| 性感美女高潮视频久久久| www久久久久久久久久久| 91亚洲手机在线视频播放| 亚洲欧美国产综合777| 一级黄色片夫妻性生活| 老司机免费视频网站在线看| 激情色图一区二区三区| 日韩欧美一级精品在线观看| 大黑人性xxxxbbbb| 日本a级视频老女人| 国产精品大陆在线2019不卡| 夜女神免费福利视频| 天天操天天弄天天射| 少妇人妻久久久久视频黄片| 国产一区二区火爆视频| 亚洲人一区二区中文字幕| 亚洲天堂精品久久久| 91精品国产高清自在线看香蕉网| av无限看熟女人妻另类av| av视屏免费在线播放| 亚洲国产欧美国产综合在线| 色综合久久久久久久久中文| 亚洲欧美成人综合在线观看| 在线免费观看亚洲精品电影| 丝袜长腿第一页在线| 成年人午夜黄片视频资源| 一区二区三区视频,福利一区二区| 日韩美女精品视频在线观看网站 | 国产精品女邻居小骚货| 日本脱亚入欧是指什么| 特级欧美插插插插插bbbbb| 中文字幕无码一区二区免费| 中国黄色av一级片| 日韩写真福利视频在线观看| 69精品视频一区二区在线观看| 亚洲天堂精品福利成人av| 日韩不卡中文在线视频网站| 少妇被强干到高潮视频在线观看| 97人人模人人爽人人喊| 欧美日本国产自视大全| 91国内精品久久久久精品一| 精品亚洲在线免费观看| 天天日天天舔天天射进去| 美女小视频网站在线| 香港三日本三韩国三欧美三级| 欧美另类重口味极品在线观看| 亚洲精品久久综合久| 亚洲综合色在线免费观看| 免费黄高清无码国产| 国产精品自拍在线视频| 久久久久久久精品成人热| 91精品国产黑色丝袜| 天天摸天天干天天操科普| 亚洲少妇高潮免费观看| 97精品成人一区二区三区 | 中文字幕在线永久免费播放| 2022国产精品视频| 新97超碰在线观看| 亚洲国产在线精品国偷产拍| 97人人妻人人澡人人爽人人精品| 美味人妻2在线播放| 人妻少妇亚洲一区二区| 免费人成黄页网站在线观看国产| 日韩精品中文字幕福利| 亚洲av琪琪男人的天堂| 不卡一区一区三区在线| 噜噜色噜噜噜久色超碰| 激情五月婷婷综合色啪| av久久精品北条麻妃av观看| 欧美亚洲免费视频观看| 在线网站你懂得老司机| 欧美一区二区三区久久久aaa| 亚洲av在线观看尤物| 日韩人妻丝袜中文字幕| 国产污污污污网站在线| 极品性荡少妇一区二区色欲| 国产亚洲精品视频合集| 人妻丰满熟妇综合网| 最新91精品视频在线| 欧美亚洲自偷自拍 在线| 天天日天天舔天天射进去| 久久国产精品精品美女| 久久永久免费精品人妻专区| 美女被肏内射视频网站| 国产高潮无码喷水AV片在线观看| 日本高清成人一区二区三区| 内射久久久久综合网| 色综合久久无码中文字幕波多| 1000小视频在线| 国产黄色片蝌蚪九色91| 国产成人一区二区三区电影网站| 亚洲中文字字幕乱码| 中文字母永久播放1区2区3区| 蜜臀av久久久久久久| 日本高清成人一区二区三区| 一色桃子久久精品亚洲 | 国产janese在线播放| 中文字幕乱码av资源| 午夜精品一区二区三区福利视频| 欧美老妇精品另类不卡片| 久精品人妻一区二区三区| 色av色婷婷人妻久久久精品高清| 亚洲天堂第一页中文字幕| 国产精品中文av在线播放| 亚洲男人在线天堂网| 首之国产AV医生和护士小芳| 动漫黑丝美女的鸡巴| 欧美精品亚洲精品日韩在线| 久久精品国产亚洲精品166m| 日本高清在线不卡一区二区| 国产又粗又黄又硬又爽| 粉嫩小穴流水视频在线观看| 青青伊人一精品视频| 天天摸天天干天天操科普| 国产福利小视频二区| 狠狠鲁狠狠操天天晚上干干| 人妻素人精油按摩中出| 爆乳骚货内射骚货内射在线| 免费人成黄页网站在线观看国产| 亚洲中文字幕综合小综合| 女同性ⅹxx女同h偷拍| 在线观看视频污一区| 国产成人精品av网站| 伊人日日日草夜夜草| 日韩人妻丝袜中文字幕| 欧美综合婷婷欧美综合| 亚洲国产成人最新资源| chinese国产盗摄一区二区| 国产精品伦理片一区二区| h国产小视频福利在线观看| 亚洲专区激情在线观看视频| 日本最新一二三区不卡在线| 欧美精品亚洲精品日韩在线| 91精品一区二区三区站长推荐| 精品91自产拍在线观看一区| 亚洲精品国品乱码久久久久| 阴茎插到阴道里面的视频| 亚洲欧美一区二区三区电影| 亚洲成人av在线一区二区| 老熟妇xxxhd老熟女| 日本www中文字幕| 伊人成人综合开心网| 亚洲男人在线天堂网| 天天干狠狠干天天操| 区一区二区三国产中文字幕| 日韩美女综合中文字幕pp| 亚洲熟女久久久36d| 天天躁夜夜躁日日躁a麻豆| 伊拉克及约旦宣布关闭领空| 亚洲另类综合一区小说| 粉嫩av蜜乳av蜜臀| 在线视频这里只有精品自拍| 岛国毛片视频免费在线观看| 亚洲av日韩精品久久久久久hd| 亚洲中文精品字幕在线观看| 男生用鸡操女生视频动漫 | 一区二区三区四区视频在线播放| 少妇人妻真实精品视频| 激情图片日韩欧美人妻| 中文字幕第一页国产在线| 大香蕉伊人国产在线| 国产高清97在线观看视频| 日韩二区视频一线天婷婷五| 欧美交性又色又爽又黄麻豆| 2018在线福利视频| 水蜜桃国产一区二区三区| 中文字幕日韩91人妻在线| 日韩三级电影华丽的外出| 日韩欧美一级精品在线观看| 精品国产亚洲av一淫| 亚洲免费视频欧洲免费视频| 爆乳骚货内射骚货内射在线| 久久尻中国美女视频| 久久久久久99国产精品| 丁香花免费在线观看中文字幕| 亚洲一级av无码一级久久精品| 久久永久免费精品人妻专区| 人妻激情图片视频小说| 日本a级视频老女人| 激情图片日韩欧美人妻| 国产欧美日韩第三页| 美女骚逼日出水来了| 国产精品sm调教视频| 专门看国产熟妇的网站| 日本性感美女写真视频| 欧洲日韩亚洲一区二区三区| 美女 午夜 在线视频 | 男人插女人视频网站| 久久香蕉国产免费天天| 午夜精品亚洲精品五月色| 欧美日韩国产一区二区三区三州 | 亚洲精品欧美日韩在线播放| 都市激情校园春色狠狠| 欧美亚洲少妇福利视频| 大鸡八强奸视频在线观看| 中文字幕综合一区二区| 大陆胖女人与丈夫操b国语高清| 欧美成人一二三在线网| 黄片色呦呦视频免费看| 91免费黄片可看视频| 91色秘乱一区二区三区| 蝴蝶伊人久久中文娱乐网| 蝴蝶伊人久久中文娱乐网| 欧美va不卡视频在线观看| 人妻爱爱 中文字幕| 年轻的人妻被夫上司侵犯| 中文字幕日韩人妻在线三区| 欧美香蕉人妻精品一区二区| 91成人在线观看免费视频| 亚洲精品 欧美日韩| 沙月文乃人妻侵犯中文字幕在线 | 91免费观看在线网站| 丁香花免费在线观看中文字幕| 欧美精品欧美极品欧美视频 | 国产janese在线播放| 1000部国产精品成人观看视频| 国产黄色高清资源在线免费观看| 亚洲综合图片20p| 100%美女蜜桃视频| 国产揄拍高清国内精品对白| 中国熟女@视频91| 亚洲国产欧美一区二区丝袜黑人| 国产成人精品午夜福利训2021| 天堂av在线播放免费| 日本一道二三区视频久久| 青青青国产免费视频| 色秀欧美视频第一页| 久草极品美女视频在线观看| 国产三级精品三级在线不卡| 亚洲精品国产在线电影| 成年人免费看在线视频| 天天色天天操天天舔| 中国视频一区二区三区| 国产亚州色婷婷久久99精品| 亚洲精品ww久久久久久| 久草视频首页在线观看| 夜夜躁狠狠躁日日躁麻豆内射 | 人妻爱爱 中文字幕| 亚洲一区自拍高清免费视频| 欧美成人精品欧美一级黄色| 绝色少妇高潮3在线观看| 97精品视频在线观看| 一区二区三区四区视频| 亚洲欧美人精品高清| 亚洲精品久久综合久| 国产伦精品一区二区三区竹菊| 99亚洲美女一区二区三区| 97瑟瑟超碰在线香蕉| 中文字幕 亚洲av| 狠狠躁夜夜躁人人爽天天久天啪| 国产午夜亚洲精品不卡在线观看| 熟女国产一区亚洲中文字幕| 久久久久久久久久一区二区三区 | 日韩a级精品一区二区| 麻豆精品成人免费视频| 沈阳熟妇28厘米大战黑人| 这里只有精品双飞在线播放| 99人妻视频免费在线| 亚洲人一区二区中文字幕| 91老熟女连续高潮对白| 亚洲 中文 自拍 另类 欧美| 青青草亚洲国产精品视频| 国产精品日韩欧美一区二区| 偷拍美女一区二区三区| 姐姐的朋友2在线观看中文字幕| 午夜在线观看岛国av,com| 欧美黑人巨大性xxxxx猛交| 日韩三级电影华丽的外出| 东京干手机福利视频| 五十路熟女av天堂| 日韩近亲视频在线观看| 免费无毒热热热热热热久| 人妻丰满熟妇综合网| 人人超碰国字幕观看97| 青青在线视频性感少妇和隔壁黑丝 | 丝袜长腿第一页在线| 在线免费观看国产精品黄色| 精品区一区二区三区四区人妻| 欧美男同性恋69视频| av在线免费资源站| 伊拉克及约旦宣布关闭领空| 久草视频在线免播放| 3337p日本欧洲大胆色噜噜| 日韩精品一区二区三区在线播放 | 80电影天堂网官网| 久久www免费人成一看片| 亚洲在线观看中文字幕av| 又粗又硬又猛又黄免费30| 亚洲人妻av毛片在线| 亚洲护士一区二区三区| 中文字幕亚洲中文字幕| 久久久久久久久久一区二区三区 | 国产女人被做到高潮免费视频| 国产精品久久久久久美女校花| 亚洲美女自偷自拍11页| 欧洲国产成人精品91铁牛tv| 天码人妻一区二区三区在线看| 男人天堂最新地址av| 在线观看视频污一区| 亚洲精品欧美日韩在线播放| 亚洲高清一区二区三区视频在线| 久久这里有免费精品| 亚洲色偷偷综合亚洲AV伊人| 日本18禁久久久久久| 91精品一区二区三区站长推荐| 边摸边做超爽毛片18禁色戒| 成人性黑人一级av| av手机免费在线观看高潮| 最新黄色av网站在线观看| 黑人大几巴狂插日本少妇| 99av国产精品欲麻豆| 黑人巨大精品欧美视频| 色狠狠av线不卡香蕉一区二区| 国产精品精品精品999| 国产一区二区火爆视频| 专门看国产熟妇的网站| 红桃av成人在线观看| 久久久久久久久久一区二区三区| 美女福利视频网址导航| 好太好爽好想要免费| 97精品成人一区二区三区| 成人av免费不卡在线观看| 91精品视频在线观看免费| 2022国产精品视频| 91久久综合男人天堂| 青青青爽视频在线播放| 成人在线欧美日韩国产| 少妇人妻二三区视频| 1024久久国产精品| 天天做天天干天天舔| 中文字幕熟女人妻久久久| 日本熟女精品一区二区三区| 欧美精品一区二区三区xxxx| 亚洲欧美另类手机在线| 中文亚洲欧美日韩无线码| 日韩精品中文字幕在线| 亚洲av人人澡人人爽人人爱| 国产成人一区二区三区电影网站| 亚洲国产精品免费在线观看| 中文字幕一区二区三区人妻大片| 这里只有精品双飞在线播放| av一本二本在线观看| 日本av高清免费网站| 亚洲超碰97人人做人人爱| 国产97视频在线精品| 成人av亚洲一区二区| 91‖亚洲‖国产熟女| 天天射夜夜操狠狠干| 成人国产影院在线观看| av欧美网站在线观看| 精品亚洲国产中文自在线| 亚洲av午夜免费观看| 日视频免费在线观看| 欧美一区二区中文字幕电影| 丰满少妇翘臀后进式| 自拍偷拍一区二区三区图片| 色呦呦视频在线观看视频| 4个黑人操素人视频网站精品91| 亚洲成a人片777777| 蜜桃视频在线欧美一区| 亚洲国产最大av综合| 国产成人精品一区在线观看| av日韩在线免费播放| caoporm超碰国产| 97欧洲一区二区精品免费| 久草视频在线看免费| 制服丝袜在线人妻中文字幕| 大鸡吧插入女阴道黄色片| 久草免费人妻视频在线| 成人av亚洲一区二区| 大香蕉伊人国产在线| 一区二区三区四区视频在线播放| 男生舔女生逼逼的视频| 精品美女在线观看视频在线观看| wwwxxx一级黄色片| 精品久久久久久久久久久a√国产 日本女大学生的黄色小视频 | 一区二区视频视频视频| 亚洲免费国产在线日韩| 中文字幕在线视频一区二区三区| 丝袜美腿视频诱惑亚洲无| 国产乱弄免费视频观看| 亚洲一区二区三区五区| 中国无遮挡白丝袜二区精品| 国产91久久精品一区二区字幕| 国产精品视频资源在线播放| 久久久人妻一区二区| 摧残蹂躏av一二三区| 99一区二区在线观看| 国产综合精品久久久久蜜臀| 色97视频在线播放| 最新91九色国产在线观看| 九色porny九色9l自拍视频| 粉嫩小穴流水视频在线观看| 伊人开心婷婷国产av| 亚洲 国产 成人 在线| 日韩剧情片电影在线收看| 在线观看av观看av| 亚洲第17页国产精品| 日韩美av高清在线| 欧美偷拍亚洲一区二区| 国产亚洲视频在线二区| 扒开让我视频在线观看| 超级福利视频在线观看| 端庄人妻堕落挣扎沉沦| 男人操女人的逼免费视频| 亚洲熟女综合色一区二区三区四区| 国产a级毛久久久久精品| 香港三日本三韩国三欧美三级| 蜜桃视频17c在线一区二区| 国内精品在线播放第一页| 91快播视频在线观看| 欧美日本在线视频一区| 91国产在线免费播放| 黄色成人在线中文字幕| 欧美乱妇无乱码一区二区| 亚洲一级av大片免费观看| 91 亚洲视频在线观看| 91精品高清一区二区三区| 1000部国产精品成人观看视频| 嫩草aⅴ一区二区三区| 岛国毛片视频免费在线观看| 黄色黄色黄片78在线| 色97视频在线播放| 亚洲天堂精品久久久| 中国视频一区二区三区| 一级黄片大鸡巴插入美女| 中文字幕日本人妻中出| 丰满熟女午夜福利视频| 91精品视频在线观看免费| 91人妻人人做人人爽在线| 99精品国产aⅴ在线观看| 亚洲精品av在线观看| 伊人情人综合成人久久网小说| 熟女少妇激情五十路| eeuss鲁片一区二区三区| 馒头大胆亚洲一区二区| 在线播放国产黄色av| 大陆胖女人与丈夫操b国语高清| 亚洲国产成人最新资源| 91欧美在线免费观看| 亚洲狠狠婷婷综合久久app| 5528327男人天堂| 日本最新一二三区不卡在线| 人人超碰国字幕观看97| 91免费观看在线网站 | 久久久久久久精品成人热| 中文字幕在线观看极品视频| 三级等保密码要求条款| 日韩av免费观看一区| 51国产偷自视频在线播放| 久久精品亚洲成在人线a| 97色视频在线观看| 亚洲高清视频在线不卡| 日本熟妇色熟妇在线观看| av在线免费中文字幕| 97精品人妻一区二区三区精品| 日本男女操逼视频免费看| 亚洲精品乱码久久久本| 人妻丝袜诱惑我操她视频| 5528327男人天堂| 91极品大一女神正在播放| 亚洲美女自偷自拍11页| 老司机欧美视频在线看| 热思思国产99re| 五月天久久激情视频| 国产97在线视频观看| 白白操白白色在线免费视频| 后入美女人妻高清在线| 偷拍自拍视频图片免费| 日本少妇精品免费视频| av中文字幕网址在线| 高清一区二区欧美系列| 国产午夜亚洲精品不卡在线观看| 免费无码人妻日韩精品一区二区| 操人妻嗷嗷叫视频一区二区 |