Review: Remove long_u: memfile: Cleanup: Others.

memfile_defs.h:
- Inline struct definitions in typedefs.
- Move memfile_T definition to this file (weirdly, was in buffer_defs.h).

memfile.c:
- Use C99 style variable declarations. This is, move variable declarations as
  near to first-usage point as possible).
- Modernize old-style function declarations.
- Fix indent at some places (some multiline expressions and the like).
This commit is contained in:
Eliseo Martínez
2014-10-20 11:07:06 +02:00
parent 8fb4097fc6
commit a69b2e3c40
3 changed files with 62 additions and 118 deletions

View File

@@ -78,7 +78,6 @@ typedef struct wininfo_S wininfo_T;
typedef struct frame_S frame_T; typedef struct frame_S frame_T;
typedef int scid_T; /* script ID */ typedef int scid_T; /* script ID */
typedef struct file_buffer buf_T; /* forward declaration */ typedef struct file_buffer buf_T; /* forward declaration */
typedef struct memfile memfile_T;
// for struct memline (it needs memfile_T) // for struct memline (it needs memfile_T)
#include "nvim/memline_defs.h" #include "nvim/memline_defs.h"

View File

@@ -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 // 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 // in ml_recover(). The size used here may be wrong, therefore mf_blocknr_max
// must be rounded up. // 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) || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
// no file or empty file // no file or empty file
mfp->mf_blocknr_max = 0; mfp->mf_blocknr_max = 0;
@@ -185,10 +186,10 @@ void mf_close(memfile_T *mfp, int del_file)
{ {
bhdr_T *hp, *nextp; bhdr_T *hp, *nextp;
if (mfp == NULL) // safety check if (mfp == NULL) { // safety check
return; 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)); EMSG(_(e_swapclose));
} }
if (del_file && mfp->mf_fname != NULL) 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. /// @param getlines TRUE to get all lines into memory.
void mf_close_file (buf_T *buf, int getlines) void mf_close_file (buf_T *buf, int getlines)
{ {
memfile_T *mfp; memfile_T *mfp = buf->b_ml.ml_mfp;
linenr_T lnum;
mfp = buf->b_ml.ml_mfp;
if (mfp == NULL || mfp->mf_fd < 0) // nothing to close if (mfp == NULL || mfp->mf_fd < 0) // nothing to close
return; return;
if (getlines) { if (getlines) {
// get all blocks in memory by accessing all lines (clumsy!) // get all blocks in memory by accessing all lines (clumsy!)
mf_dont_release = TRUE; 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); (void)ml_get_buf(buf, lnum, FALSE);
mf_dont_release = FALSE; mf_dont_release = FALSE;
// TODO: should check if all blocks are really in core // 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. /// @param page_count Desired number of pages.
bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count) 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 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 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. // 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: // Decide on the number to use:
// If there is a free block, use its number. // If there is a free block, use its number.
// Otherwise use mf_block_min for a negative number, mf_block_max for // Otherwise use mf_block_min for a negative number, mf_block_max for
// a positive number. // 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 (!negative && freep != NULL && freep->bh_page_count >= page_count) {
// If the block in the free list has more pages, take only the number // 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. // 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_bnum += page_count;
freep->bh_page_count -= page_count; freep->bh_page_count -= page_count;
} else if (hp == NULL) { // need to allocate memory for this block } 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 = mf_rem_free(mfp);
hp->bh_data = p; hp->bh_data = p;
} else { // use the number, remove entry from free list } 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. // Init the data to all zero, to avoid reading uninitialized data.
// This also avoids that the passwd file ends up in the swap file! // This also avoids that the passwd file ends up in the swap file!
(void)memset((char *)(hp->bh_data), 0, (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; return hp;
} }
@@ -330,13 +324,12 @@ bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count)
// @return NULL if not found // @return NULL if not found
bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, int page_count) bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, int page_count)
{ {
bhdr_T *hp;
// check block number exists // check block number exists
if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min) if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
return NULL; return NULL;
// see if it is in the cache // 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 (hp == NULL) { // not in the hash list
if (nr < 0 || nr >= mfp->mf_infile_count) // can't be in the file if (nr < 0 || nr >= mfp->mf_infile_count) // can't be in the file
return NULL; 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). /// @param infile Block should be in file (needed for recovery).
void mf_put(memfile_T *mfp, bhdr_T *hp, int dirty, int infile) void mf_put(memfile_T *mfp, bhdr_T *hp, int dirty, int infile)
{ {
int flags; int flags = hp->bh_flags;
flags = hp->bh_flags;
if ((flags & BH_LOCKED) == 0) if ((flags & BH_LOCKED) == 0)
EMSG(_("E293: block was not locked")); EMSG(_("E293: block was not locked"));
@@ -421,11 +412,6 @@ void mf_free(memfile_T *mfp, bhdr_T *hp)
/// OK Otherwise. /// OK Otherwise.
int mf_sync(memfile_T *mfp, int flags) 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; int got_int_save = got_int;
if (mfp->mf_fd < 0) { // there is no file, nothing to do 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. // 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 // Then we only try to write blocks within the existing file. If that also
// fails then we give up. // 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) for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
if (((flags & MFS_ALL) || hp->bh_bnum >= 0) if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
&& (hp->bh_flags & BH_DIRTY) && (hp->bh_flags & BH_DIRTY)
@@ -486,6 +473,7 @@ int mf_sync(memfile_T *mfp, int flags)
# ifdef SYNC_DUP_CLOSE # ifdef SYNC_DUP_CLOSE
// Win32 is a bit more work: Duplicate the file handle and close it. // Win32 is a bit more work: Duplicate the file handle and close it.
// This should flush the file to disk. // This should flush the file to disk.
int fd;
if ((fd = dup(mfp->mf_fd)) >= 0) if ((fd = dup(mfp->mf_fd)) >= 0)
close(fd); close(fd);
# endif # 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. /// These are blocks that need to be written to a newly created swapfile.
void mf_set_dirty(memfile_T *mfp) 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) for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
if (hp->bh_bnum > 0) if (hp->bh_bnum > 0)
hp->bh_flags |= BH_DIRTY; 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. /// - Unlocked dirty block found, but flush failed.
static bhdr_T *mf_release(memfile_T *mfp, int page_count) 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() // don't release while in mf_close_file()
if (mf_dont_release) if (mf_dont_release)
return NULL; return NULL;
/// Need to release a block if the number of blocks for this memfile is /// 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'. /// higher than the maximum one or total memory used is over 'maxmemtot'.
need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max) int need_release = (mfp->mf_used_count >= mfp->mf_used_count_max
|| (total_mem_used >> 10) >= (long_u)p_mmt); || (total_mem_used >> 10) >= (long_u)p_mmt);
/// Try to create swap file if the amount of memory used is getting too high. /// Try to create swap file if the amount of memory used is getting too high.
if (mfp->mf_fd < 0 && need_release && p_uc) { 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) if (mfp->mf_fd < 0 || !need_release)
return NULL; return NULL;
bhdr_T *hp;
for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
if (!(hp->bh_flags & BH_LOCKED)) if (!(hp->bh_flags & BH_LOCKED))
break; break;
@@ -640,12 +625,9 @@ static bhdr_T *mf_release(memfile_T *mfp, int page_count)
/// FALSE If not. /// FALSE If not.
int mf_release_all(void) int mf_release_all(void)
{ {
memfile_T *mfp;
bhdr_T *hp;
int retval = FALSE; int retval = FALSE;
FOR_ALL_BUFFERS(buf) { FOR_ALL_BUFFERS(buf) {
mfp = buf->b_ml.ml_mfp; memfile_T *mfp = buf->b_ml.ml_mfp;
if (mfp != NULL) { if (mfp != NULL) {
// If no swap file yet, may open one. // If no swap file yet, may open one.
if (mfp->mf_fd < 0 && buf->b_may_swap) 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. // Flush as many blocks as possible, only if there is a swapfile.
if (mfp->mf_fd >= 0) { 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) if (!(hp->bh_flags & BH_LOCKED)
&& (!(hp->bh_flags & BH_DIRTY) && (!(hp->bh_flags & BH_DIRTY)
|| mf_write(mfp, hp) != FAIL)) { || 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)); bhdr_T *hp = xmalloc(sizeof(bhdr_T));
hp->bh_data = xmalloc(mfp->mf_page_size * page_count); hp->bh_data = xmalloc(mfp->mf_page_size * page_count);
hp->bh_page_count = page_count; hp->bh_page_count = page_count;
return hp; 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. /// Caller must check that mfp->mf_free_first is not NULL.
static bhdr_T *mf_rem_free(memfile_T *mfp) static bhdr_T *mf_rem_free(memfile_T *mfp)
{ {
bhdr_T *hp; bhdr_T *hp = mfp->mf_free_first;
hp = mfp->mf_free_first;
mfp->mf_free_first = hp->bh_next; mfp->mf_free_first = hp->bh_next;
return hp; return hp;
} }
@@ -715,16 +694,12 @@ static bhdr_T *mf_rem_free(memfile_T *mfp)
/// - Error reading file. /// - Error reading file.
static int mf_read(memfile_T *mfp, bhdr_T *hp) 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 if (mfp->mf_fd < 0) // there is no file, can't read
return FAIL; return FAIL;
page_size = mfp->mf_page_size; unsigned page_size = mfp->mf_page_size;
offset = (off_t)page_size * hp->bh_bnum; off_t offset = (off_t)page_size * hp->bh_bnum;
size = page_size * hp->bh_page_count; unsigned size = page_size * hp->bh_page_count;
if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) { if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
PERROR(_("E294: Seek error in swap file read")); PERROR(_("E294: Seek error in swap file read"));
return FAIL; return FAIL;
@@ -767,7 +742,7 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// to extend the file. /// to extend the file.
/// If block 'mf_infile_count' is not in the hash list, it has been /// 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. /// freed. Fill the space in the file with data from the current block.
for (;; ) { for (;;) {
nr = hp->bh_bnum; nr = hp->bh_bnum;
if (nr > mfp->mf_infile_count) { // beyond end of file if (nr > mfp->mf_infile_count) { // beyond end of file
nr = mfp->mf_infile_count; nr = mfp->mf_infile_count;
@@ -810,14 +785,13 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
/// ///
/// @return OK On success. /// @return OK On success.
/// FAIL On failure. /// 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; int result = OK;
if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size) if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size)
result = FAIL; result = FAIL;
return result; 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. /// FAIL On failure.
static int mf_trans_add(memfile_T *mfp, bhdr_T *hp) 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 if (hp->bh_bnum >= 0) // it's already positive
return OK; return OK;
@@ -839,8 +809,9 @@ static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
// Get a new number for the block. // Get a new number for the block.
// If the first item in the free list has sufficient pages, use its number. // If the first item in the free list has sufficient pages, use its number.
// Otherwise use mf_blocknr_max. // Otherwise use mf_blocknr_max.
freep = mfp->mf_free_first; blocknr_T new_bnum;
page_count = hp->bh_page_count; bhdr_T *freep = mfp->mf_free_first;
int page_count = hp->bh_page_count;
if (freep != NULL && freep->bh_page_count >= page_count) { if (freep != NULL && freep->bh_page_count >= page_count) {
new_bnum = freep->bh_bnum; new_bnum = freep->bh_bnum;
// If the page count of the free block was larger, reduce it. // 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. /// The old number When not found.
blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr) blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
{ {
NR_TRANS *np; NR_TRANS *np = (NR_TRANS *)mf_hash_find(&mfp->mf_trans, old_nr);
blocknr_T new_bnum;
np = (NR_TRANS *)mf_hash_find(&mfp->mf_trans, old_nr);
if (np == NULL) // not found if (np == NULL) // not found
return old_nr; return old_nr;
mfp->mf_neg_count--; mfp->mf_neg_count--;
new_bnum = np->nt_new_bnum; blocknr_T new_bnum = np->nt_new_bnum;
// remove entry from the trans list // remove entry from the trans list
mf_hash_rem_item(&mfp->mf_trans, (mf_hashitem_T *)np); 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). /// "fname" must be in allocated memory, and is consumed (also when error).
/// ///
/// @param flags Flags for open(). /// @param flags Flags for open().
static void static void mf_do_open (memfile_T *mfp, char_u *fname, int flags)
mf_do_open (
memfile_T *mfp,
char_u *fname,
int flags /* flags for open() */
)
{ {
// fname cannot be NameBuff, because it must have been allocated. // fname cannot be NameBuff, because it must have been allocated.
mfp->mf_fname = fname; 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. /// Free the array of a hash table and all the items it contains.
static void mf_hash_free_all(mf_hashtab_T *mht) static void mf_hash_free_all(mf_hashtab_T *mht)
{ {
long_u idx; mf_hashitem_T *next;
mf_hashitem_T *mhi;
mf_hashitem_T *next;
for (idx = 0; idx <= mht->mht_mask; idx++) for (long_u idx = 0; idx <= mht->mht_mask; idx++)
for (mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next) { for (mf_hashitem_T *mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next) {
next = mhi->mhi_next; next = mhi->mhi_next;
free(mhi); 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. /// @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) static mf_hashitem_T *mf_hash_find(mf_hashtab_T *mht, blocknr_T key)
{ {
mf_hashitem_T *mhi; mf_hashitem_T *mhi = mht->mht_buckets[key & mht->mht_mask];
mhi = mht->mht_buckets[key & mht->mht_mask];
while (mhi != NULL && mhi->mhi_key != key) while (mhi != NULL && mhi->mhi_key != key)
mhi = mhi->mhi_next; mhi = mhi->mhi_next;
return mhi; return mhi;
} }
/// Add item to hashtable. Item must not be NULL. /// Add item to hashtable. Item must not be NULL.
static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi) static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
{ {
long_u idx; long_u idx = mhi->mhi_key & mht->mht_mask;
idx = mhi->mhi_key & mht->mht_mask;
mhi->mhi_next = mht->mht_buckets[idx]; mhi->mhi_next = mht->mht_buckets[idx];
mhi->mhi_prev = NULL; mhi->mhi_prev = NULL;
if (mhi->mhi_next != 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. /// rehash items.
static void mf_hash_grow(mf_hashtab_T *mht) static void mf_hash_grow(mf_hashtab_T *mht)
{ {
long_u i, j; size_t size = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR * sizeof(void *);
int shift; mf_hashitem_T **buckets = xcalloc(1, size);
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 *); int shift = 0;
buckets = xcalloc(1, size);
shift = 0;
while ((mht->mht_mask >> shift) != 0) while ((mht->mht_mask >> shift) != 0)
shift++; 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 /// Traverse the items in the i-th original bucket and move them into
/// MHT_GROWTH_FACTOR new buckets, preserving their relative order /// MHT_GROWTH_FACTOR new buckets, preserving their relative order
/// within each new bucket. Preserving the order is important because /// 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 /// Here we strongly rely on the fact that hashes are computed modulo
/// a power of two. /// a power of two.
mf_hashitem_T *tails[MHT_GROWTH_FACTOR];
memset(tails, 0, sizeof(tails)); memset(tails, 0, sizeof(tails));
for (mhi = mht->mht_buckets[i]; mhi != NULL; mhi = mhi->mhi_next) { for (mf_hashitem_T *mhi = mht->mht_buckets[i];
j = (mhi->mhi_key >> shift) & (MHT_GROWTH_FACTOR - 1); mhi != NULL; mhi = mhi->mhi_next) {
long_u j = (mhi->mhi_key >> shift) & (MHT_GROWTH_FACTOR - 1);
if (tails[j] == NULL) { if (tails[j] == NULL) {
buckets[i + (j << shift)] = mhi; buckets[i + (j << shift)] = mhi;
tails[j] = 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) if (tails[j] != NULL)
tails[j]->mhi_next = NULL; tails[j]->mhi_next = NULL;
} }

View File

@@ -3,8 +3,6 @@
#include "nvim/types.h" #include "nvim/types.h"
typedef struct block_hdr bhdr_T;
/// A block number. /// A block number.
/// ///
/// Blocks numbered from 0 upwards have been assigned a place in the actual /// 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 /// Therefore, items can be arbitrary data structures beginning with pointers
/// for the list and and a block number key. /// for the list and and a block number key.
typedef struct mf_hashitem_S mf_hashitem_T; typedef struct mf_hashitem_S {
struct mf_hashitem_S *mhi_next;
struct mf_hashitem_S { struct mf_hashitem_S *mhi_prev;
mf_hashitem_T *mhi_next;
mf_hashitem_T *mhi_prev;
blocknr_T mhi_key; blocknr_T mhi_key;
}; } mf_hashitem_T;
/// Initial size for a hashtable. /// Initial size for a hashtable.
#define MHT_INIT_SIZE 64 #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 free list is a single linked list, not sorted.
/// The blocks in the free list have no block of memory allocated and /// 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. /// 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 mf_hashitem_T bh_hashitem; /// header for hash table and key
#define bh_bnum bh_hashitem.mhi_key /// block number, part of bh_hashitem #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 struct block_hdr *bh_next; /// next block_hdr in free or used list
bhdr_T *bh_prev; /// previous block_hdr in used list struct block_hdr *bh_prev; /// previous block_hdr in used list
char_u *bh_data; /// pointer to memory (for used block) char_u *bh_data; /// pointer to memory (for used block)
int bh_page_count; /// number of pages in this block int bh_page_count; /// number of pages in this block
#define BH_DIRTY 1 #define BH_DIRTY 1
#define BH_LOCKED 2 #define BH_LOCKED 2
char bh_flags; // BH_DIRTY or BH_LOCKED char bh_flags; // BH_DIRTY or BH_LOCKED
}; } bhdr_T;
/// A block number translation list item. /// 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 /// 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 /// 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. /// double linked trans lists. The structure is the same as the hash lists.
typedef struct nr_trans NR_TRANS; typedef struct nr_trans {
struct nr_trans {
mf_hashitem_T nt_hashitem; /// header for hash table and key mf_hashitem_T nt_hashitem; /// header for hash table and key
#define nt_old_bnum nt_hashitem.mhi_key /// old, negative, number #define nt_old_bnum nt_hashitem.mhi_key /// old, negative, number
blocknr_T nt_new_bnum; /// new, positive, number blocknr_T nt_new_bnum; /// new, positive, number
}; } NR_TRANS;
/// A memory file. /// A memory file.
struct memfile { typedef struct memfile {
char_u *mf_fname; /// name of the file char_u *mf_fname; /// name of the file
char_u *mf_ffname; /// idem, full path char_u *mf_ffname; /// idem, full path
int mf_fd; /// file descriptor int mf_fd; /// file descriptor
@@ -107,6 +101,6 @@ struct memfile {
blocknr_T mf_infile_count; /// number of pages in the file blocknr_T mf_infile_count; /// number of pages in the file
unsigned mf_page_size; /// number of bytes in a page unsigned mf_page_size; /// number of bytes in a page
int mf_dirty; /// TRUE if there are dirty blocks int mf_dirty; /// TRUE if there are dirty blocks
}; } memfile_T;
#endif // NVIM_MEMFILE_DEFS_H #endif // NVIM_MEMFILE_DEFS_H