系列文章:
void mmkv::loadfromfile
() m_metainfo.read(m_metafile.getmemory());
/* o_rdwr:讀、寫開啟
* o_creat:若此檔案不存在則建立它。使用此選擇項時,需同時說明第三個引數mode,用其說明該新檔案的訪問許可權位。
* s_irwxu:模式標誌:由使用者讀,寫,執行。
*/m_fd = open(m_path.c_str(), o_rdwr | o_creat, s_irwxu);
if (m_fd < 0) else ;
// 讀取檔案的大小
if (fstat(m_fd, &st) != -1)
// 對齊操作,mmap的使用要求
// round up to (n * pagesize)
if (m_size < default_mmap_size || (m_size % default_mmap_size != 0))
zerofillfile(m_fd, oldsize, m_size - oldsize);
}// mmkv的核心之一,使用mmap函式的map_shared來實現檔案和記憶體形成對映,只要修改記憶體的資料,這個函式會自動的幫我們寫到檔案裡,非常好用。
m_ptr = (char *) mmap(nullptr, m_size, prot_read | prot_write, map_shared, m_fd, 0);
if (m_ptr == map_failed) else
// 將記憶體的資料反序列化到map裡,m_dic是個map
m_dic = minipbcoder::decodemap(inputbuffer);
m_output = new codedoutputdata(m_ptr + fixed32size + m_actualsize,
m_size - fixed32size - m_actualsize);
loaded = true;}}
}if (!loaded)
m_output = new codedoutputdata(m_ptr + fixed32size, m_size - fixed32size);
recaculatecrcdigest();
}mmkvinfo("loaded [%s] with %zu values", m_mmapid.c_str(), m_dic.size());}}
if (!isfilevalid())
m_needloadfromfile = false;
}複製**
mmap函式是mmkv的乾貨之一了,如果沒有這個函式的存在,或許就沒有今天的mmkv了,下面說下這個函式的引數和使用方法。
mmap (一種記憶體對映檔案的方法)
mmap將乙個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後乙個頁不被使用的空間將會清零。mmap在使用者空間對映呼叫系統中作用很大。
標頭檔案
函式原型
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
length:對映區的長度。傳入檔案對齊後的大小m_size。
prot:期望的記憶體保護標誌,不能與檔案的開啟模式衝突。設定可讀可寫。
flags:指定對映物件的型別,對映選項和對映頁是否可以共享。設定map_shared表示可程序共享,mmkv之所以可以實現跨程序使用,這裡是關鍵。
fd:有效的檔案描述詞。用上面所開啟的m_fd。
off_toffset:被對映物件內容的起點。從頭開始,比較好理解。
在跨程序讀寫的時候,程序a修改了乙個資料,程序b去讀的時候,就會校驗記憶體的資料和檔案的資料,一旦不相同,就說明有了跨程序的操作,這個時候就需要記憶體重組,清空原有資料,重新讀最新的檔案對映到記憶體中。
void mmkv::checkloaddata
() if (!m_isinterprocess)
// todo: atomic lock m_metafile?
mmkvmetainfo metainfo;
// 讀取檔案的狀態
metainfo.read(m_metafile.getmemory());
// 對比檔案和記憶體的讀寫操作次數,次數不一樣,說明跨程序操作了,清空下原資料,再載入新資料
if (m_metainfo.m_sequence != metainfo.m_sequence)
// 比較下crc校驗碼
else
if (m_metainfo.m_crcdigest != metainfo.m_crcdigest) else ;
if (fstat(m_fd, &st) != -1)
}if (m_size != filesize) else
}}複製**
記憶體重組涉及到跨程序操作,跨程序的原理在後續文章再詳細講解。
關於crc32校驗,看《crc32加密演算法原理》
如果本文對您有用的話,記得點乙個贊哦!
PHP實現微信退款的分析與原始碼實現
原文 需要注意的事項 4.錯誤碼參照 如下 2.錯誤碼參照 header content type text html charset utf 8 mchid xx apikey xx 帳戶設定 安全設定 api安全 api金鑰 設定api金鑰 orderno wxorderno totalfee ...
PHP實現微信退款的分析與原始碼實現
原文 需要注意的事項 4.錯誤碼參照 如下 2.錯誤碼參照 header content type text html charset utf 8 mchid xx apikey xx 帳戶設定 安全設定 api安全 api金鑰 設定api金鑰 orderno wxorderno totalfee ...
二 LinkedList原始碼分析
二 linkedlist原始碼分析 上篇看了下arraylist原始碼,這篇記錄下linkedlist原始碼分析 linkedlist 繼承 abstractsequentiallist 提供了對元素順序訪問的抽象 linkedlist 實現 deque介面,底層構成雙向鍊錶結構 linkedlis...