mirror of
https://github.com/Tencent/MMKV.git
synced 2026-10-17 04:30:56 +08:00
add readonly support
This commit is contained in:
+22
-11
@@ -43,7 +43,7 @@ File::File(MMKVPath_t path, OpenFlag flag) : m_path(std::move(path)), m_fd(INVAL
|
||||
|
||||
static pair<int, int> OpenFlag2NativeFlag(OpenFlag flag) {
|
||||
int access = 0, create = OPEN_EXISTING;
|
||||
if (flag & OpenFlag::ReadWrite) {
|
||||
if ((flag & OpenFlagRWMask) == OpenFlag::ReadWrite) {
|
||||
access = (GENERIC_READ | GENERIC_WRITE);
|
||||
} else if (flag & OpenFlag::ReadOnly) {
|
||||
access |= GENERIC_READ;
|
||||
@@ -70,10 +70,10 @@ bool File::open() {
|
||||
m_fd = CreateFile(m_path.c_str(), pair.first, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
|
||||
pair.second, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (!isFileValid()) {
|
||||
MMKVError("fail to open:[%ls], %d", m_path.c_str(), GetLastError());
|
||||
MMKVError("fail to open:[%ls], flag %x, error %d", m_path.c_str(), m_flag, GetLastError());
|
||||
return false;
|
||||
}
|
||||
MMKVInfo("open fd[%p], %ls", m_fd, m_path.c_str());
|
||||
MMKVInfo("open fd[%p], flag %x, %ls", m_fd, m_flag, m_path.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -94,11 +94,12 @@ size_t File::getActualFileSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
MemoryFile::MemoryFile(MMKVPath_t path, size_t expectedCapacity)
|
||||
: m_diskFile(std::move(path), OpenFlag::ReadWrite | OpenFlag::Create)
|
||||
MemoryFile::MemoryFile(MMKVPath_t path, size_t expectedCapacity, bool readOnly)
|
||||
: m_diskFile(std::move(path), readOnly ? OpenFlag::ReadOnly : (OpenFlag::ReadWrite | OpenFlag::Create))
|
||||
, m_fileMapping(nullptr)
|
||||
, m_ptr(nullptr)
|
||||
, m_size(0) {
|
||||
, m_size(0)
|
||||
, m_readOnly(readOnly) {
|
||||
reloadFromFile(expectedCapacity);
|
||||
}
|
||||
|
||||
@@ -109,6 +110,10 @@ bool MemoryFile::truncate(size_t size) {
|
||||
if (size == m_size) {
|
||||
return true;
|
||||
}
|
||||
if (m_readOnly) {
|
||||
// truncate readonly file not allow
|
||||
return false;
|
||||
}
|
||||
|
||||
auto oldSize = m_size;
|
||||
m_size = size;
|
||||
@@ -151,6 +156,10 @@ bool MemoryFile::truncate(size_t size) {
|
||||
}
|
||||
|
||||
bool MemoryFile::msync(SyncFlag syncFlag) {
|
||||
if (m_readOnly) {
|
||||
// there's no point in msync() readonly memory
|
||||
return true;
|
||||
}
|
||||
if (m_ptr) {
|
||||
if (FlushViewOfFile(m_ptr, m_size)) {
|
||||
if (syncFlag == MMKV_SYNC) {
|
||||
@@ -168,14 +177,16 @@ bool MemoryFile::msync(SyncFlag syncFlag) {
|
||||
}
|
||||
|
||||
bool MemoryFile::mmap() {
|
||||
m_fileMapping = CreateFileMapping(m_diskFile.getFd(), nullptr, PAGE_READWRITE, 0, 0, nullptr);
|
||||
auto mode = m_readOnly ? PAGE_READONLY : PAGE_READWRITE;
|
||||
m_fileMapping = CreateFileMapping(m_diskFile.getFd(), nullptr, mode, 0, 0, nullptr);
|
||||
if (!m_fileMapping) {
|
||||
MMKVError("fail to CreateFileMapping [%ls], %d", m_diskFile.m_path.c_str(), GetLastError());
|
||||
MMKVError("fail to CreateFileMapping [%ls], mode %x, %d", m_diskFile.m_path.c_str(), mode, GetLastError());
|
||||
return false;
|
||||
} else {
|
||||
m_ptr = (char *) MapViewOfFile(m_fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
auto viewMode = m_readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS;
|
||||
m_ptr = (char *) MapViewOfFile(m_fileMapping, viewMode, 0, 0, 0);
|
||||
if (!m_ptr) {
|
||||
MMKVError("fail to mmap [%ls], %d", m_diskFile.m_path.c_str(), GetLastError());
|
||||
MMKVError("fail to mmap [%ls], mode %x, %d", m_diskFile.m_path.c_str(), viewMode, GetLastError());
|
||||
return false;
|
||||
}
|
||||
MMKVInfo("mmap to address [%p], [%ls]", m_ptr, m_diskFile.m_path.c_str());
|
||||
@@ -199,7 +210,7 @@ void MemoryFile::reloadFromFile(size_t expectedCapacity) {
|
||||
mmkv::getFileSize(m_diskFile.getFd(), m_size);
|
||||
size_t expectedSize = std::max<size_t>(DEFAULT_MMAP_SIZE, roundUp<size_t>(expectedCapacity, DEFAULT_MMAP_SIZE));
|
||||
// round up to (n * pagesize)
|
||||
if (m_size < expectedSize || (m_size % DEFAULT_MMAP_SIZE != 0)) {
|
||||
if (!m_readOnly && (m_size < expectedSize || (m_size % DEFAULT_MMAP_SIZE != 0))) {
|
||||
size_t roundSize = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE;;
|
||||
roundSize = std::max<size_t>(expectedSize, roundSize);
|
||||
truncate(roundSize);
|
||||
|
||||
Reference in New Issue
Block a user