ATS写文件
與讀緩存類似,寫緩存也有大文件小文件的區(qū)分,這里先討論寫小文件。大致的思想就是將CacheVC::blocks中的數(shù)據(jù)拷貝到agg_buf中,整個(gè)流程如下:
Cache::open_write: 根據(jù)key生成一個(gè)新key作為earliest_key,不過(guò)小文件的話貌似earlist_key沒(méi)用。根據(jù)CacheV->first_key計(jì)算的到vol。執(zhí)行Vol::open_write,在Vol::open_write中進(jìn)行了簡(jiǎn)單的aggregation buf的錯(cuò)誤檢查就執(zhí)行了OpenDir::open_write。最后將CacheVC::openWriteMain設(shè)置為回調(diào)函數(shù),流程結(jié)束。
OpenDir::open_write: 根據(jù)first_key計(jì)算bucket,原理就是最低32位處以bucket數(shù)量然后取余。遍歷這個(gè)bucket所有的位置看是否已經(jīng)有寫操作了,如果沒(méi)有的話,新建一個(gè)OpenDirEntry對(duì)象并且放倒bucket中
CacheVC::openWriteMain: 設(shè)置讀寫相關(guān)的字節(jié)數(shù),將資源在reader中consume掉,向continuation發(fā)送VC_EVENT_WRITE_COMPLETE信號(hào)
CacheVC::die: 設(shè)置回調(diào)函數(shù)為CacheVC::openWriteClose并執(zhí)行
CacheVC::openWriteClose: 執(zhí)行openWriteCloseHead
CacheVC::openWriteCloseHead: 設(shè)置回調(diào)函數(shù)為CacheVC::updateVector,并執(zhí)行
CacheVC::updateVector: 設(shè)置了回調(diào)函數(shù)為CacheVC::openWriteCloseHeadDone,執(zhí)行CacheVC::do_write_call。
CacheVC::do_write_call函數(shù)對(duì)回調(diào)函數(shù)執(zhí)行了push操作,CacheVC::handleWrite函數(shù)又執(zhí)行了pop操作。CacheVC::do_write_call最終返回了EVENT_RETURN,CacheVC::updateVector函數(shù)最后會(huì)執(zhí)行回調(diào)函數(shù)CacheVC::openWriteCloseHeadDone。
CacheVC::handleWrite: 將回調(diào)函數(shù)POP出。計(jì)算大概大小,將CacheVC對(duì)象加入到vol->agg中,vol->agg是一個(gè)隊(duì)列,每個(gè)元素就是一個(gè)寫緩存的CacheVC。判斷是否已經(jīng)有io操作正在進(jìn)行了,如果沒(méi)有,直接執(zhí)行Vol::aggWrite
Vol::aggWrite: 循環(huán)遍歷vol->agg隊(duì)列,判斷agg_buf是否還能裝下當(dāng)前的資源,如果可以裝下,執(zhí)行agg_copy,將CacheVC從vol->agg中刪除。
agg_copy: 設(shè)置dir的各個(gè)bit,初始化vc->dir各個(gè)bit。一開(kāi)始將一個(gè)Doc類型指針指向agg_buf,并對(duì)這個(gè)Doc進(jìn)行初始化。執(zhí)行iobufferblock_memcpy,將vc中的內(nèi)從拷貝到doc->data()。
CacheVC::openWriteCloseHeadDone: 執(zhí)行了dir_insert函數(shù),dir_insert函數(shù)中在特定的segment的特定的bucket中找一個(gè)位置放置這個(gè)資源的dir。最后執(zhí)行CacheVC::openWriteCloseDir
dir_insert: 通過(guò)key找到對(duì)應(yīng)的bucket,在freelist中找到一個(gè)位置,將dir放進(jìn)去。
CacheVC::openWriteCloseDir: 做一些善后工作,釋放CacheVC的資源。
對(duì)于寫大文件,CacheVC::openWriteMain處理的邏輯有一些不同,具體如下:
CacheVC::openWriteMain: 會(huì)執(zhí)行若干次,每次會(huì)對(duì)vio中的數(shù)據(jù)做一些處理,主要是初始化CacheVC::blocks,標(biāo)記一些已經(jīng)處理過(guò)的數(shù)據(jù)長(zhǎng)度,本次處理的數(shù)據(jù)長(zhǎng)度。如果攢夠了一個(gè)fragment的長(zhǎng)度,就寫到agg_buf中,并且開(kāi)始處理下一個(gè)fragment的數(shù)據(jù)。CacheVC::openWriteMain函數(shù)中并沒(méi)有實(shí)現(xiàn)數(shù)據(jù)的拷貝。
CacheVC::openWriteWriteDone:每個(gè)fragment數(shù)據(jù)處理完了會(huì)執(zhí)行這個(gè)函數(shù)。函數(shù)執(zhí)行了iobufferblock_skip,因?yàn)槊看位叵騛gg_buf中寫一個(gè)fragment那么多數(shù)據(jù),但是執(zhí)行CacheVC::openWriteWriteDone時(shí)已經(jīng)處理過(guò)的數(shù)據(jù)可能大于一個(gè)fragment的長(zhǎng)度,所以需要重新計(jì)算CacheVC::length。獲取了下一個(gè)key,將回調(diào)函數(shù)設(shè)置為CacheVC::openWriteMain并執(zhí)行。
轉(zhuǎn)載于:https://blog.51cto.com/11490450/1876682
總結(jié)
- 上一篇: ceph对象存储折腾记
- 下一篇: 说说JavaScriptCore