-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#265 Update MemoryMappedPageManager memory mapped initiation #388
base: main
Are you sure you want to change the base?
#265 Update MemoryMappedPageManager memory mapped initiation #388
Conversation
Hi @Scooletz, pls let me know if these changes are in the right direction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provided comments. I don't understand how this could work without significant changes or using the NT method mentioned in the referred issue. Maybe we should add some tests for the MemoryMappedPageManager
to ensure that it works properly? Also, add some matrix for OS dependent tests?
HandleInheritability.None, true); | ||
|
||
_whole = _mapped.CreateViewAccessor(); | ||
_whole = _mapped.CreateViewAccessor(0, historyDepth * Page.PageSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _whole
is used as both, the view to ForceFlush
when a synchronization happens and as an accessor that provides the pointer _ptr
for the whole file. This is why it was set to cover whole file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we introduce a new variable called _viewAccessor for accessing the memory mapped portion as a pointer. And use _whole as it is for ForceFlush
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following. ForceFlush
semantics should be that all the pages that were allocated are flushed down and then FSYNC is called. I believe we could create a one time use accessor and flush it. This might work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean, inside the ForceFlush method, we can get another accessor for _file that covers the whole file and flush it?
@@ -61,11 +61,9 @@ public unsafe MemoryMappedPageManager(long size, byte historyDepth, string dir, | |||
_file = new FileStream(Path, FileMode.Open, FileAccess.ReadWrite, FileShare.None, 4096, | |||
PaprikaFileOptions); | |||
} | |||
_mapped = MemoryMappedFile.CreateFromFile(_file, null, 0, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, the mapping will get size from the _file
, but if the file is just created, it won't work as expected as one will need to set the length. I don't understand how this should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if we remove this line -
_file.setLength(size);
while creating a new file. We can set it to some safe initial size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how to answer. We may do all the things as long as the file is properly mapped and written and flushed 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you recommend -
- initialize the _file with an initial size of say, 4 MB.
- modifying the write and flush operations in a way it first checks the size of the _file and only if it's large enough to store incoming data, proceed as it is. Otherwise, can double the file size until it can accommodate incoming data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you recommend -
- initialize the _file with an initial size of say, 4 MB.
- modifying the write and flush operations in a way it first checks the size of the _file and only if it's large enough to store incoming data, proceed as it is. Otherwise, can double the file size until it can accommodate incoming data.
@Scooletz What do you think about this approach?
I read somewhere that the .NET memory-mapped file API abstracts the complexity of memory management, so we don’t need to use lower-level functions like NtCreateSection in C#. Might be completely wrong here. Do you suggest using ntdll.dll and create a custom class like this to get the same behavior as lmdb? -
Although since ntdll.dll is an unmanaged dll, on Linux machines, it will not work. |
The issue is pure Windows issue (see #265 that you linked). On Linux, mmap behaves nicely not preallocating whole file up front. The only method that I partially investigated was the mentioned |
Any comments @shubham-sonthalia ? |
#265
Two changes:
_mapped = MemoryMappedFile.CreateFromFile(_file, null, 0, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true);
_whole = _mapped.CreateViewAccessor(0, historyDepth * Page.PageSize);