xref: /vim-8.2.3635/src/memfile.c (revision cf2d8dee)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * memfile.c: Contains the functions for handling blocks of memory which can
12  * be stored in a file. This is the implementation of a sort of virtual memory.
13  *
14  * A memfile consists of a sequence of blocks. The blocks numbered from 0
15  * upwards have been assigned a place in the actual file. The block number
16  * is equal to the page number in the file. The
17  * blocks with negative numbers are currently in memory only. They can be
18  * assigned a place in the file when too much memory is being used. At that
19  * moment they get a new, positive, number. A list is used for translation of
20  * negative to positive numbers.
21  *
22  * The size of a block is a multiple of a page size, normally the page size of
23  * the device the file is on. Most blocks are 1 page long. A Block of multiple
24  * pages is used for a line that does not fit in a single page.
25  *
26  * Each block can be in memory and/or in a file. The block stays in memory
27  * as long as it is locked. If it is no longer locked it can be swapped out to
28  * the file. It is only written to the file if it has been changed.
29  *
30  * Under normal operation the file is created when opening the memory file and
31  * deleted when closing the memory file. Only with recovery an existing memory
32  * file is opened.
33  */
34 
35 #include "vim.h"
36 
37 /*
38  * Some systems have the page size in statfs.f_bsize, some in stat.st_blksize
39  */
40 #ifdef HAVE_ST_BLKSIZE
41 # define STATFS stat
42 # define F_BSIZE st_blksize
43 # define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
44 #else
45 # ifdef HAVE_SYS_STATFS_H
46 #  include <sys/statfs.h>
47 #  define STATFS statfs
48 #  define F_BSIZE f_bsize
49 #  ifdef __MINT__		/* do we still need this? */
50 #   define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
51 #  endif
52 # endif
53 #endif
54 
55 /*
56  * for Amiga Dos 2.0x we use Flush
57  */
58 #ifdef AMIGA
59 # ifdef FEAT_ARP
60 extern int dos2;			/* this is in os_amiga.c */
61 # endif
62 # ifdef SASC
63 #  include <proto/dos.h>
64 #  include <ios1.h>			/* for chkufb() */
65 # endif
66 #endif
67 
68 #define MEMFILE_PAGE_SIZE 4096		/* default page size */
69 
70 static long_u	total_mem_used = 0;	/* total memory used for memfiles */
71 
72 static void mf_ins_hash(memfile_T *, bhdr_T *);
73 static void mf_rem_hash(memfile_T *, bhdr_T *);
74 static bhdr_T *mf_find_hash(memfile_T *, blocknr_T);
75 static void mf_ins_used(memfile_T *, bhdr_T *);
76 static void mf_rem_used(memfile_T *, bhdr_T *);
77 static bhdr_T *mf_release(memfile_T *, int);
78 static bhdr_T *mf_alloc_bhdr(memfile_T *, int);
79 static void mf_free_bhdr(bhdr_T *);
80 static void mf_ins_free(memfile_T *, bhdr_T *);
81 static bhdr_T *mf_rem_free(memfile_T *);
82 static int  mf_read(memfile_T *, bhdr_T *);
83 static int  mf_write(memfile_T *, bhdr_T *);
84 static int  mf_write_block(memfile_T *mfp, bhdr_T *hp, off_t offset, unsigned size);
85 static int  mf_trans_add(memfile_T *, bhdr_T *);
86 static void mf_do_open(memfile_T *, char_u *, int);
87 static void mf_hash_init(mf_hashtab_T *);
88 static void mf_hash_free(mf_hashtab_T *);
89 static void mf_hash_free_all(mf_hashtab_T *);
90 static mf_hashitem_T *mf_hash_find(mf_hashtab_T *, blocknr_T);
91 static void mf_hash_add_item(mf_hashtab_T *, mf_hashitem_T *);
92 static void mf_hash_rem_item(mf_hashtab_T *, mf_hashitem_T *);
93 static int mf_hash_grow(mf_hashtab_T *);
94 
95 /*
96  * The functions for using a memfile:
97  *
98  * mf_open()	    open a new or existing memfile
99  * mf_open_file()   open a swap file for an existing memfile
100  * mf_close()	    close (and delete) a memfile
101  * mf_new()	    create a new block in a memfile and lock it
102  * mf_get()	    get an existing block and lock it
103  * mf_put()	    unlock a block, may be marked for writing
104  * mf_free()	    remove a block
105  * mf_sync()	    sync changed parts of memfile to disk
106  * mf_release_all() release as much memory as possible
107  * mf_trans_del()   may translate negative to positive block number
108  * mf_fullname()    make file name full path (use before first :cd)
109  */
110 
111 /*
112  * Open an existing or new memory block file.
113  *
114  *  fname:	name of file to use (NULL means no file at all)
115  *		Note: fname must have been allocated, it is not copied!
116  *			If opening the file fails, fname is freed.
117  *  flags:	flags for open() call
118  *
119  *  If fname != NULL and file cannot be opened, fail.
120  *
121  * return value: identifier for this memory block file.
122  */
123     memfile_T *
124 mf_open(char_u *fname, int flags)
125 {
126     memfile_T		*mfp;
127     off_t		size;
128 #if defined(STATFS) && defined(UNIX) && !defined(__QNX__) && !defined(__minix)
129 # define USE_FSTATFS
130     struct STATFS	stf;
131 #endif
132 
133     if ((mfp = (memfile_T *)alloc((unsigned)sizeof(memfile_T))) == NULL)
134 	return NULL;
135 
136     if (fname == NULL)	    /* no file for this memfile, use memory only */
137     {
138 	mfp->mf_fname = NULL;
139 	mfp->mf_ffname = NULL;
140 	mfp->mf_fd = -1;
141     }
142     else
143     {
144 	mf_do_open(mfp, fname, flags);	/* try to open the file */
145 
146 	/* if the file cannot be opened, return here */
147 	if (mfp->mf_fd < 0)
148 	{
149 	    vim_free(mfp);
150 	    return NULL;
151 	}
152     }
153 
154     mfp->mf_free_first = NULL;		/* free list is empty */
155     mfp->mf_used_first = NULL;		/* used list is empty */
156     mfp->mf_used_last = NULL;
157     mfp->mf_dirty = FALSE;
158     mfp->mf_used_count = 0;
159     mf_hash_init(&mfp->mf_hash);
160     mf_hash_init(&mfp->mf_trans);
161     mfp->mf_page_size = MEMFILE_PAGE_SIZE;
162 #ifdef FEAT_CRYPT
163     mfp->mf_old_key = NULL;
164 #endif
165 
166 #ifdef USE_FSTATFS
167     /*
168      * Try to set the page size equal to the block size of the device.
169      * Speeds up I/O a lot.
170      * When recovering, the actual block size will be retrieved from block 0
171      * in ml_recover().  The size used here may be wrong, therefore
172      * mf_blocknr_max must be rounded up.
173      */
174     if (mfp->mf_fd >= 0
175 	    && fstatfs(mfp->mf_fd, &stf, sizeof(struct statfs), 0) == 0
176 	    && stf.F_BSIZE >= MIN_SWAP_PAGE_SIZE
177 	    && stf.F_BSIZE <= MAX_SWAP_PAGE_SIZE)
178 	mfp->mf_page_size = stf.F_BSIZE;
179 #endif
180 
181     if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
182 		      || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
183 	mfp->mf_blocknr_max = 0;	/* no file or empty file */
184     else
185 	mfp->mf_blocknr_max = (blocknr_T)((size + mfp->mf_page_size - 1)
186 							 / mfp->mf_page_size);
187     mfp->mf_blocknr_min = -1;
188     mfp->mf_neg_count = 0;
189     mfp->mf_infile_count = mfp->mf_blocknr_max;
190 
191     /*
192      * Compute maximum number of pages ('maxmem' is in Kbyte):
193      *	'mammem' * 1Kbyte / page-size-in-bytes.
194      * Avoid overflow by first reducing page size as much as possible.
195      */
196     {
197 	int	    shift = 10;
198 	unsigned    page_size = mfp->mf_page_size;
199 
200 	while (shift > 0 && (page_size & 1) == 0)
201 	{
202 	    page_size = page_size >> 1;
203 	    --shift;
204 	}
205 	mfp->mf_used_count_max = (p_mm << shift) / page_size;
206 	if (mfp->mf_used_count_max < 10)
207 	    mfp->mf_used_count_max = 10;
208     }
209 
210     return mfp;
211 }
212 
213 /*
214  * Open a file for an existing memfile.  Used when updatecount set from 0 to
215  * some value.
216  * If the file already exists, this fails.
217  * "fname" is the name of file to use (NULL means no file at all)
218  * Note: "fname" must have been allocated, it is not copied!  If opening the
219  * file fails, "fname" is freed.
220  *
221  * return value: FAIL if file could not be opened, OK otherwise
222  */
223     int
224 mf_open_file(memfile_T *mfp, char_u *fname)
225 {
226     mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); /* try to open the file */
227 
228     if (mfp->mf_fd < 0)
229 	return FAIL;
230 
231     mfp->mf_dirty = TRUE;
232     return OK;
233 }
234 
235 /*
236  * Close a memory file and delete the associated file if 'del_file' is TRUE.
237  */
238     void
239 mf_close(memfile_T *mfp, int del_file)
240 {
241     bhdr_T	*hp, *nextp;
242 
243     if (mfp == NULL)		    /* safety check */
244 	return;
245     if (mfp->mf_fd >= 0)
246     {
247 	if (close(mfp->mf_fd) < 0)
248 	    EMSG(_(e_swapclose));
249     }
250     if (del_file && mfp->mf_fname != NULL)
251 	mch_remove(mfp->mf_fname);
252 					    /* free entries in used list */
253     for (hp = mfp->mf_used_first; hp != NULL; hp = nextp)
254     {
255 	total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
256 	nextp = hp->bh_next;
257 	mf_free_bhdr(hp);
258     }
259     while (mfp->mf_free_first != NULL)	    /* free entries in free list */
260 	vim_free(mf_rem_free(mfp));
261     mf_hash_free(&mfp->mf_hash);
262     mf_hash_free_all(&mfp->mf_trans);	    /* free hashtable and its items */
263     vim_free(mfp->mf_fname);
264     vim_free(mfp->mf_ffname);
265     vim_free(mfp);
266 }
267 
268 /*
269  * Close the swap file for a memfile.  Used when 'swapfile' is reset.
270  */
271     void
272 mf_close_file(
273     buf_T	*buf,
274     int		getlines)	/* get all lines into memory? */
275 {
276     memfile_T	*mfp;
277     linenr_T	lnum;
278 
279     mfp = buf->b_ml.ml_mfp;
280     if (mfp == NULL || mfp->mf_fd < 0)		/* nothing to close */
281 	return;
282 
283     if (getlines)
284     {
285 	/* get all blocks in memory by accessing all lines (clumsy!) */
286 	mf_dont_release = TRUE;
287 	for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
288 	    (void)ml_get_buf(buf, lnum, FALSE);
289 	mf_dont_release = FALSE;
290 	/* TODO: should check if all blocks are really in core */
291     }
292 
293     if (close(mfp->mf_fd) < 0)			/* close the file */
294 	EMSG(_(e_swapclose));
295     mfp->mf_fd = -1;
296 
297     if (mfp->mf_fname != NULL)
298     {
299 	mch_remove(mfp->mf_fname);		/* delete the swap file */
300 	vim_free(mfp->mf_fname);
301 	vim_free(mfp->mf_ffname);
302 	mfp->mf_fname = NULL;
303 	mfp->mf_ffname = NULL;
304     }
305 }
306 
307 /*
308  * Set new size for a memfile.  Used when block 0 of a swapfile has been read
309  * and the size it indicates differs from what was guessed.
310  */
311     void
312 mf_new_page_size(memfile_T *mfp, unsigned new_size)
313 {
314     /* Correct the memory used for block 0 to the new size, because it will be
315      * freed with that size later on. */
316     total_mem_used += new_size - mfp->mf_page_size;
317     mfp->mf_page_size = new_size;
318 }
319 
320 /*
321  * get a new block
322  *
323  *   negative: TRUE if negative block number desired (data block)
324  */
325     bhdr_T *
326 mf_new(memfile_T *mfp, int negative, int page_count)
327 {
328     bhdr_T	*hp;	/* new bhdr_T */
329     bhdr_T	*freep;	/* first block in free list */
330     char_u	*p;
331 
332     /*
333      * If we reached the maximum size for the used memory blocks, release one
334      * If a bhdr_T is returned, use it and adjust the page_count if necessary.
335      */
336     hp = mf_release(mfp, page_count);
337 
338 /*
339  * Decide on the number to use:
340  * If there is a free block, use its number.
341  * Otherwise use mf_block_min for a negative number, mf_block_max for
342  * a positive number.
343  */
344     freep = mfp->mf_free_first;
345     if (!negative && freep != NULL && freep->bh_page_count >= page_count)
346     {
347 	/*
348 	 * If the block in the free list has more pages, take only the number
349 	 * of pages needed and allocate a new bhdr_T with data
350 	 *
351 	 * If the number of pages matches and mf_release() did not return a
352 	 * bhdr_T, use the bhdr_T from the free list and allocate the data
353 	 *
354 	 * If the number of pages matches and mf_release() returned a bhdr_T,
355 	 * just use the number and free the bhdr_T from the free list
356 	 */
357 	if (freep->bh_page_count > page_count)
358 	{
359 	    if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
360 		return NULL;
361 	    hp->bh_bnum = freep->bh_bnum;
362 	    freep->bh_bnum += page_count;
363 	    freep->bh_page_count -= page_count;
364 	}
365 	else if (hp == NULL)	    /* need to allocate memory for this block */
366 	{
367 	    if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
368 		return NULL;
369 	    hp = mf_rem_free(mfp);
370 	    hp->bh_data = p;
371 	}
372 	else		    /* use the number, remove entry from free list */
373 	{
374 	    freep = mf_rem_free(mfp);
375 	    hp->bh_bnum = freep->bh_bnum;
376 	    vim_free(freep);
377 	}
378     }
379     else	/* get a new number */
380     {
381 	if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
382 	    return NULL;
383 	if (negative)
384 	{
385 	    hp->bh_bnum = mfp->mf_blocknr_min--;
386 	    mfp->mf_neg_count++;
387 	}
388 	else
389 	{
390 	    hp->bh_bnum = mfp->mf_blocknr_max;
391 	    mfp->mf_blocknr_max += page_count;
392 	}
393     }
394     hp->bh_flags = BH_LOCKED | BH_DIRTY;	/* new block is always dirty */
395     mfp->mf_dirty = TRUE;
396     hp->bh_page_count = page_count;
397     mf_ins_used(mfp, hp);
398     mf_ins_hash(mfp, hp);
399 
400     /*
401      * Init the data to all zero, to avoid reading uninitialized data.
402      * This also avoids that the passwd file ends up in the swap file!
403      */
404     (void)vim_memset((char *)(hp->bh_data), 0,
405 				      (size_t)mfp->mf_page_size * page_count);
406 
407     return hp;
408 }
409 
410 /*
411  * Get existing block "nr" with "page_count" pages.
412  *
413  * Note: The caller should first check a negative nr with mf_trans_del()
414  */
415     bhdr_T *
416 mf_get(memfile_T *mfp, blocknr_T nr, int page_count)
417 {
418     bhdr_T    *hp;
419 						/* doesn't exist */
420     if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
421 	return NULL;
422 
423     /*
424      * see if it is in the cache
425      */
426     hp = mf_find_hash(mfp, nr);
427     if (hp == NULL)	/* not in the hash list */
428     {
429 	if (nr < 0 || nr >= mfp->mf_infile_count)   /* can't be in the file */
430 	    return NULL;
431 
432 	/* could check here if the block is in the free list */
433 
434 	/*
435 	 * Check if we need to flush an existing block.
436 	 * If so, use that block.
437 	 * If not, allocate a new block.
438 	 */
439 	hp = mf_release(mfp, page_count);
440 	if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
441 	    return NULL;
442 
443 	hp->bh_bnum = nr;
444 	hp->bh_flags = 0;
445 	hp->bh_page_count = page_count;
446 	if (mf_read(mfp, hp) == FAIL)	    /* cannot read the block! */
447 	{
448 	    mf_free_bhdr(hp);
449 	    return NULL;
450 	}
451     }
452     else
453     {
454 	mf_rem_used(mfp, hp);	/* remove from list, insert in front below */
455 	mf_rem_hash(mfp, hp);
456     }
457 
458     hp->bh_flags |= BH_LOCKED;
459     mf_ins_used(mfp, hp);	/* put in front of used list */
460     mf_ins_hash(mfp, hp);	/* put in front of hash list */
461 
462     return hp;
463 }
464 
465 /*
466  * release the block *hp
467  *
468  *   dirty: Block must be written to file later
469  *   infile: Block should be in file (needed for recovery)
470  *
471  *  no return value, function cannot fail
472  */
473     void
474 mf_put(
475     memfile_T	*mfp,
476     bhdr_T	*hp,
477     int		dirty,
478     int		infile)
479 {
480     int		flags;
481 
482     flags = hp->bh_flags;
483 
484     if ((flags & BH_LOCKED) == 0)
485 	EMSG(_("E293: block was not locked"));
486     flags &= ~BH_LOCKED;
487     if (dirty)
488     {
489 	flags |= BH_DIRTY;
490 	mfp->mf_dirty = TRUE;
491     }
492     hp->bh_flags = flags;
493     if (infile)
494 	mf_trans_add(mfp, hp);	    /* may translate negative in positive nr */
495 }
496 
497 /*
498  * block *hp is no longer in used, may put it in the free list of memfile *mfp
499  */
500     void
501 mf_free(memfile_T *mfp, bhdr_T *hp)
502 {
503     vim_free(hp->bh_data);	/* free the memory */
504     mf_rem_hash(mfp, hp);	/* get *hp out of the hash list */
505     mf_rem_used(mfp, hp);	/* get *hp out of the used list */
506     if (hp->bh_bnum < 0)
507     {
508 	vim_free(hp);		/* don't want negative numbers in free list */
509 	mfp->mf_neg_count--;
510     }
511     else
512 	mf_ins_free(mfp, hp);	/* put *hp in the free list */
513 }
514 
515 #if defined(__MORPHOS__) && defined(__libnix__)
516 /* function is missing in MorphOS libnix version */
517 extern unsigned long *__stdfiledes;
518 
519     static unsigned long
520 fdtofh(int filedescriptor)
521 {
522     return __stdfiledes[filedescriptor];
523 }
524 #endif
525 
526 /*
527  * Sync the memory file *mfp to disk.
528  * Flags:
529  *  MFS_ALL	If not given, blocks with negative numbers are not synced,
530  *		even when they are dirty!
531  *  MFS_STOP	Stop syncing when a character becomes available, but sync at
532  *		least one block.
533  *  MFS_FLUSH	Make sure buffers are flushed to disk, so they will survive a
534  *		system crash.
535  *  MFS_ZERO	Only write block 0.
536  *
537  * Return FAIL for failure, OK otherwise
538  */
539     int
540 mf_sync(memfile_T *mfp, int flags)
541 {
542     int		status;
543     bhdr_T	*hp;
544 #if defined(SYNC_DUP_CLOSE)
545     int		fd;
546 #endif
547     int		got_int_save = got_int;
548 
549     if (mfp->mf_fd < 0)	    /* there is no file, nothing to do */
550     {
551 	mfp->mf_dirty = FALSE;
552 	return FAIL;
553     }
554 
555     /* Only a CTRL-C while writing will break us here, not one typed
556      * previously. */
557     got_int = FALSE;
558 
559     /*
560      * sync from last to first (may reduce the probability of an inconsistent
561      * file) If a write fails, it is very likely caused by a full filesystem.
562      * Then we only try to write blocks within the existing file. If that also
563      * fails then we give up.
564      */
565     status = OK;
566     for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
567 	if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
568 		&& (hp->bh_flags & BH_DIRTY)
569 		&& (status == OK || (hp->bh_bnum >= 0
570 		    && hp->bh_bnum < mfp->mf_infile_count)))
571 	{
572 	    if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
573 		continue;
574 	    if (mf_write(mfp, hp) == FAIL)
575 	    {
576 		if (status == FAIL)	/* double error: quit syncing */
577 		    break;
578 		status = FAIL;
579 	    }
580 	    if (flags & MFS_STOP)
581 	    {
582 		/* Stop when char available now. */
583 		if (ui_char_avail())
584 		    break;
585 	    }
586 	    else
587 		ui_breakcheck();
588 	    if (got_int)
589 		break;
590 	}
591 
592     /*
593      * If the whole list is flushed, the memfile is not dirty anymore.
594      * In case of an error this flag is also set, to avoid trying all the time.
595      */
596     if (hp == NULL || status == FAIL)
597 	mfp->mf_dirty = FALSE;
598 
599     if ((flags & MFS_FLUSH) && *p_sws != NUL)
600     {
601 #if defined(UNIX)
602 # ifdef HAVE_FSYNC
603 	/*
604 	 * most Unixes have the very useful fsync() function, just what we need.
605 	 * However, with OS/2 and EMX it is also available, but there are
606 	 * reports of bad problems with it (a bug in HPFS.IFS).
607 	 * So we disable use of it here in case someone tries to be smart
608 	 * and changes os_os2_cfg.h... (even though there is no __EMX__ test
609 	 * in the #if, as __EMX__ does not have sync(); we hope for a timely
610 	 * sync from the system itself).
611 	 */
612 #  if defined(__EMX__)
613    error "Don't use fsync with EMX! Read emxdoc.doc or emxfix01.doc for info."
614 #  endif
615 	if (STRCMP(p_sws, "fsync") == 0)
616 	{
617 	    if (fsync(mfp->mf_fd))
618 		status = FAIL;
619 	}
620 	else
621 # endif
622 	    /* OpenNT is strictly POSIX (Benzinger) */
623 	    /* Tandem/Himalaya NSK-OSS doesn't have sync() */
624 	    /* No sync() on Stratus VOS */
625 # if defined(__OPENNT) || defined(__TANDEM) || defined(__VOS__)
626 	    fflush(NULL);
627 # else
628 	    sync();
629 # endif
630 #endif
631 #ifdef VMS
632 	if (STRCMP(p_sws, "fsync") == 0)
633 	{
634 	    if (fsync(mfp->mf_fd))
635 		status = FAIL;
636 	}
637 #endif
638 #ifdef SYNC_DUP_CLOSE
639 	/*
640 	 * Win32 is a bit more work: Duplicate the file handle and close it.
641 	 * This should flush the file to disk.
642 	 */
643 	if ((fd = dup(mfp->mf_fd)) >= 0)
644 	    close(fd);
645 #endif
646 #ifdef AMIGA
647 # if defined(__AROS__) || defined(__amigaos4__)
648 	if (fsync(mfp->mf_fd) != 0)
649 	    status = FAIL;
650 # else
651 	/*
652 	 * Flush() only exists for AmigaDos 2.0.
653 	 * For 1.3 it should be done with close() + open(), but then the risk
654 	 * is that the open() may fail and lose the file....
655 	 */
656 #  ifdef FEAT_ARP
657 	if (dos2)
658 #  endif
659 #  ifdef SASC
660 	{
661 	    struct UFB *fp = chkufb(mfp->mf_fd);
662 
663 	    if (fp != NULL)
664 		Flush(fp->ufbfh);
665 	}
666 #  else
667 #   if defined(_DCC) || defined(__GNUC__) || defined(__MORPHOS__)
668 	{
669 #    if defined(__GNUC__) && !defined(__MORPHOS__) && defined(__libnix__)
670 	    /* Have function (in libnix at least),
671 	     * but ain't got no prototype anywhere. */
672 	    extern unsigned long fdtofh(int filedescriptor);
673 #    endif
674 #    if !defined(__libnix__)
675 	    fflush(NULL);
676 #    else
677 	    BPTR fh = (BPTR)fdtofh(mfp->mf_fd);
678 
679 	    if (fh != 0)
680 		Flush(fh);
681 #    endif
682 	}
683 #   else /* assume Manx */
684 	    Flush(_devtab[mfp->mf_fd].fd);
685 #   endif
686 #  endif
687 # endif
688 #endif /* AMIGA */
689     }
690 
691     got_int |= got_int_save;
692 
693     return status;
694 }
695 
696 /*
697  * For all blocks in memory file *mfp that have a positive block number set
698  * the dirty flag.  These are blocks that need to be written to a newly
699  * created swapfile.
700  */
701     void
702 mf_set_dirty(memfile_T *mfp)
703 {
704     bhdr_T	*hp;
705 
706     for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
707 	if (hp->bh_bnum > 0)
708 	    hp->bh_flags |= BH_DIRTY;
709     mfp->mf_dirty = TRUE;
710 }
711 
712 /*
713  * insert block *hp in front of hashlist of memfile *mfp
714  */
715     static void
716 mf_ins_hash(memfile_T *mfp, bhdr_T *hp)
717 {
718     mf_hash_add_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
719 }
720 
721 /*
722  * remove block *hp from hashlist of memfile list *mfp
723  */
724     static void
725 mf_rem_hash(memfile_T *mfp, bhdr_T *hp)
726 {
727     mf_hash_rem_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
728 }
729 
730 /*
731  * look in hash lists of memfile *mfp for block header with number 'nr'
732  */
733     static bhdr_T *
734 mf_find_hash(memfile_T *mfp, blocknr_T nr)
735 {
736     return (bhdr_T *)mf_hash_find(&mfp->mf_hash, nr);
737 }
738 
739 /*
740  * insert block *hp in front of used list of memfile *mfp
741  */
742     static void
743 mf_ins_used(memfile_T *mfp, bhdr_T *hp)
744 {
745     hp->bh_next = mfp->mf_used_first;
746     mfp->mf_used_first = hp;
747     hp->bh_prev = NULL;
748     if (hp->bh_next == NULL)	    /* list was empty, adjust last pointer */
749 	mfp->mf_used_last = hp;
750     else
751 	hp->bh_next->bh_prev = hp;
752     mfp->mf_used_count += hp->bh_page_count;
753     total_mem_used += hp->bh_page_count * mfp->mf_page_size;
754 }
755 
756 /*
757  * remove block *hp from used list of memfile *mfp
758  */
759     static void
760 mf_rem_used(memfile_T *mfp, bhdr_T *hp)
761 {
762     if (hp->bh_next == NULL)	    /* last block in used list */
763 	mfp->mf_used_last = hp->bh_prev;
764     else
765 	hp->bh_next->bh_prev = hp->bh_prev;
766     if (hp->bh_prev == NULL)	    /* first block in used list */
767 	mfp->mf_used_first = hp->bh_next;
768     else
769 	hp->bh_prev->bh_next = hp->bh_next;
770     mfp->mf_used_count -= hp->bh_page_count;
771     total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
772 }
773 
774 /*
775  * Release the least recently used block from the used list if the number
776  * of used memory blocks gets to big.
777  *
778  * Return the block header to the caller, including the memory block, so
779  * it can be re-used. Make sure the page_count is right.
780  *
781  * Returns NULL if no block is released.
782  */
783     static bhdr_T *
784 mf_release(memfile_T *mfp, int page_count)
785 {
786     bhdr_T	*hp;
787     int		need_release;
788     buf_T	*buf;
789 
790     /* don't release while in mf_close_file() */
791     if (mf_dont_release)
792 	return NULL;
793 
794     /*
795      * Need to release a block if the number of blocks for this memfile is
796      * higher than the maximum or total memory used is over 'maxmemtot'
797      */
798     need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max)
799 				  || (total_mem_used >> 10) >= (long_u)p_mmt);
800 
801     /*
802      * Try to create a swap file if the amount of memory used is getting too
803      * high.
804      */
805     if (mfp->mf_fd < 0 && need_release && p_uc)
806     {
807 	/* find for which buffer this memfile is */
808 	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
809 	    if (buf->b_ml.ml_mfp == mfp)
810 		break;
811 	if (buf != NULL && buf->b_may_swap)
812 	    ml_open_file(buf);
813     }
814 
815     /*
816      * don't release a block if
817      *	there is no file for this memfile
818      * or
819      *	the number of blocks for this memfile is lower than the maximum
820      *	  and
821      *	total memory used is not up to 'maxmemtot'
822      */
823     if (mfp->mf_fd < 0 || !need_release)
824 	return NULL;
825 
826     for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
827 	if (!(hp->bh_flags & BH_LOCKED))
828 	    break;
829     if (hp == NULL)	/* not a single one that can be released */
830 	return NULL;
831 
832     /*
833      * If the block is dirty, write it.
834      * If the write fails we don't free it.
835      */
836     if ((hp->bh_flags & BH_DIRTY) && mf_write(mfp, hp) == FAIL)
837 	return NULL;
838 
839     mf_rem_used(mfp, hp);
840     mf_rem_hash(mfp, hp);
841 
842     /*
843      * If a bhdr_T is returned, make sure that the page_count of bh_data is
844      * right
845      */
846     if (hp->bh_page_count != page_count)
847     {
848 	vim_free(hp->bh_data);
849 	if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL)
850 	{
851 	    vim_free(hp);
852 	    return NULL;
853 	}
854 	hp->bh_page_count = page_count;
855     }
856     return hp;
857 }
858 
859 /*
860  * release as many blocks as possible
861  * Used in case of out of memory
862  *
863  * return TRUE if any memory was released
864  */
865     int
866 mf_release_all(void)
867 {
868     buf_T	*buf;
869     memfile_T	*mfp;
870     bhdr_T	*hp;
871     int		retval = FALSE;
872 
873     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
874     {
875 	mfp = buf->b_ml.ml_mfp;
876 	if (mfp != NULL)
877 	{
878 	    /* If no swap file yet, may open one */
879 	    if (mfp->mf_fd < 0 && buf->b_may_swap)
880 		ml_open_file(buf);
881 
882 	    /* only if there is a swapfile */
883 	    if (mfp->mf_fd >= 0)
884 	    {
885 		for (hp = mfp->mf_used_last; hp != NULL; )
886 		{
887 		    if (!(hp->bh_flags & BH_LOCKED)
888 			    && (!(hp->bh_flags & BH_DIRTY)
889 				|| mf_write(mfp, hp) != FAIL))
890 		    {
891 			mf_rem_used(mfp, hp);
892 			mf_rem_hash(mfp, hp);
893 			mf_free_bhdr(hp);
894 			hp = mfp->mf_used_last;	/* re-start, list was changed */
895 			retval = TRUE;
896 		    }
897 		    else
898 			hp = hp->bh_prev;
899 		}
900 	    }
901 	}
902     }
903     return retval;
904 }
905 
906 /*
907  * Allocate a block header and a block of memory for it
908  */
909     static bhdr_T *
910 mf_alloc_bhdr(memfile_T *mfp, int page_count)
911 {
912     bhdr_T	*hp;
913 
914     if ((hp = (bhdr_T *)alloc((unsigned)sizeof(bhdr_T))) != NULL)
915     {
916 	if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count))
917 								      == NULL)
918 	{
919 	    vim_free(hp);	    /* not enough memory */
920 	    return NULL;
921 	}
922 	hp->bh_page_count = page_count;
923     }
924     return hp;
925 }
926 
927 /*
928  * Free a block header and the block of memory for it
929  */
930     static void
931 mf_free_bhdr(bhdr_T *hp)
932 {
933     vim_free(hp->bh_data);
934     vim_free(hp);
935 }
936 
937 /*
938  * insert entry *hp in the free list
939  */
940     static void
941 mf_ins_free(memfile_T *mfp, bhdr_T *hp)
942 {
943     hp->bh_next = mfp->mf_free_first;
944     mfp->mf_free_first = hp;
945 }
946 
947 /*
948  * remove the first entry from the free list and return a pointer to it
949  * Note: caller must check that mfp->mf_free_first is not NULL!
950  */
951     static bhdr_T *
952 mf_rem_free(memfile_T *mfp)
953 {
954     bhdr_T	*hp;
955 
956     hp = mfp->mf_free_first;
957     mfp->mf_free_first = hp->bh_next;
958     return hp;
959 }
960 
961 /*
962  * read a block from disk
963  *
964  * Return FAIL for failure, OK otherwise
965  */
966     static int
967 mf_read(memfile_T *mfp, bhdr_T *hp)
968 {
969     off_t	offset;
970     unsigned	page_size;
971     unsigned	size;
972 
973     if (mfp->mf_fd < 0)	    /* there is no file, can't read */
974 	return FAIL;
975 
976     page_size = mfp->mf_page_size;
977     offset = (off_t)page_size * hp->bh_bnum;
978     size = page_size * hp->bh_page_count;
979     if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
980     {
981 	PERROR(_("E294: Seek error in swap file read"));
982 	return FAIL;
983     }
984     if ((unsigned)read_eintr(mfp->mf_fd, hp->bh_data, size) != size)
985     {
986 	PERROR(_("E295: Read error in swap file"));
987 	return FAIL;
988     }
989 
990 #ifdef FEAT_CRYPT
991     /* Decrypt if 'key' is set and this is a data block. And when changing the
992      * key. */
993     if (*mfp->mf_buffer->b_p_key != NUL || mfp->mf_old_key != NULL)
994 	ml_decrypt_data(mfp, hp->bh_data, offset, size);
995 #endif
996 
997     return OK;
998 }
999 
1000 /*
1001  * write a block to disk
1002  *
1003  * Return FAIL for failure, OK otherwise
1004  */
1005     static int
1006 mf_write(memfile_T *mfp, bhdr_T *hp)
1007 {
1008     off_t	offset;	    /* offset in the file */
1009     blocknr_T	nr;	    /* block nr which is being written */
1010     bhdr_T	*hp2;
1011     unsigned	page_size;  /* number of bytes in a page */
1012     unsigned	page_count; /* number of pages written */
1013     unsigned	size;	    /* number of bytes written */
1014 
1015     if (mfp->mf_fd < 0)	    /* there is no file, can't write */
1016 	return FAIL;
1017 
1018     if (hp->bh_bnum < 0)	/* must assign file block number */
1019 	if (mf_trans_add(mfp, hp) == FAIL)
1020 	    return FAIL;
1021 
1022     page_size = mfp->mf_page_size;
1023 
1024     /*
1025      * We don't want gaps in the file. Write the blocks in front of *hp
1026      * to extend the file.
1027      * If block 'mf_infile_count' is not in the hash list, it has been
1028      * freed. Fill the space in the file with data from the current block.
1029      */
1030     for (;;)
1031     {
1032 	nr = hp->bh_bnum;
1033 	if (nr > mfp->mf_infile_count)		/* beyond end of file */
1034 	{
1035 	    nr = mfp->mf_infile_count;
1036 	    hp2 = mf_find_hash(mfp, nr);	/* NULL caught below */
1037 	}
1038 	else
1039 	    hp2 = hp;
1040 
1041 	offset = (off_t)page_size * nr;
1042 	if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
1043 	{
1044 	    PERROR(_("E296: Seek error in swap file write"));
1045 	    return FAIL;
1046 	}
1047 	if (hp2 == NULL)	    /* freed block, fill with dummy data */
1048 	    page_count = 1;
1049 	else
1050 	    page_count = hp2->bh_page_count;
1051 	size = page_size * page_count;
1052 	if (mf_write_block(mfp, hp2 == NULL ? hp : hp2, offset, size) == FAIL)
1053 	{
1054 	    /*
1055 	     * Avoid repeating the error message, this mostly happens when the
1056 	     * disk is full. We give the message again only after a successful
1057 	     * write or when hitting a key. We keep on trying, in case some
1058 	     * space becomes available.
1059 	     */
1060 	    if (!did_swapwrite_msg)
1061 		EMSG(_("E297: Write error in swap file"));
1062 	    did_swapwrite_msg = TRUE;
1063 	    return FAIL;
1064 	}
1065 	did_swapwrite_msg = FALSE;
1066 	if (hp2 != NULL)		    /* written a non-dummy block */
1067 	    hp2->bh_flags &= ~BH_DIRTY;
1068 					    /* appended to the file */
1069 	if (nr + (blocknr_T)page_count > mfp->mf_infile_count)
1070 	    mfp->mf_infile_count = nr + page_count;
1071 	if (nr == hp->bh_bnum)		    /* written the desired block */
1072 	    break;
1073     }
1074     return OK;
1075 }
1076 
1077 /*
1078  * Write block "hp" with data size "size" to file "mfp->mf_fd".
1079  * Takes care of encryption.
1080  * Return FAIL or OK.
1081  */
1082     static int
1083 mf_write_block(
1084     memfile_T	*mfp,
1085     bhdr_T	*hp,
1086     off_t	offset UNUSED,
1087     unsigned	size)
1088 {
1089     char_u	*data = hp->bh_data;
1090     int		result = OK;
1091 
1092 #ifdef FEAT_CRYPT
1093     /* Encrypt if 'key' is set and this is a data block. */
1094     if (*mfp->mf_buffer->b_p_key != NUL)
1095     {
1096 	data = ml_encrypt_data(mfp, data, offset, size);
1097 	if (data == NULL)
1098 	    return FAIL;
1099     }
1100 #endif
1101 
1102     if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size)
1103 	result = FAIL;
1104 
1105 #ifdef FEAT_CRYPT
1106     if (data != hp->bh_data)
1107 	vim_free(data);
1108 #endif
1109 
1110     return result;
1111 }
1112 
1113 /*
1114  * Make block number for *hp positive and add it to the translation list
1115  *
1116  * Return FAIL for failure, OK otherwise
1117  */
1118     static int
1119 mf_trans_add(memfile_T *mfp, bhdr_T *hp)
1120 {
1121     bhdr_T	*freep;
1122     blocknr_T	new_bnum;
1123     NR_TRANS	*np;
1124     int		page_count;
1125 
1126     if (hp->bh_bnum >= 0)		    /* it's already positive */
1127 	return OK;
1128 
1129     if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL)
1130 	return FAIL;
1131 
1132 /*
1133  * Get a new number for the block.
1134  * If the first item in the free list has sufficient pages, use its number
1135  * Otherwise use mf_blocknr_max.
1136  */
1137     freep = mfp->mf_free_first;
1138     page_count = hp->bh_page_count;
1139     if (freep != NULL && freep->bh_page_count >= page_count)
1140     {
1141 	new_bnum = freep->bh_bnum;
1142 	/*
1143 	 * If the page count of the free block was larger, reduce it.
1144 	 * If the page count matches, remove the block from the free list
1145 	 */
1146 	if (freep->bh_page_count > page_count)
1147 	{
1148 	    freep->bh_bnum += page_count;
1149 	    freep->bh_page_count -= page_count;
1150 	}
1151 	else
1152 	{
1153 	    freep = mf_rem_free(mfp);
1154 	    vim_free(freep);
1155 	}
1156     }
1157     else
1158     {
1159 	new_bnum = mfp->mf_blocknr_max;
1160 	mfp->mf_blocknr_max += page_count;
1161     }
1162 
1163     np->nt_old_bnum = hp->bh_bnum;	    /* adjust number */
1164     np->nt_new_bnum = new_bnum;
1165 
1166     mf_rem_hash(mfp, hp);		    /* remove from old hash list */
1167     hp->bh_bnum = new_bnum;
1168     mf_ins_hash(mfp, hp);		    /* insert in new hash list */
1169 
1170     /* Insert "np" into "mf_trans" hashtable with key "np->nt_old_bnum" */
1171     mf_hash_add_item(&mfp->mf_trans, (mf_hashitem_T *)np);
1172 
1173     return OK;
1174 }
1175 
1176 /*
1177  * Lookup a translation from the trans lists and delete the entry.
1178  *
1179  * Return the positive new number when found, the old number when not found
1180  */
1181     blocknr_T
1182 mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
1183 {
1184     NR_TRANS	*np;
1185     blocknr_T	new_bnum;
1186 
1187     np = (NR_TRANS *)mf_hash_find(&mfp->mf_trans, old_nr);
1188 
1189     if (np == NULL)		/* not found */
1190 	return old_nr;
1191 
1192     mfp->mf_neg_count--;
1193     new_bnum = np->nt_new_bnum;
1194 
1195     /* remove entry from the trans list */
1196     mf_hash_rem_item(&mfp->mf_trans, (mf_hashitem_T *)np);
1197 
1198     vim_free(np);
1199 
1200     return new_bnum;
1201 }
1202 
1203 /*
1204  * Set mfp->mf_ffname according to mfp->mf_fname and some other things.
1205  * Only called when creating or renaming the swapfile.	Either way it's a new
1206  * name so we must work out the full path name.
1207  */
1208     void
1209 mf_set_ffname(memfile_T *mfp)
1210 {
1211     mfp->mf_ffname = FullName_save(mfp->mf_fname, FALSE);
1212 }
1213 
1214 /*
1215  * Make the name of the file used for the memfile a full path.
1216  * Used before doing a :cd
1217  */
1218     void
1219 mf_fullname(memfile_T *mfp)
1220 {
1221     if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_ffname != NULL)
1222     {
1223 	vim_free(mfp->mf_fname);
1224 	mfp->mf_fname = mfp->mf_ffname;
1225 	mfp->mf_ffname = NULL;
1226     }
1227 }
1228 
1229 /*
1230  * return TRUE if there are any translations pending for 'mfp'
1231  */
1232     int
1233 mf_need_trans(memfile_T *mfp)
1234 {
1235     return (mfp->mf_fname != NULL && mfp->mf_neg_count > 0);
1236 }
1237 
1238 /*
1239  * Open a swap file for a memfile.
1240  * The "fname" must be in allocated memory, and is consumed (also when an
1241  * error occurs).
1242  */
1243     static void
1244 mf_do_open(
1245     memfile_T	*mfp,
1246     char_u	*fname,
1247     int		flags)		/* flags for open() */
1248 {
1249 #ifdef HAVE_LSTAT
1250     struct stat sb;
1251 #endif
1252 
1253     mfp->mf_fname = fname;
1254 
1255     /*
1256      * Get the full path name before the open, because this is
1257      * not possible after the open on the Amiga.
1258      * fname cannot be NameBuff, because it must have been allocated.
1259      */
1260     mf_set_ffname(mfp);
1261 #if defined(MSWIN)
1262     /*
1263      * A ":!cd e:xxx" may change the directory without us knowing, use the
1264      * full pathname always.  Careful: This frees fname!
1265      */
1266     mf_fullname(mfp);
1267 #endif
1268 
1269 #ifdef HAVE_LSTAT
1270     /*
1271      * Extra security check: When creating a swap file it really shouldn't
1272      * exist yet.  If there is a symbolic link, this is most likely an attack.
1273      */
1274     if ((flags & O_CREAT) && mch_lstat((char *)mfp->mf_fname, &sb) >= 0)
1275     {
1276 	mfp->mf_fd = -1;
1277 	EMSG(_("E300: Swap file already exists (symlink attack?)"));
1278     }
1279     else
1280 #endif
1281     {
1282 	/*
1283 	 * try to open the file
1284 	 */
1285 	flags |= O_EXTRA | O_NOFOLLOW;
1286 #ifdef WIN32
1287 	/* Prevent handle inheritance that cause problems with Cscope
1288 	 * (swap file may not be deleted if cscope connection was open after
1289 	 * the file) */
1290 	flags |= O_NOINHERIT;
1291 #endif
1292 	mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
1293     }
1294 
1295     /*
1296      * If the file cannot be opened, use memory only
1297      */
1298     if (mfp->mf_fd < 0)
1299     {
1300 	vim_free(mfp->mf_fname);
1301 	vim_free(mfp->mf_ffname);
1302 	mfp->mf_fname = NULL;
1303 	mfp->mf_ffname = NULL;
1304     }
1305     else
1306     {
1307 #ifdef HAVE_FD_CLOEXEC
1308 	int fdflags = fcntl(mfp->mf_fd, F_GETFD);
1309 	if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
1310 	    (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
1311 #endif
1312 #if defined(HAVE_SELINUX) || defined(HAVE_SMACK)
1313 	mch_copy_sec(fname, mfp->mf_fname);
1314 #endif
1315 	mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
1316     }
1317 }
1318 
1319 /*
1320  * Implementation of mf_hashtab_T follows.
1321  */
1322 
1323 /*
1324  * The number of buckets in the hashtable is increased by a factor of
1325  * MHT_GROWTH_FACTOR when the average number of items per bucket
1326  * exceeds 2 ^ MHT_LOG_LOAD_FACTOR.
1327  */
1328 #define MHT_LOG_LOAD_FACTOR 6
1329 #define MHT_GROWTH_FACTOR   2   /* must be a power of two */
1330 
1331 /*
1332  * Initialize an empty hash table.
1333  */
1334     static void
1335 mf_hash_init(mf_hashtab_T *mht)
1336 {
1337     vim_memset(mht, 0, sizeof(mf_hashtab_T));
1338     mht->mht_buckets = mht->mht_small_buckets;
1339     mht->mht_mask = MHT_INIT_SIZE - 1;
1340 }
1341 
1342 /*
1343  * Free the array of a hash table.  Does not free the items it contains!
1344  * The hash table must not be used again without another mf_hash_init() call.
1345  */
1346     static void
1347 mf_hash_free(mf_hashtab_T *mht)
1348 {
1349     if (mht->mht_buckets != mht->mht_small_buckets)
1350 	vim_free(mht->mht_buckets);
1351 }
1352 
1353 /*
1354  * Free the array of a hash table and all the items it contains.
1355  */
1356     static void
1357 mf_hash_free_all(mf_hashtab_T *mht)
1358 {
1359     long_u	    idx;
1360     mf_hashitem_T   *mhi;
1361     mf_hashitem_T   *next;
1362 
1363     for (idx = 0; idx <= mht->mht_mask; idx++)
1364 	for (mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next)
1365 	{
1366 	    next = mhi->mhi_next;
1367 	    vim_free(mhi);
1368 	}
1369 
1370     mf_hash_free(mht);
1371 }
1372 
1373 /*
1374  * Find "key" in hashtable "mht".
1375  * Returns a pointer to a mf_hashitem_T or NULL if the item was not found.
1376  */
1377     static mf_hashitem_T *
1378 mf_hash_find(mf_hashtab_T *mht, blocknr_T key)
1379 {
1380     mf_hashitem_T   *mhi;
1381 
1382     mhi = mht->mht_buckets[key & mht->mht_mask];
1383     while (mhi != NULL && mhi->mhi_key != key)
1384 	mhi = mhi->mhi_next;
1385 
1386     return mhi;
1387 }
1388 
1389 /*
1390  * Add item "mhi" to hashtable "mht".
1391  * "mhi" must not be NULL.
1392  */
1393     static void
1394 mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
1395 {
1396     long_u	    idx;
1397 
1398     idx = mhi->mhi_key & mht->mht_mask;
1399     mhi->mhi_next = mht->mht_buckets[idx];
1400     mhi->mhi_prev = NULL;
1401     if (mhi->mhi_next != NULL)
1402 	mhi->mhi_next->mhi_prev = mhi;
1403     mht->mht_buckets[idx] = mhi;
1404 
1405     mht->mht_count++;
1406 
1407     /*
1408      * Grow hashtable when we have more thank 2^MHT_LOG_LOAD_FACTOR
1409      * items per bucket on average
1410      */
1411     if (mht->mht_fixed == 0
1412 	&& (mht->mht_count >> MHT_LOG_LOAD_FACTOR) > mht->mht_mask)
1413     {
1414 	if (mf_hash_grow(mht) == FAIL)
1415 	{
1416 	    /* stop trying to grow after first failure to allocate memory */
1417 	    mht->mht_fixed = 1;
1418 	}
1419     }
1420 }
1421 
1422 /*
1423  * Remove item "mhi" from hashtable "mht".
1424  * "mhi" must not be NULL and must have been inserted into "mht".
1425  */
1426     static void
1427 mf_hash_rem_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
1428 {
1429     if (mhi->mhi_prev == NULL)
1430 	mht->mht_buckets[mhi->mhi_key & mht->mht_mask] = mhi->mhi_next;
1431     else
1432 	mhi->mhi_prev->mhi_next = mhi->mhi_next;
1433 
1434     if (mhi->mhi_next != NULL)
1435 	mhi->mhi_next->mhi_prev = mhi->mhi_prev;
1436 
1437     mht->mht_count--;
1438 
1439     /* We could shrink the table here, but it typically takes little memory,
1440      * so why bother?  */
1441 }
1442 
1443 /*
1444  * Increase number of buckets in the hashtable by MHT_GROWTH_FACTOR and
1445  * rehash items.
1446  * Returns FAIL when out of memory.
1447  */
1448     static int
1449 mf_hash_grow(mf_hashtab_T *mht)
1450 {
1451     long_u	    i, j;
1452     int		    shift;
1453     mf_hashitem_T   *mhi;
1454     mf_hashitem_T   *tails[MHT_GROWTH_FACTOR];
1455     mf_hashitem_T   **buckets;
1456     size_t	    size;
1457 
1458     size = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR * sizeof(void *);
1459     buckets = (mf_hashitem_T **)lalloc_clear(size, FALSE);
1460     if (buckets == NULL)
1461 	return FAIL;
1462 
1463     shift = 0;
1464     while ((mht->mht_mask >> shift) != 0)
1465 	shift++;
1466 
1467     for (i = 0; i <= mht->mht_mask; i++)
1468     {
1469 	/*
1470 	 * Traverse the items in the i-th original bucket and move them into
1471 	 * MHT_GROWTH_FACTOR new buckets, preserving their relative order
1472 	 * within each new bucket.  Preserving the order is important because
1473 	 * mf_get() tries to keep most recently used items at the front of
1474 	 * each bucket.
1475 	 *
1476 	 * Here we strongly rely on the fact the hashes are computed modulo
1477 	 * a power of two.
1478 	 */
1479 
1480 	vim_memset(tails, 0, sizeof(tails));
1481 
1482 	for (mhi = mht->mht_buckets[i]; mhi != NULL; mhi = mhi->mhi_next)
1483 	{
1484 	    j = (mhi->mhi_key >> shift) & (MHT_GROWTH_FACTOR - 1);
1485 	    if (tails[j] == NULL)
1486 	    {
1487 		buckets[i + (j << shift)] = mhi;
1488 		tails[j] = mhi;
1489 		mhi->mhi_prev = NULL;
1490 	    }
1491 	    else
1492 	    {
1493 		tails[j]->mhi_next = mhi;
1494 		mhi->mhi_prev = tails[j];
1495 		tails[j] = mhi;
1496 	    }
1497 	}
1498 
1499 	for (j = 0; j < MHT_GROWTH_FACTOR; j++)
1500 	    if (tails[j] != NULL)
1501 		tails[j]->mhi_next = NULL;
1502     }
1503 
1504     if (mht->mht_buckets != mht->mht_small_buckets)
1505 	vim_free(mht->mht_buckets);
1506 
1507     mht->mht_buckets = buckets;
1508     mht->mht_mask = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR - 1;
1509 
1510     return OK;
1511 }
1512