comparison src/structs.h @ 2730:e0a90042318d

updated for version 7.3.143 Problem: Memfile is not tested sufficiently. Looking up blocks in a memfile is slow when there are many blocks. Solution: Add high level test and unittest. Adjust the number of hash buckets to the number of blocks. (Ivan Krasilnikov)
author Bram Moolenaar <bram@vim.org>
date Tue, 22 Mar 2011 18:10:45 +0100
parents cd3f52531f6c
children 8bd38abda314
comparison
equal deleted inserted replaced
2729:12f838be9c59 2730:e0a90042318d
376 typedef struct block_hdr bhdr_T; 376 typedef struct block_hdr bhdr_T;
377 typedef struct memfile memfile_T; 377 typedef struct memfile memfile_T;
378 typedef long blocknr_T; 378 typedef long blocknr_T;
379 379
380 /* 380 /*
381 * mf_hashtab_T is a chained hashtable with blocknr_T key and arbitrary
382 * structures as items. This is an intrusive data structure: we require
383 * that items begin with mf_hashitem_T which contains the key and linked
384 * list pointers. List of items in each bucket is doubly-linked.
385 */
386
387 typedef struct mf_hashitem_S mf_hashitem_T;
388
389 struct mf_hashitem_S
390 {
391 mf_hashitem_T *mhi_next;
392 mf_hashitem_T *mhi_prev;
393 blocknr_T mhi_key;
394 };
395
396 #define MHT_INIT_SIZE 64
397
398 typedef struct mf_hashtab_S
399 {
400 long_u mht_mask; /* mask used for hash value (nr of items
401 * in array is "mht_mask" + 1) */
402 long_u mht_count; /* nr of items inserted into hashtable */
403 mf_hashitem_T **mht_buckets; /* points to mht_small_buckets or
404 *dynamically allocated array */
405 mf_hashitem_T *mht_small_buckets[MHT_INIT_SIZE]; /* initial buckets */
406 char mht_fixed; /* non-zero value forbids growth */
407 } mf_hashtab_T;
408
409 /*
381 * for each (previously) used block in the memfile there is one block header. 410 * for each (previously) used block in the memfile there is one block header.
382 * 411 *
383 * The block may be linked in the used list OR in the free list. 412 * The block may be linked in the used list OR in the free list.
384 * The used blocks are also kept in hash lists. 413 * The used blocks are also kept in hash lists.
385 * 414 *
392 * the contents of the block in the file (if any) is irrelevant. 421 * the contents of the block in the file (if any) is irrelevant.
393 */ 422 */
394 423
395 struct block_hdr 424 struct block_hdr
396 { 425 {
426 mf_hashitem_T bh_hashitem; /* header for hash table and key */
427 #define bh_bnum bh_hashitem.mhi_key /* block number, part of bh_hashitem */
428
397 bhdr_T *bh_next; /* next block_hdr in free or used list */ 429 bhdr_T *bh_next; /* next block_hdr in free or used list */
398 bhdr_T *bh_prev; /* previous block_hdr in used list */ 430 bhdr_T *bh_prev; /* previous block_hdr in used list */
399 bhdr_T *bh_hash_next; /* next block_hdr in hash list */
400 bhdr_T *bh_hash_prev; /* previous block_hdr in hash list */
401 blocknr_T bh_bnum; /* block number */
402 char_u *bh_data; /* pointer to memory (for used block) */ 431 char_u *bh_data; /* pointer to memory (for used block) */
403 int bh_page_count; /* number of pages in this block */ 432 int bh_page_count; /* number of pages in this block */
404 433
405 #define BH_DIRTY 1 434 #define BH_DIRTY 1
406 #define BH_LOCKED 2 435 #define BH_LOCKED 2
415 */ 444 */
416 typedef struct nr_trans NR_TRANS; 445 typedef struct nr_trans NR_TRANS;
417 446
418 struct nr_trans 447 struct nr_trans
419 { 448 {
420 NR_TRANS *nt_next; /* next nr_trans in hash list */ 449 mf_hashitem_T nt_hashitem; /* header for hash table and key */
421 NR_TRANS *nt_prev; /* previous nr_trans in hash list */ 450 #define nt_old_bnum nt_hashitem.mhi_key /* old, negative, number */
422 blocknr_T nt_old_bnum; /* old, negative, number */ 451
423 blocknr_T nt_new_bnum; /* new, positive, number */ 452 blocknr_T nt_new_bnum; /* new, positive, number */
424 }; 453 };
425 454
426 /* 455 /*
427 * structure used to store one block of the stuff/redo/recording buffers 456 * structure used to store one block of the stuff/redo/recording buffers
497 # endif 526 # endif
498 } cmdmod_T; 527 } cmdmod_T;
499 528
500 typedef struct file_buffer buf_T; /* forward declaration */ 529 typedef struct file_buffer buf_T; /* forward declaration */
501 530
502 /*
503 * Simplistic hashing scheme to quickly locate the blocks in the used list.
504 * 64 blocks are found directly (64 * 4K = 256K, most files are smaller).
505 */
506 #define MEMHASHSIZE 64
507 #define MEMHASH(nr) ((nr) & (MEMHASHSIZE - 1))
508 #define MF_SEED_LEN 8 531 #define MF_SEED_LEN 8
509 532
510 struct memfile 533 struct memfile
511 { 534 {
512 char_u *mf_fname; /* name of the file */ 535 char_u *mf_fname; /* name of the file */
515 bhdr_T *mf_free_first; /* first block_hdr in free list */ 538 bhdr_T *mf_free_first; /* first block_hdr in free list */
516 bhdr_T *mf_used_first; /* mru block_hdr in used list */ 539 bhdr_T *mf_used_first; /* mru block_hdr in used list */
517 bhdr_T *mf_used_last; /* lru block_hdr in used list */ 540 bhdr_T *mf_used_last; /* lru block_hdr in used list */
518 unsigned mf_used_count; /* number of pages in used list */ 541 unsigned mf_used_count; /* number of pages in used list */
519 unsigned mf_used_count_max; /* maximum number of pages in memory */ 542 unsigned mf_used_count_max; /* maximum number of pages in memory */
520 bhdr_T *mf_hash[MEMHASHSIZE]; /* array of hash lists */ 543 mf_hashtab_T mf_hash; /* hash lists */
521 NR_TRANS *mf_trans[MEMHASHSIZE]; /* array of trans lists */ 544 mf_hashtab_T mf_trans; /* trans lists */
522 blocknr_T mf_blocknr_max; /* highest positive block number + 1*/ 545 blocknr_T mf_blocknr_max; /* highest positive block number + 1*/
523 blocknr_T mf_blocknr_min; /* lowest negative block number - 1 */ 546 blocknr_T mf_blocknr_min; /* lowest negative block number - 1 */
524 blocknr_T mf_neg_count; /* number of negative blocks numbers */ 547 blocknr_T mf_neg_count; /* number of negative blocks numbers */
525 blocknr_T mf_infile_count; /* number of pages in the file */ 548 blocknr_T mf_infile_count; /* number of pages in the file */
526 unsigned mf_page_size; /* number of bytes in a page */ 549 unsigned mf_page_size; /* number of bytes in a page */