aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/memfile.c149
-rw-r--r--src/nvim/memfile_defs.h30
3 files changed, 62 insertions, 118 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 4ea288c258..094d6dfd05 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -78,7 +78,6 @@ typedef struct wininfo_S wininfo_T;
typedef struct frame_S frame_T;
typedef int scid_T; /* script ID */
typedef struct file_buffer buf_T; /* forward declaration */
-typedef struct memfile memfile_T;
// for struct memline (it needs memfile_T)
#include "nvim/memline_defs.h"
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index ca6628afb1..1f02e7b320 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -123,7 +123,8 @@ memfile_T *mf_open(char_u *fname, int flags)
// When recovering, the actual block size will be retrieved from block 0
// in ml_recover(). The size used here may be wrong, therefore mf_blocknr_max
// must be rounded up.
- if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
+ if (mfp->mf_fd < 0
+ || (flags & (O_TRUNC|O_EXCL))
|| (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
// no file or empty file
mfp->mf_blocknr_max = 0;
@@ -185,10 +186,10 @@ void mf_close(memfile_T *mfp, int del_file)
{
bhdr_T *hp, *nextp;
- if (mfp == NULL) // safety check
+ if (mfp == NULL) { // safety check
return;
- if (mfp->mf_fd >= 0) {
- if (close(mfp->mf_fd) < 0)
+ }
+ if (mfp->mf_fd >= 0 && close(mfp->mf_fd) < 0) {
EMSG(_(e_swapclose));
}
if (del_file && mfp->mf_fname != NULL)
@@ -213,17 +214,14 @@ void mf_close(memfile_T *mfp, int del_file)
/// @param getlines TRUE to get all lines into memory.
void mf_close_file (buf_T *buf, int getlines)
{
- memfile_T *mfp;
- linenr_T lnum;
-
- mfp = buf->b_ml.ml_mfp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
if (mfp == NULL || mfp->mf_fd < 0) // nothing to close
return;
if (getlines) {
// get all blocks in memory by accessing all lines (clumsy!)
mf_dont_release = TRUE;
- for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
+ for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
(void)ml_get_buf(buf, lnum, FALSE);
mf_dont_release = FALSE;
// TODO: should check if all blocks are really in core
@@ -258,20 +256,16 @@ void mf_new_page_size(memfile_T *mfp, unsigned new_size)
/// @param page_count Desired number of pages.
bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count)
{
- bhdr_T *hp; // new block
- bhdr_T *freep; // first block in free list
- char_u *p;
-
// If we reached the maximum size for the used memory blocks, release one.
// If a bhdr_T is returned, use it and adjust the page_count if necessary.
// If no bhdr_T is returned, a new one will be created.
- hp = mf_release(mfp, page_count);
+ bhdr_T *hp = mf_release(mfp, page_count); // the block to be returned
// Decide on the number to use:
// If there is a free block, use its number.
// Otherwise use mf_block_min for a negative number, mf_block_max for
// a positive number.
- freep = mfp->mf_free_first;
+ bhdr_T *freep = mfp->mf_free_first; // first free block
if (!negative && freep != NULL && freep->bh_page_count >= page_count) {
// If the block in the free list has more pages, take only the number
// of pages needed and allocate a new bhdr_T with data.
@@ -289,7 +283,7 @@ bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count)
freep->bh_bnum += page_count;
freep->bh_page_count -= page_count;
} else if (hp == NULL) { // need to allocate memory for this block
- p = xmalloc(mfp->mf_page_size * page_count);
+ char_u *p = xmalloc(mfp->mf_page_size * page_count);
hp = mf_rem_free(mfp);
hp->bh_data = p;
} else { // use the number, remove entry from free list
@@ -318,7 +312,7 @@ bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count)
// Init the data to all zero, to avoid reading uninitialized data.
// This also avoids that the passwd file ends up in the swap file!
(void)memset((char *)(hp->bh_data), 0,
- (size_t)mfp->mf_page_size * page_count);
+ (size_t)mfp->mf_page_size * page_count);
return hp;
}
@@ -330,13 +324,12 @@ bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count)
// @return NULL if not found
bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, int page_count)
{
- bhdr_T *hp;
// check block number exists
if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
return NULL;
// see if it is in the cache
- hp = mf_find_hash(mfp, nr);
+ bhdr_T *hp = mf_find_hash(mfp, nr);
if (hp == NULL) { // not in the hash list
if (nr < 0 || nr >= mfp->mf_infile_count) // can't be in the file
return NULL;
@@ -376,9 +369,7 @@ bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, int page_count)
/// @param infile Block should be in file (needed for recovery).
void mf_put(memfile_T *mfp, bhdr_T *hp, int dirty, int infile)
{
- int flags;
-
- flags = hp->bh_flags;
+ int flags = hp->bh_flags;
if ((flags & BH_LOCKED) == 0)
EMSG(_("E293: block was not locked"));
@@ -421,11 +412,6 @@ void mf_free(memfile_T *mfp, bhdr_T *hp)
/// OK Otherwise.
int mf_sync(memfile_T *mfp, int flags)
{
- int status;
- bhdr_T *hp;
-#if defined(SYNC_DUP_CLOSE)
- int fd;
-#endif
int got_int_save = got_int;
if (mfp->mf_fd < 0) { // there is no file, nothing to do
@@ -440,7 +426,8 @@ int mf_sync(memfile_T *mfp, int flags)
// file). If a write fails, it is very likely caused by a full filesystem.
// Then we only try to write blocks within the existing file. If that also
// fails then we give up.
- status = OK;
+ int status = OK;
+ bhdr_T *hp;
for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
&& (hp->bh_flags & BH_DIRTY)
@@ -486,6 +473,7 @@ int mf_sync(memfile_T *mfp, int flags)
# ifdef SYNC_DUP_CLOSE
// Win32 is a bit more work: Duplicate the file handle and close it.
// This should flush the file to disk.
+ int fd;
if ((fd = dup(mfp->mf_fd)) >= 0)
close(fd);
# endif
@@ -500,8 +488,7 @@ int mf_sync(memfile_T *mfp, int flags)
/// These are blocks that need to be written to a newly created swapfile.
void mf_set_dirty(memfile_T *mfp)
{
- bhdr_T *hp;
-
+ bhdr_T *hp;
for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
if (hp->bh_bnum > 0)
hp->bh_flags |= BH_DIRTY;
@@ -573,17 +560,14 @@ static void mf_rem_used(memfile_T *mfp, bhdr_T *hp)
/// - Unlocked dirty block found, but flush failed.
static bhdr_T *mf_release(memfile_T *mfp, int page_count)
{
- bhdr_T *hp;
- int need_release;
-
// don't release while in mf_close_file()
if (mf_dont_release)
return NULL;
/// Need to release a block if the number of blocks for this memfile is
/// higher than the maximum one or total memory used is over 'maxmemtot'.
- need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max)
- || (total_mem_used >> 10) >= (long_u)p_mmt);
+ int need_release = (mfp->mf_used_count >= mfp->mf_used_count_max
+ || (total_mem_used >> 10) >= (long_u)p_mmt);
/// Try to create swap file if the amount of memory used is getting too high.
if (mfp->mf_fd < 0 && need_release && p_uc) {
@@ -609,6 +593,7 @@ static bhdr_T *mf_release(memfile_T *mfp, int page_count)
if (mfp->mf_fd < 0 || !need_release)
return NULL;
+ bhdr_T *hp;
for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
if (!(hp->bh_flags & BH_LOCKED))
break;
@@ -640,12 +625,9 @@ static bhdr_T *mf_release(memfile_T *mfp, int page_count)
/// FALSE If not.
int mf_release_all(void)
{
- memfile_T *mfp;
- bhdr_T *hp;
int retval = FALSE;
-
FOR_ALL_BUFFERS(buf) {
- mfp = buf->b_ml.ml_mfp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
if (mfp != NULL) {
// If no swap file yet, may open one.
if (mfp->mf_fd < 0 && buf->b_may_swap)
@@ -653,7 +635,7 @@ int mf_release_all(void)
// Flush as many blocks as possible, only if there is a swapfile.
if (mfp->mf_fd >= 0) {
- for (hp = mfp->mf_used_last; hp != NULL; ) {
+ for (bhdr_T *hp = mfp->mf_used_last; hp != NULL; ) {
if (!(hp->bh_flags & BH_LOCKED)
&& (!(hp->bh_flags & BH_DIRTY)
|| mf_write(mfp, hp) != FAIL)) {
@@ -677,7 +659,6 @@ static bhdr_T *mf_alloc_bhdr(memfile_T *mfp, int page_count)
bhdr_T *hp = xmalloc(sizeof(bhdr_T));
hp->bh_data = xmalloc(mfp->mf_page_size * page_count);
hp->bh_page_count = page_count;
-
return hp;
}
@@ -700,9 +681,7 @@ static void mf_ins_free(memfile_T *mfp, bhdr_T *hp)
/// Caller must check that mfp->mf_free_first is not NULL.
static bhdr_T *mf_rem_free(memfile_T *mfp)
{
- bhdr_T *hp;
-
- hp = mfp->mf_free_first;
+ bhdr_T *hp = mfp->mf_free_first;
mfp->mf_free_first = hp->bh_next;
return hp;
}
@@ -715,16 +694,12 @@ static bhdr_T *mf_rem_free(memfile_T *mfp)
/// - Error reading file.
static int mf_read(memfile_T *mfp, bhdr_T *hp)
{
- off_t offset;
- unsigned page_size;
- unsigned size;
-
if (mfp->mf_fd < 0) // there is no file, can't read
return FAIL;
- page_size = mfp->mf_page_size;
- offset = (off_t)page_size * hp->bh_bnum;
- size = page_size * hp->bh_page_count;
+ unsigned page_size = mfp->mf_page_size;
+ off_t offset = (off_t)page_size * hp->bh_bnum;
+ unsigned size = page_size * hp->bh_page_count;
if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
PERROR(_("E294: Seek error in swap file read"));
return FAIL;
@@ -767,7 +742,7 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// to extend the file.
/// If block 'mf_infile_count' is not in the hash list, it has been
/// freed. Fill the space in the file with data from the current block.
- for (;; ) {
+ for (;;) {
nr = hp->bh_bnum;
if (nr > mfp->mf_infile_count) { // beyond end of file
nr = mfp->mf_infile_count;
@@ -810,14 +785,13 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
///
/// @return OK On success.
/// FAIL On failure.
-static int mf_write_block(memfile_T *mfp, bhdr_T *hp, off_t offset, unsigned size)
+static int mf_write_block(memfile_T *mfp, bhdr_T *hp,
+ off_t offset, unsigned size)
{
- char_u *data = hp->bh_data;
+ char_u *data = hp->bh_data;
int result = OK;
-
if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size)
result = FAIL;
-
return result;
}
@@ -827,10 +801,6 @@ static int mf_write_block(memfile_T *mfp, bhdr_T *hp, off_t offset, unsigned siz
/// FAIL On failure.
static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
{
- bhdr_T *freep;
- blocknr_T new_bnum;
- int page_count;
-
if (hp->bh_bnum >= 0) // it's already positive
return OK;
@@ -839,8 +809,9 @@ static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
// Get a new number for the block.
// If the first item in the free list has sufficient pages, use its number.
// Otherwise use mf_blocknr_max.
- freep = mfp->mf_free_first;
- page_count = hp->bh_page_count;
+ blocknr_T new_bnum;
+ bhdr_T *freep = mfp->mf_free_first;
+ int page_count = hp->bh_page_count;
if (freep != NULL && freep->bh_page_count >= page_count) {
new_bnum = freep->bh_bnum;
// If the page count of the free block was larger, reduce it.
@@ -876,16 +847,13 @@ static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
/// The old number When not found.
blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
{
- NR_TRANS *np;
- blocknr_T new_bnum;
-
- np = (NR_TRANS *)mf_hash_find(&mfp->mf_trans, old_nr);
+ NR_TRANS *np = (NR_TRANS *)mf_hash_find(&mfp->mf_trans, old_nr);
if (np == NULL) // not found
return old_nr;
mfp->mf_neg_count--;
- new_bnum = np->nt_new_bnum;
+ blocknr_T new_bnum = np->nt_new_bnum;
// remove entry from the trans list
mf_hash_rem_item(&mfp->mf_trans, (mf_hashitem_T *)np);
@@ -928,12 +896,7 @@ int mf_need_trans(memfile_T *mfp)
/// "fname" must be in allocated memory, and is consumed (also when error).
///
/// @param flags Flags for open().
-static void
-mf_do_open (
- memfile_T *mfp,
- char_u *fname,
- int flags /* flags for open() */
-)
+static void mf_do_open (memfile_T *mfp, char_u *fname, int flags)
{
// fname cannot be NameBuff, because it must have been allocated.
mfp->mf_fname = fname;
@@ -1000,12 +963,10 @@ static void mf_hash_free(mf_hashtab_T *mht)
/// Free the array of a hash table and all the items it contains.
static void mf_hash_free_all(mf_hashtab_T *mht)
{
- long_u idx;
- mf_hashitem_T *mhi;
- mf_hashitem_T *next;
+ mf_hashitem_T *next;
- for (idx = 0; idx <= mht->mht_mask; idx++)
- for (mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next) {
+ for (long_u idx = 0; idx <= mht->mht_mask; idx++)
+ for (mf_hashitem_T *mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next) {
next = mhi->mhi_next;
free(mhi);
}
@@ -1018,21 +979,16 @@ static void mf_hash_free_all(mf_hashtab_T *mht)
/// @return A pointer to a mf_hashitem_T or NULL if the item was not found.
static mf_hashitem_T *mf_hash_find(mf_hashtab_T *mht, blocknr_T key)
{
- mf_hashitem_T *mhi;
-
- mhi = mht->mht_buckets[key & mht->mht_mask];
+ mf_hashitem_T *mhi = mht->mht_buckets[key & mht->mht_mask];
while (mhi != NULL && mhi->mhi_key != key)
mhi = mhi->mhi_next;
-
return mhi;
}
/// Add item to hashtable. Item must not be NULL.
static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
{
- long_u idx;
-
- idx = mhi->mhi_key & mht->mht_mask;
+ long_u idx = mhi->mhi_key & mht->mht_mask;
mhi->mhi_next = mht->mht_buckets[idx];
mhi->mhi_prev = NULL;
if (mhi->mhi_next != NULL)
@@ -1070,21 +1026,14 @@ static void mf_hash_rem_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
/// rehash items.
static void mf_hash_grow(mf_hashtab_T *mht)
{
- long_u i, j;
- int shift;
- mf_hashitem_T *mhi;
- mf_hashitem_T *tails[MHT_GROWTH_FACTOR];
- mf_hashitem_T **buckets;
- size_t size;
-
- size = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR * sizeof(void *);
- buckets = xcalloc(1, size);
+ size_t size = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR * sizeof(void *);
+ mf_hashitem_T **buckets = xcalloc(1, size);
- shift = 0;
+ int shift = 0;
while ((mht->mht_mask >> shift) != 0)
shift++;
- for (i = 0; i <= mht->mht_mask; i++) {
+ for (long_u i = 0; i <= mht->mht_mask; i++) {
/// Traverse the items in the i-th original bucket and move them into
/// MHT_GROWTH_FACTOR new buckets, preserving their relative order
/// within each new bucket. Preserving the order is important because
@@ -1094,10 +1043,12 @@ static void mf_hash_grow(mf_hashtab_T *mht)
/// Here we strongly rely on the fact that hashes are computed modulo
/// a power of two.
+ mf_hashitem_T *tails[MHT_GROWTH_FACTOR];
memset(tails, 0, sizeof(tails));
- for (mhi = mht->mht_buckets[i]; mhi != NULL; mhi = mhi->mhi_next) {
- j = (mhi->mhi_key >> shift) & (MHT_GROWTH_FACTOR - 1);
+ for (mf_hashitem_T *mhi = mht->mht_buckets[i];
+ mhi != NULL; mhi = mhi->mhi_next) {
+ long_u j = (mhi->mhi_key >> shift) & (MHT_GROWTH_FACTOR - 1);
if (tails[j] == NULL) {
buckets[i + (j << shift)] = mhi;
tails[j] = mhi;
@@ -1109,7 +1060,7 @@ static void mf_hash_grow(mf_hashtab_T *mht)
}
}
- for (j = 0; j < MHT_GROWTH_FACTOR; j++)
+ for (long_u j = 0; j < MHT_GROWTH_FACTOR; j++)
if (tails[j] != NULL)
tails[j]->mhi_next = NULL;
}
diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h
index 5dc17a751a..bc527be6f5 100644
--- a/src/nvim/memfile_defs.h
+++ b/src/nvim/memfile_defs.h
@@ -3,8 +3,6 @@
#include "nvim/types.h"
-typedef struct block_hdr bhdr_T;
-
/// A block number.
///
/// Blocks numbered from 0 upwards have been assigned a place in the actual
@@ -19,13 +17,11 @@ typedef long blocknr_T;
///
/// Therefore, items can be arbitrary data structures beginning with pointers
/// for the list and and a block number key.
-typedef struct mf_hashitem_S mf_hashitem_T;
-
-struct mf_hashitem_S {
- mf_hashitem_T *mhi_next;
- mf_hashitem_T *mhi_prev;
+typedef struct mf_hashitem_S {
+ struct mf_hashitem_S *mhi_next;
+ struct mf_hashitem_S *mhi_prev;
blocknr_T mhi_key;
-};
+} mf_hashitem_T;
/// Initial size for a hashtable.
#define MHT_INIT_SIZE 64
@@ -61,19 +57,19 @@ typedef struct mf_hashtab_S {
/// The free list is a single linked list, not sorted.
/// The blocks in the free list have no block of memory allocated and
/// the contents of the block in the file (if any) is irrelevant.
-struct block_hdr {
+typedef struct block_hdr {
mf_hashitem_T bh_hashitem; /// header for hash table and key
#define bh_bnum bh_hashitem.mhi_key /// block number, part of bh_hashitem
- bhdr_T *bh_next; /// next block_hdr in free or used list
- bhdr_T *bh_prev; /// previous block_hdr in used list
+ struct block_hdr *bh_next; /// next block_hdr in free or used list
+ struct block_hdr *bh_prev; /// previous block_hdr in used list
char_u *bh_data; /// pointer to memory (for used block)
int bh_page_count; /// number of pages in this block
#define BH_DIRTY 1
#define BH_LOCKED 2
char bh_flags; // BH_DIRTY or BH_LOCKED
-};
+} bhdr_T;
/// A block number translation list item.
///
@@ -81,16 +77,14 @@ struct block_hdr {
/// a positive number. Because the reference to the block is still the negative
/// number, we remember the translation to the new positive number in the
/// double linked trans lists. The structure is the same as the hash lists.
-typedef struct nr_trans NR_TRANS;
-
-struct nr_trans {
+typedef struct nr_trans {
mf_hashitem_T nt_hashitem; /// header for hash table and key
#define nt_old_bnum nt_hashitem.mhi_key /// old, negative, number
blocknr_T nt_new_bnum; /// new, positive, number
-};
+} NR_TRANS;
/// A memory file.
-struct memfile {
+typedef struct memfile {
char_u *mf_fname; /// name of the file
char_u *mf_ffname; /// idem, full path
int mf_fd; /// file descriptor
@@ -107,6 +101,6 @@ struct memfile {
blocknr_T mf_infile_count; /// number of pages in the file
unsigned mf_page_size; /// number of bytes in a page
int mf_dirty; /// TRUE if there are dirty blocks
-};
+} memfile_T;
#endif // NVIM_MEMFILE_DEFS_H