Macros | Functions
memfile.c File Reference
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <string.h>
#include <stdbool.h>
#include <fcntl.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/memfile.h"
#include "nvim/fileio.h"
#include "nvim/memline.h"
#include "nvim/message.h"
#include "nvim/memory.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"

Macros

#define MEMFILE_PAGE_SIZE   4096
 
#define MHT_LOG_LOAD_FACTOR   6
 
#define MHT_GROWTH_FACTOR   2
 

Functions

memfile_Tmf_open (char_u *fname, int flags)
 
int mf_open_file (memfile_T *mfp, char_u *fname)
 
void mf_close (memfile_T *mfp, bool del_file)
 
void mf_close_file (buf_T *buf, bool getlines)
 
void mf_new_page_size (memfile_T *mfp, unsigned new_size)
 
bhdr_Tmf_new (memfile_T *mfp, bool negative, unsigned page_count)
 
bhdr_Tmf_get (memfile_T *mfp, blocknr_T nr, unsigned page_count)
 
void mf_put (memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile)
 
void mf_free (memfile_T *mfp, bhdr_T *hp)
 Signal block as no longer used (may put it in the free list). More...
 
int mf_sync (memfile_T *mfp, int flags)
 
void mf_set_dirty (memfile_T *mfp)
 
bool mf_release_all (void)
 
blocknr_T mf_trans_del (memfile_T *mfp, blocknr_T old_nr)
 
void mf_free_fnames (memfile_T *mfp)
 Frees mf_fname and mf_ffname. More...
 
void mf_set_fnames (memfile_T *mfp, char_u *fname)
 
void mf_fullname (memfile_T *mfp)
 
bool mf_need_trans (memfile_T *mfp)
 Return true if there are any translations pending for memfile. More...
 

Macro Definition Documentation

#define MEMFILE_PAGE_SIZE   4096

An abstraction to handle blocks of memory which can be stored in a file. This is the implementation of a sort of virtual memory.

A memfile consists of a sequence of blocks:

  • Blocks numbered from 0 upwards have been assigned a place in the actual file. The block number is equal to the page number in the file.
  • Blocks with negative numbers are currently in memory only. They can be assigned a place in the file when too much memory is being used. At that moment, they get a new, positive, number. A list is used for translation of negative to positive numbers.

The size of a block is a multiple of a page size, normally the page size of the device the file is on. Most blocks are 1 page long. A block of multiple pages is used for a line that does not fit in a single page.

Each block can be in memory and/or in a file. The block stays in memory as long as it is locked. If it is no longer locked it can be swapped out to the file. It is only written to the file if it has been changed.

Under normal operation the file is created when opening the memory file and deleted when closing the memory file. Only with recovery an existing memory file is opened.

The functions for using a memfile:

mf_open() open a new or existing memfile mf_open_file() open a swap file for an existing memfile mf_close() close (and delete) a memfile mf_new() create a new block in a memfile and lock it mf_get() get an existing block and lock it mf_put() unlock a block, may be marked for writing mf_free() remove a block mf_sync() sync changed parts of memfile to disk mf_release_all() release as much memory as possible mf_trans_del() may translate negative to positive block number mf_fullname() make file name full path (use before first :cd)

#define MHT_GROWTH_FACTOR   2
#define MHT_LOG_LOAD_FACTOR   6

The number of buckets in the hashtable is increased by a factor of MHT_GROWTH_FACTOR when the average number of items per bucket exceeds 2 ^ MHT_LOG_LOAD_FACTOR.

Function Documentation

void mf_close ( memfile_T mfp,
bool  del_file 
)

Close a memory file and optionally delete the associated file.

Parameters
del_fileWhether to delete associated file.
void mf_close_file ( buf_T buf,
bool  getlines 
)

Close the swap file for a memfile. Used when 'swapfile' is reset.

Parameters
getlinesWhether to get all lines into memory.
void mf_free ( memfile_T mfp,
bhdr_T hp 
)

Signal block as no longer used (may put it in the free list).

void mf_free_fnames ( memfile_T mfp)

Frees mf_fname and mf_ffname.

void mf_fullname ( memfile_T mfp)

Make name of memfile's swapfile a full path.

Used before doing a :cd

bhdr_T* mf_get ( memfile_T mfp,
blocknr_T  nr,
unsigned  page_count 
)
bool mf_need_trans ( memfile_T mfp)

Return true if there are any translations pending for memfile.

bhdr_T* mf_new ( memfile_T mfp,
bool  negative,
unsigned  page_count 
)

Get a new block

Parameters
negativeWhether a negative block number is desired (data block).
page_countDesired number of pages.
void mf_new_page_size ( memfile_T mfp,
unsigned  new_size 
)

Set new size for a memfile. Used when block 0 of a swapfile has been read and the size it indicates differs from what was guessed.

memfile_T* mf_open ( char_u fname,
int  flags 
)

Open a new or existing memory block file.

Parameters
fnameName of file to use.
  • If NULL, it means no file (use memory only).
  • If not NULL:
    • Should correspond to an existing file.
    • String must have been allocated (it is not copied).
    • If opening the file fails, it is freed and function fails.
flagsFlags for open() call.
Returns
- The open memory file, on success.
  • NULL, on failure (e.g. file does not exist).
int mf_open_file ( memfile_T mfp,
char_u fname 
)

Open a file for an existing memfile.

Used when updatecount set from 0 to some value.

Parameters
fnameName of file to use.
  • If NULL, it means no file (use memory only).
  • If not NULL:
    • Should correspond to an existing file.
    • String must have been allocated (it is not copied).
    • If opening the file fails, it is freed and function fails.
Returns
OK On success. FAIL If file could not be opened.
void mf_put ( memfile_T mfp,
bhdr_T hp,
bool  dirty,
bool  infile 
)

Release the block *hp.

Parameters
dirtyWhether block must be written to file later.
infileWhether block should be in file (needed for recovery).
bool mf_release_all ( void  )

Release as many blocks as possible.

Used in case of out of memory

Returns
Whether any memory was released.
void mf_set_dirty ( memfile_T mfp)

Set dirty flag for all blocks in memory file with a positive block number. These are blocks that need to be written to a newly created swapfile.

void mf_set_fnames ( memfile_T mfp,
char_u fname 
)

Set the simple file name and the full file name of memfile's swapfile, out of simple file name and some other considerations.

Only called when creating or renaming the swapfile. Either way it's a new name so we must work out the full path name.

int mf_sync ( memfile_T mfp,
int  flags 
)

Sync memory file to disk.

Parameters
flagsMFS_ALL If not given, blocks with negative numbers are not synced, even when they are dirty. MFS_STOP Stop syncing when a character becomes available, but sync at least one block. MFS_FLUSH Make sure buffers are flushed to disk, so they will survive a system crash. MFS_ZERO Only write block 0.
Returns
FAIL If failure. Possible causes:
  • No file (nothing to do).
  • Write error (probably full disk). OK Otherwise.
blocknr_T mf_trans_del ( memfile_T mfp,
blocknr_T  old_nr 
)

Lookup translation from trans list and delete the entry.

Returns
The positive new number When found. The old number When not found.