Patch 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)
Files:      Filelist, src/Makefile, src/main.c, src/memfile.c,
            src/memfile_test.c src/structs.h src/testdir/Make_amiga.mak,
            src/testdir/Make_dos.mak, src/testdir/Make_ming.mak,
            src/testdir/Make_os2.mak, src/testdir/Make_vms.mak,
            src/testdir/Makefile, src/testdir/test77.in, src/testdir/test77.ok


*** ../vim-7.3.142/Filelist     2010-08-15 21:57:20.000000000 +0200
--- Filelist    2011-03-22 17:39:22.000000000 +0100
***************
*** 39,44 ****
--- 39,45 ----
                src/mark.c \
                src/mbyte.c \
                src/memfile.c \
+               src/memfile_test.c \
                src/memline.c \
                src/menu.c \
                src/message.c \
***************
*** 686,691 ****
--- 687,694 ----
                runtime/tutor/tutor.utf-8 \
                runtime/tutor/tutor.?? \
                runtime/tutor/tutor.??.* \
+               runtime/tutor/tutor.bar \
+               runtime/tutor/tutor.bar.* \
                runtime/spell/README.txt \
                runtime/spell/??/*.diff \
                runtime/spell/??/main.aap \
*** ../vim-7.3.142/src/Makefile 2011-02-15 15:27:00.000000000 +0100
--- src/Makefile        2011-03-22 18:07:25.000000000 +0100
***************
*** 561,567 ****
  #CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall 
-Wmissing-prototypes
  
  # Use this with GCC to check for mistakes, unused arguments, etc.
! #CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code 
-D_FORTIFY_SOURCE=1 -DU_DEBUG
  #CFLAGS = -g -O2 -Wall -Wextra -Wmissing-prototypes -D_FORTIFY_SOURCE=1 
-DU_DEBUG
  #PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
  #MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
--- 561,567 ----
  #CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall 
-Wmissing-prototypes
  
  # Use this with GCC to check for mistakes, unused arguments, etc.
! #CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code 
-D_FORTIFY_SOURCE=1
  #CFLAGS = -g -O2 -Wall -Wextra -Wmissing-prototypes -D_FORTIFY_SOURCE=1 
-DU_DEBUG
  #PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
  #MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
***************
*** 594,601 ****
  
  # PROFILING - Uncomment the next two lines to do profiling with gcc and gprof.
  # Might not work with GUI or Perl.
! # For unknown reasons adding "-lc" fixes a linking problem with GCC.  That's
! # probably a bug in the "-pg" implementation.
  # Need to recompile everything after changing this: "make clean" "make".
  #PROFILE_CFLAGS = -pg -g -DWE_ARE_PROFILING
  #PROFILE_LIBS = -pg
--- 594,602 ----
  
  # PROFILING - Uncomment the next two lines to do profiling with gcc and gprof.
  # Might not work with GUI or Perl.
! # For unknown reasons adding "-lc" fixes a linking problem with some versions
! # of GCC.  That's probably a bug in the "-pg" implementation.
! # After running Vim see the profile result with: gmon vim gmon.out | vim -
  # Need to recompile everything after changing this: "make clean" "make".
  #PROFILE_CFLAGS = -pg -g -DWE_ARE_PROFILING
  #PROFILE_LIBS = -pg
***************
*** 606,613 ****
  # Configuration is in the .ccmalloc or ~/.ccmalloc file.
  # Doesn't work very well, since memory linked to from global variables
  # (in libraries) is also marked as leaked memory.
! #PROFILE_CFLAGS = -DEXITFREE
! #PROFILE_LIBS = -lccmalloc
  
  #####################################################
  ###  Specific systems, check if yours is listed!  ### {{{
--- 607,614 ----
  # Configuration is in the .ccmalloc or ~/.ccmalloc file.
  # Doesn't work very well, since memory linked to from global variables
  # (in libraries) is also marked as leaked memory.
! #LEAK_CFLAGS = -DEXITFREE
! #LEAK_LIBS = -lccmalloc
  
  #####################################################
  ###  Specific systems, check if yours is listed!  ### {{{
***************
*** 1329,1335 ****
  PRE_DEFS = -Iproto $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) 
$(EXTRA_IPATHS)
  POST_DEFS = $(X_CFLAGS) $(MZSCHEME_CFLAGS) $(TCL_CFLAGS) $(EXTRA_DEFS)
  
! ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(POST_DEFS)
  
  # Exclude $CFLAGS for osdef.sh, for Mac 10.4 some flags don't work together
  # with "-E".
--- 1330,1336 ----
  PRE_DEFS = -Iproto $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) 
$(EXTRA_IPATHS)
  POST_DEFS = $(X_CFLAGS) $(MZSCHEME_CFLAGS) $(TCL_CFLAGS) $(EXTRA_DEFS)
  
! ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(LEAK_CFLAGS) 
$(POST_DEFS)
  
  # Exclude $CFLAGS for osdef.sh, for Mac 10.4 some flags don't work together
  # with "-E".
***************
*** 1358,1364 ****
           $(PYTHON3_LIBS) \
           $(TCL_LIBS) \
           $(RUBY_LIBS) \
!          $(PROFILE_LIBS)
  
  # abbreviations
  DEST_BIN = $(DESTDIR)$(BINDIR)
--- 1359,1366 ----
           $(PYTHON3_LIBS) \
           $(TCL_LIBS) \
           $(RUBY_LIBS) \
!          $(PROFILE_LIBS) \
!          $(LEAK_LIBS)
  
  # abbreviations
  DEST_BIN = $(DESTDIR)$(BINDIR)
***************
*** 1480,1487 ****
            if_python.c if_python3.c if_tcl.c if_ruby.c if_sniff.c \
            gui_beval.c workshop.c wsdebug.c integration.c netbeans.c
  
  # All sources, also the ones that are not configured
! ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(EXTRA_SRC)
  
  # Which files to check with lint.  Select one of these three lines.  ALL_SRC
  # checks more, but may not work well for checking a GUI that wasn't 
configured.
--- 1482,1496 ----
            if_python.c if_python3.c if_tcl.c if_ruby.c if_sniff.c \
            gui_beval.c workshop.c wsdebug.c integration.c netbeans.c
  
+ # Unittest files
+ MEMFILE_TEST_SRC = memfile_test.c
+ MEMFILE_TEST_TARGET = memfile_test$(EXEEXT)
+ 
+ UNITTEST_SRC = $(MEMFILE_TEST_SRC)
+ UNITTEST_TARGETS = $(MEMFILE_TEST_TARGET)
+ 
  # All sources, also the ones that are not configured
! ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(UNITTEST_SRC) $(EXTRA_SRC)
  
  # Which files to check with lint.  Select one of these three lines.  ALL_SRC
  # checks more, but may not work well for checking a GUI that wasn't 
configured.
***************
*** 1492,1498 ****
  #LINT_SRC = $(ALL_SRC)
  #LINT_SRC = $(BASIC_SRC)
  
! OBJ = \
        objects/buffer.o \
        objects/blowfish.o \
        objects/charset.o \
--- 1501,1507 ----
  #LINT_SRC = $(ALL_SRC)
  #LINT_SRC = $(BASIC_SRC)
  
! OBJ_COMMON = \
        objects/buffer.o \
        objects/blowfish.o \
        objects/charset.o \
***************
*** 1513,1522 ****
        $(HANGULIN_OBJ) \
        objects/if_cscope.o \
        objects/if_xcmdsrv.o \
-       objects/main.o \
        objects/mark.o \
!       objects/memfile.o \
!       objects/memline.o \
        objects/menu.o \
        objects/message.o \
        objects/misc1.o \
--- 1522,1529 ----
        $(HANGULIN_OBJ) \
        objects/if_cscope.o \
        objects/if_xcmdsrv.o \
        objects/mark.o \
!         objects/memline.o \
        objects/menu.o \
        objects/message.o \
        objects/misc1.o \
***************
*** 1541,1546 ****
--- 1548,1554 ----
        objects/term.o \
        objects/ui.o \
        objects/undo.o \
+       objects/version.o \
        objects/window.o \
        $(GUI_OBJ) \
        $(LUA_OBJ) \
***************
*** 1555,1560 ****
--- 1563,1575 ----
        $(NETBEANS_OBJ) \
        $(WSDEBUG_OBJ)
  
+ OBJ = $(OBJ_COMMON) \
+       objects/main.o \
+       objects/memfile.o \
+ 
+ MEMFILE_TEST_OBJ = $(OBJ_COMMON) \
+         objects/memfile_test.o
+ 
  PRO_AUTO = \
        blowfish.pro \
        buffer.pro \
***************
*** 1700,1706 ****
  $(VIMTARGET): auto/config.mk objects $(OBJ) version.c version.h
        $(CCC) version.c -o objects/version.o
        @LINK="$(PURIFY) $(SHRPENV) $(CClink) $(ALL_LIB_DIRS) $(LDFLAGS) \
!               -o $(VIMTARGET) $(OBJ) objects/version.o $(ALL_LIBS)" \
                MAKE="$(MAKE)" LINK_AS_NEEDED=$(LINK_AS_NEEDED) \
                sh $(srcdir)/link.sh
  
--- 1715,1721 ----
  $(VIMTARGET): auto/config.mk objects $(OBJ) version.c version.h
        $(CCC) version.c -o objects/version.o
        @LINK="$(PURIFY) $(SHRPENV) $(CClink) $(ALL_LIB_DIRS) $(LDFLAGS) \
!               -o $(VIMTARGET) $(OBJ) $(ALL_LIBS)" \
                MAKE="$(MAKE)" LINK_AS_NEEDED=$(LINK_AS_NEEDED) \
                sh $(srcdir)/link.sh
  
***************
*** 1825,1830 ****
--- 1840,1854 ----
                ln -s $(VIMTARGET) vim; \
        fi
        cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) 
VIMPROG=../$(VIMTARGET) $(GUI_TESTARG)
+       $(MAKE) -f Makefile unittest
+ 
+ unittesttargets:
+       $(MAKE) -f Makefile $(UNITTEST_TARGETS)
+ 
+ unittest unittests: $(UNITTEST_TARGETS)
+       @for t in $(UNITTEST_TARGETS); do \
+               ./$$t || exit 1; echo $$t passed; \
+       done
  
  testclean:
        cd testdir; $(MAKE) -f Makefile clean
***************
*** 1832,1837 ****
--- 1856,1872 ----
                cd $(PODIR); $(MAKE) checkclean; \
        fi
  
+ # Unittests
+ # It's build just like Vim to satisfy all dependencies.
+ $(MEMFILE_TEST_TARGET): auto/config.mk objects $(MEMFILE_TEST_OBJ)
+       $(CCC) version.c -o objects/version.o
+       @LINK="$(PURIFY) $(SHRPENV) $(CClink) $(ALL_LIB_DIRS) $(LDFLAGS) \
+               -o $(MEMFILE_TEST_TARGET) $(MEMFILE_TEST_OBJ) $(ALL_LIBS)" \
+               MAKE="$(MAKE)" LINK_AS_NEEDED=$(LINK_AS_NEEDED) \
+               sh $(srcdir)/link.sh
+ 
+ # install targets
+ 
  install: $(GUI_INSTALL)
  
  install_normal: installvim installtools $(INSTALL_LANGS) install-icons
***************
*** 2265,2270 ****
--- 2300,2306 ----
        -rm -f *.o objects/* core $(VIMTARGET).core $(VIMTARGET) vim xxd/*.o
        -rm -f $(TOOLS) auto/osdef.h auto/pathdef.c auto/if_perl.c
        -rm -f conftest* *~ auto/link.sed
+       -rm -f $(UNITTEST_TARGETS)
        -rm -f runtime pixmaps
        -rm -rf $(APPDIR)
        -rm -rf mzscheme_base.c
***************
*** 2559,2564 ****
--- 2595,2603 ----
  objects/memfile.o: memfile.c
        $(CCC) -o $@ memfile.c
  
+ objects/memfile_test.o: memfile_test.c
+       $(CCC) -o $@ memfile_test.c
+ 
  objects/memline.o: memline.c
        $(CCC) -o $@ memline.c
  
***************
*** 2877,2883 ****
  objects/os_unix.o: os_unix.c vim.h auto/config.h feature.h os_unix.h 
auto/osdef.h \
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
!  arabic.h if_mzsch.h os_unixx.h
  objects/pathdef.o: auto/pathdef.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
--- 2916,2922 ----
  objects/os_unix.o: os_unix.c vim.h auto/config.h feature.h os_unix.h 
auto/osdef.h \
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
!  arabic.h os_unixx.h
  objects/pathdef.o: auto/pathdef.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
***************
*** 3016,3021 ****
--- 3055,3064 ----
  objects/pty.o: pty.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h 
ascii.h \
   keymap.h term.h macros.h option.h structs.h regexp.h gui.h gui_beval.h \
   proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h arabic.h
+ objects/memfile_test.o: memfile_test.c main.c vim.h auto/config.h feature.h \
+  os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h \
+  structs.h regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h \
+  proto.h globals.h farsi.h arabic.h farsi.c arabic.c memfile.c
  objects/hangulin.o: hangulin.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
***************
*** 3027,3033 ****
  objects/if_mzsch.o: if_mzsch.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
!  globals.h farsi.h arabic.h if_mzsch.h mzscheme_base.c
  objects/if_perl.o: auto/if_perl.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
--- 3070,3076 ----
  objects/if_mzsch.o: if_mzsch.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
!  globals.h farsi.h arabic.h if_mzsch.h
  objects/if_perl.o: auto/if_perl.c vim.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
   regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
***************
*** 3048,3054 ****
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
   arabic.h
! objects/if_ruby.o: if_ruby.c vim.h auto/config.h feature.h os_unix.h 
auto/osdef.h \
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
   arabic.h version.h
--- 3091,3097 ----
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
   arabic.h
! objects/if_ruby.o: if_ruby.c auto/config.h vim.h feature.h os_unix.h 
auto/osdef.h \
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
   arabic.h version.h
*** ../vim-7.3.142/src/main.c   2011-02-15 16:29:54.000000000 +0100
--- src/main.c  2011-03-18 13:19:48.000000000 +0100
***************
*** 92,128 ****
  #define EDIT_TAG    3     /* tag name argument given, use tagname */
  #define EDIT_QF           4       /* start in quickfix mode */
  
! #if defined(UNIX) || defined(VMS)
  static int file_owned __ARGS((char *fname));
  #endif
  static void mainerr __ARGS((int, char_u *));
  static void main_msg __ARGS((char *s));
  static void usage __ARGS((void));
  static int get_number_arg __ARGS((char_u *p, int *idx, int def));
! #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
  static void init_locale __ARGS((void));
! #endif
  static void parse_command_name __ARGS((mparm_T *parmp));
  static void early_arg_scan __ARGS((mparm_T *parmp));
  static void command_line_scan __ARGS((mparm_T *parmp));
  static void check_tty __ARGS((mparm_T *parmp));
  static void read_stdin __ARGS((void));
  static void create_windows __ARGS((mparm_T *parmp));
! #ifdef FEAT_WINDOWS
  static void edit_buffers __ARGS((mparm_T *parmp));
! #endif
  static void exe_pre_commands __ARGS((mparm_T *parmp));
  static void exe_commands __ARGS((mparm_T *parmp));
  static void source_startup_scripts __ARGS((mparm_T *parmp));
  static void main_start_gui __ARGS((void));
! #if defined(HAS_SWAP_EXISTS_ACTION)
  static void check_swap_exists_action __ARGS((void));
! #endif
! #ifdef FEAT_CLIENTSERVER
  static void exec_on_server __ARGS((mparm_T *parmp));
  static void prepare_server __ARGS((mparm_T *parmp));
  static void cmdsrv_main __ARGS((int *argc, char **argv, char_u 
*serverName_arg, char_u **serverStr));
  static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
  #endif
  
  
--- 92,130 ----
  #define EDIT_TAG    3     /* tag name argument given, use tagname */
  #define EDIT_QF           4       /* start in quickfix mode */
  
! #if (defined(UNIX) || defined(VMS)) && !defined(NO_VIM_MAIN)
  static int file_owned __ARGS((char *fname));
  #endif
  static void mainerr __ARGS((int, char_u *));
+ #ifndef NO_VIM_MAIN
  static void main_msg __ARGS((char *s));
  static void usage __ARGS((void));
  static int get_number_arg __ARGS((char_u *p, int *idx, int def));
! # if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
  static void init_locale __ARGS((void));
! # endif
  static void parse_command_name __ARGS((mparm_T *parmp));
  static void early_arg_scan __ARGS((mparm_T *parmp));
  static void command_line_scan __ARGS((mparm_T *parmp));
  static void check_tty __ARGS((mparm_T *parmp));
  static void read_stdin __ARGS((void));
  static void create_windows __ARGS((mparm_T *parmp));
! # ifdef FEAT_WINDOWS
  static void edit_buffers __ARGS((mparm_T *parmp));
! # endif
  static void exe_pre_commands __ARGS((mparm_T *parmp));
  static void exe_commands __ARGS((mparm_T *parmp));
  static void source_startup_scripts __ARGS((mparm_T *parmp));
  static void main_start_gui __ARGS((void));
! # if defined(HAS_SWAP_EXISTS_ACTION)
  static void check_swap_exists_action __ARGS((void));
! # endif
! # if defined(FEAT_CLIENTSERVER) || defined(PROTO)
  static void exec_on_server __ARGS((mparm_T *parmp));
  static void prepare_server __ARGS((mparm_T *parmp));
  static void cmdsrv_main __ARGS((int *argc, char **argv, char_u 
*serverName_arg, char_u **serverStr));
  static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
+ # endif
  #endif
  
  
***************
*** 145,151 ****
  #define ME_INVALID_ARG                5
  };
  
! #ifndef PROTO     /* don't want a prototype for main() */
      int
  # ifdef VIMDLL
  _export
--- 147,154 ----
  #define ME_INVALID_ARG                5
  };
  
! #ifndef NO_VIM_MAIN   /* skip this for unittests */
! #ifndef PROTO         /* don't want a prototype for main() */
      int
  # ifdef VIMDLL
  _export
***************
*** 966,971 ****
--- 969,975 ----
      return 0;
  }
  #endif /* PROTO */
+ #endif /* NO_VIM_MAIN */
  
  /*
   * Main loop: Execute Normal mode commands until exiting Vim.
***************
*** 1430,1435 ****
--- 1434,1440 ----
      mch_exit(exitval);
  }
  
+ #ifndef NO_VIM_MAIN
  /*
   * Get a (optional) count for a Vim argument.
   */
***************
*** 2994,2999 ****
--- 2999,3006 ----
  #endif
  }
  
+ #endif  /* NO_VIM_MAIN */
+ 
  /*
   * Get an environment variable, and execute it as Ex commands.
   * Returns FAIL if the environment variable was not executed, OK otherwise.
***************
*** 3033,3039 ****
      return FAIL;
  }
  
! #if defined(UNIX) || defined(VMS)
  /*
   * Return TRUE if we are certain the user owns the file "fname".
   * Used for ".vimrc" and ".exrc".
--- 3040,3046 ----
      return FAIL;
  }
  
! #if (defined(UNIX) || defined(VMS)) && !defined(NO_VIM_MAIN)
  /*
   * Return TRUE if we are certain the user owns the file "fname".
   * Used for ".vimrc" and ".exrc".
***************
*** 3091,3096 ****
--- 3098,3104 ----
      mainerr(ME_ARG_MISSING, str);
  }
  
+ #ifndef NO_VIM_MAIN
  /*
   * print a message with three spaces prepended and '\n' appended.
   */
***************
*** 3311,3316 ****
--- 3319,3326 ----
  }
  #endif
  
+ #endif
+ 
  #if defined(STARTUPTIME) || defined(PROTO)
  static void time_diff __ARGS((struct timeval *then, struct timeval *now));
  
***************
*** 3420,3426 ****
  
  #endif
  
! #if defined(FEAT_CLIENTSERVER) || defined(PROTO)
  
  /*
   * Common code for the X command server and the Win32 command server.
--- 3430,3436 ----
  
  #endif
  
! #if (defined(FEAT_CLIENTSERVER) && !defined(NO_VIM_MAIN)) || defined(PROTO)
  
  /*
   * Common code for the X command server and the Win32 command server.
***************
*** 3888,3893 ****
--- 3898,3929 ----
  }
  
  /*
+  * Make our basic server name: use the specified "arg" if given, otherwise use
+  * the tail of the command "cmd" we were started with.
+  * Return the name in allocated memory.  This doesn't include a serial number.
+  */
+     static char_u *
+ serverMakeName(arg, cmd)
+     char_u    *arg;
+     char      *cmd;
+ {
+     char_u *p;
+ 
+     if (arg != NULL && *arg != NUL)
+       p = vim_strsave_up(arg);
+     else
+     {
+       p = vim_strsave_up(gettail((char_u *)cmd));
+       /* Remove .exe or .bat from the name. */
+       if (p != NULL && vim_strchr(p, '.') != NULL)
+           *vim_strchr(p, '.') = NUL;
+     }
+     return p;
+ }
+ #endif /* FEAT_CLIENTSERVER */
+ 
+ #if defined(FEAT_CLIENTSERVER) || defined(PROTO)
+ /*
   * Replace termcodes such as <CR> and insert as key presses if there is room.
   */
      void
***************
*** 3998,4029 ****
  # endif
      return res;
  }
! 
! 
! /*
!  * Make our basic server name: use the specified "arg" if given, otherwise use
!  * the tail of the command "cmd" we were started with.
!  * Return the name in allocated memory.  This doesn't include a serial number.
!  */
!     static char_u *
! serverMakeName(arg, cmd)
!     char_u    *arg;
!     char      *cmd;
! {
!     char_u *p;
! 
!     if (arg != NULL && *arg != NUL)
!       p = vim_strsave_up(arg);
!     else
!     {
!       p = vim_strsave_up(gettail((char_u *)cmd));
!       /* Remove .exe or .bat from the name. */
!       if (p != NULL && vim_strchr(p, '.') != NULL)
!           *vim_strchr(p, '.') = NUL;
!     }
!     return p;
! }
! #endif /* FEAT_CLIENTSERVER */
  
  /*
   * When FEAT_FKMAP is defined, also compile the Farsi source code.
--- 4034,4040 ----
  # endif
      return res;
  }
! #endif
  
  /*
   * When FEAT_FKMAP is defined, also compile the Farsi source code.
*** ../vim-7.3.142/src/memfile.c        2010-12-17 18:06:00.000000000 +0100
--- src/memfile.c       2011-03-03 18:47:39.000000000 +0100
***************
*** 84,89 ****
--- 84,96 ----
  static int  mf_write_block __ARGS((memfile_T *mfp, bhdr_T *hp, off_t offset, 
unsigned size));
  static int  mf_trans_add __ARGS((memfile_T *, bhdr_T *));
  static void mf_do_open __ARGS((memfile_T *, char_u *, int));
+ static void mf_hash_init __ARGS((mf_hashtab_T *));
+ static void mf_hash_free __ARGS((mf_hashtab_T *));
+ static void mf_hash_free_all __ARGS((mf_hashtab_T *));
+ static mf_hashitem_T *mf_hash_find __ARGS((mf_hashtab_T *, blocknr_T));
+ static void mf_hash_add_item __ARGS((mf_hashtab_T *, mf_hashitem_T *));
+ static void mf_hash_rem_item __ARGS((mf_hashtab_T *, mf_hashitem_T *));
+ static int mf_hash_grow __ARGS((mf_hashtab_T *));
  
  /*
   * The functions for using a memfile:
***************
*** 119,125 ****
      int               flags;
  {
      memfile_T         *mfp;
-     int                       i;
      off_t             size;
  #if defined(STATFS) && defined(UNIX) && !defined(__QNX__)
  # define USE_FSTATFS
--- 126,131 ----
***************
*** 152,162 ****
      mfp->mf_used_last = NULL;
      mfp->mf_dirty = FALSE;
      mfp->mf_used_count = 0;
!     for (i = 0; i < MEMHASHSIZE; ++i)
!     {
!       mfp->mf_hash[i] = NULL;         /* hash lists are empty */
!       mfp->mf_trans[i] = NULL;        /* trans lists are empty */
!     }
      mfp->mf_page_size = MEMFILE_PAGE_SIZE;
  #ifdef FEAT_CRYPT
      mfp->mf_old_key = NULL;
--- 158,165 ----
      mfp->mf_used_last = NULL;
      mfp->mf_dirty = FALSE;
      mfp->mf_used_count = 0;
!     mf_hash_init(&mfp->mf_hash);
!     mf_hash_init(&mfp->mf_trans);
      mfp->mf_page_size = MEMFILE_PAGE_SIZE;
  #ifdef FEAT_CRYPT
      mfp->mf_old_key = NULL;
***************
*** 242,249 ****
      int               del_file;
  {
      bhdr_T    *hp, *nextp;
-     NR_TRANS  *tp, *tpnext;
-     int               i;
  
      if (mfp == NULL)              /* safety check */
        return;
--- 245,250 ----
***************
*** 263,274 ****
      }
      while (mfp->mf_free_first != NULL)            /* free entries in free 
list */
        vim_free(mf_rem_free(mfp));
!     for (i = 0; i < MEMHASHSIZE; ++i)     /* free entries in trans lists */
!       for (tp = mfp->mf_trans[i]; tp != NULL; tp = tpnext)
!       {
!           tpnext = tp->nt_next;
!           vim_free(tp);
!       }
      vim_free(mfp->mf_fname);
      vim_free(mfp->mf_ffname);
      vim_free(mfp);
--- 264,271 ----
      }
      while (mfp->mf_free_first != NULL)            /* free entries in free 
list */
        vim_free(mf_rem_free(mfp));
!     mf_hash_free(&mfp->mf_hash);
!     mf_hash_free_all(&mfp->mf_trans);     /* free hashtable and its items */
      vim_free(mfp->mf_fname);
      vim_free(mfp->mf_ffname);
      vim_free(mfp);
***************
*** 743,758 ****
      memfile_T *mfp;
      bhdr_T    *hp;
  {
!     bhdr_T    *hhp;
!     int               hash;
! 
!     hash = MEMHASH(hp->bh_bnum);
!     hhp = mfp->mf_hash[hash];
!     hp->bh_hash_next = hhp;
!     hp->bh_hash_prev = NULL;
!     if (hhp != NULL)
!       hhp->bh_hash_prev = hp;
!     mfp->mf_hash[hash] = hp;
  }
  
  /*
--- 740,746 ----
      memfile_T *mfp;
      bhdr_T    *hp;
  {
!     mf_hash_add_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
  }
  
  /*
***************
*** 763,775 ****
      memfile_T *mfp;
      bhdr_T    *hp;
  {
!     if (hp->bh_hash_prev == NULL)
!       mfp->mf_hash[MEMHASH(hp->bh_bnum)] = hp->bh_hash_next;
!     else
!       hp->bh_hash_prev->bh_hash_next = hp->bh_hash_next;
! 
!     if (hp->bh_hash_next)
!       hp->bh_hash_next->bh_hash_prev = hp->bh_hash_prev;
  }
  
  /*
--- 751,757 ----
      memfile_T *mfp;
      bhdr_T    *hp;
  {
!     mf_hash_rem_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
  }
  
  /*
***************
*** 780,791 ****
      memfile_T *mfp;
      blocknr_T nr;
  {
!     bhdr_T    *hp;
! 
!     for (hp = mfp->mf_hash[MEMHASH(nr)]; hp != NULL; hp = hp->bh_hash_next)
!       if (hp->bh_bnum == nr)
!           break;
!     return hp;
  }
  
  /*
--- 762,768 ----
      memfile_T *mfp;
      blocknr_T nr;
  {
!     return (bhdr_T *)mf_hash_find(&mfp->mf_hash, nr);
  }
  
  /*
***************
*** 1187,1193 ****
  {
      bhdr_T    *freep;
      blocknr_T new_bnum;
-     int               hash;
      NR_TRANS  *np;
      int               page_count;
  
--- 1164,1169 ----
***************
*** 1235,1246 ****
      hp->bh_bnum = new_bnum;
      mf_ins_hash(mfp, hp);                 /* insert in new hash list */
  
!     hash = MEMHASH(np->nt_old_bnum);      /* insert in trans list */
!     np->nt_next = mfp->mf_trans[hash];
!     mfp->mf_trans[hash] = np;
!     if (np->nt_next != NULL)
!       np->nt_next->nt_prev = np;
!     np->nt_prev = NULL;
  
      return OK;
  }
--- 1211,1218 ----
      hp->bh_bnum = new_bnum;
      mf_ins_hash(mfp, hp);                 /* insert in new hash list */
  
!     /* Insert "np" into "mf_trans" hashtable with key "np->nt_old_bnum" */
!     mf_hash_add_item(&mfp->mf_trans, (mf_hashitem_T *)np);
  
      return OK;
  }
***************
*** 1255,1279 ****
      memfile_T *mfp;
      blocknr_T old_nr;
  {
-     int               hash;
      NR_TRANS  *np;
      blocknr_T new_bnum;
  
!     hash = MEMHASH(old_nr);
!     for (np = mfp->mf_trans[hash]; np != NULL; np = np->nt_next)
!       if (np->nt_old_bnum == old_nr)
!           break;
      if (np == NULL)           /* not found */
        return old_nr;
  
      mfp->mf_neg_count--;
      new_bnum = np->nt_new_bnum;
!     if (np->nt_prev != NULL)          /* remove entry from the trans list */
!       np->nt_prev->nt_next = np->nt_next;
!     else
!       mfp->mf_trans[hash] = np->nt_next;
!     if (np->nt_next != NULL)
!       np->nt_next->nt_prev = np->nt_prev;
      vim_free(np);
  
      return new_bnum;
--- 1227,1246 ----
      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);
! 
      if (np == NULL)           /* not found */
        return old_nr;
  
      mfp->mf_neg_count--;
      new_bnum = np->nt_new_bnum;
! 
!     /* remove entry from the trans list */
!     mf_hash_rem_item(&mfp->mf_trans, (mf_hashitem_T *)np);
! 
      vim_free(np);
  
      return new_bnum;
***************
*** 1397,1399 ****
--- 1364,1570 ----
        mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
      }
  }
+ 
+ /*
+  * Implementation of mf_hashtab_T follows.
+  */
+ 
+ /*
+  * The number of buckets in the hashtable is increased by a factor of
+  * MHT_GROWTH_FACTOR when the average number of items per bucket
+  * exceeds 2 ^ MHT_LOG_LOAD_FACTOR.
+  */
+ #define MHT_LOG_LOAD_FACTOR 6
+ #define MHT_GROWTH_FACTOR   2   /* must be a power of two */
+ 
+ /*
+  * Initialize an empty hash table.
+  */
+     static void
+ mf_hash_init(mht)
+     mf_hashtab_T *mht;
+ {
+     vim_memset(mht, 0, sizeof(mf_hashtab_T));
+     mht->mht_buckets = mht->mht_small_buckets;
+     mht->mht_mask = MHT_INIT_SIZE - 1;
+ }
+ 
+ /*
+  * Free the array of a hash table.  Does not free the items it contains!
+  * The hash table must not be used again without another mf_hash_init() call.
+  */
+     static void
+ mf_hash_free(mht)
+     mf_hashtab_T *mht;
+ {
+     if (mht->mht_buckets != mht->mht_small_buckets)
+       vim_free(mht->mht_buckets);
+ }
+ 
+ /*
+  * Free the array of a hash table and all the items it contains.
+  */
+     static void
+ mf_hash_free_all(mht)
+     mf_hashtab_T    *mht;
+ {
+     long_u        idx;
+     mf_hashitem_T   *mhi;
+     mf_hashitem_T   *next;
+ 
+     for (idx = 0; idx <= mht->mht_mask; idx++)
+       for (mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next)
+       {
+           next = mhi->mhi_next;
+           vim_free(mhi);
+       }
+ 
+     mf_hash_free(mht);
+ }
+ 
+ /*
+  * Find "key" in hashtable "mht".
+  * Returns a pointer to a mf_hashitem_T or NULL if the item was not found.
+  */
+     static mf_hashitem_T *
+ mf_hash_find(mht, key)
+     mf_hashtab_T    *mht;
+     blocknr_T     key;
+ {
+     mf_hashitem_T   *mhi;
+ 
+     mhi = mht->mht_buckets[key & mht->mht_mask];
+     while (mhi != NULL && mhi->mhi_key != key)
+       mhi = mhi->mhi_next;
+ 
+     return mhi;
+ }
+ 
+ /*
+  * Add item "mhi" to hashtable "mht".
+  * "mhi" must not be NULL.
+  */
+     static void
+ mf_hash_add_item(mht, mhi)
+     mf_hashtab_T    *mht;
+     mf_hashitem_T   *mhi;
+ {
+     long_u        idx;
+ 
+     idx = mhi->mhi_key & mht->mht_mask;
+     mhi->mhi_next = mht->mht_buckets[idx];
+     mhi->mhi_prev = NULL;
+     if (mhi->mhi_next != NULL)
+       mhi->mhi_next->mhi_prev = mhi;
+     mht->mht_buckets[idx] = mhi;
+ 
+     mht->mht_count++;
+ 
+     /*
+      * Grow hashtable when we have more thank 2^MHT_LOG_LOAD_FACTOR
+      * items per bucket on average
+      */
+     if (mht->mht_fixed == 0
+       && (mht->mht_count >> MHT_LOG_LOAD_FACTOR) > mht->mht_mask)
+     {
+       if (mf_hash_grow(mht) == FAIL)
+       {
+           /* stop trying to grow after first failure to allocate memory */
+           mht->mht_fixed = 1;
+       }
+     }
+ }
+ 
+ /*
+  * Remove item "mhi" from hashtable "mht".
+  * "mhi" must not be NULL and must have been inserted into "mht".
+  */
+     static void
+ mf_hash_rem_item(mht, mhi)
+     mf_hashtab_T    *mht;
+     mf_hashitem_T   *mhi;
+ {
+     if (mhi->mhi_prev == NULL)
+       mht->mht_buckets[mhi->mhi_key & mht->mht_mask] = mhi->mhi_next;
+     else
+       mhi->mhi_prev->mhi_next = mhi->mhi_next;
+ 
+     if (mhi->mhi_next != NULL)
+       mhi->mhi_next->mhi_prev = mhi->mhi_prev;
+ 
+     mht->mht_count--;
+ 
+     /* We could shrink the table here, but it typically takes little memory,
+      * so why bother?  */
+ }
+ 
+ /*
+  * Increase number of buckets in the hashtable by MHT_GROWTH_FACTOR and
+  * rehash items.
+  * Returns FAIL when out of memory.
+  */
+     static int
+ mf_hash_grow(mht)
+     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 = (mf_hashitem_T **)lalloc_clear(size, FALSE);
+     if (buckets == NULL)
+       return FAIL;
+ 
+     shift = 0;
+     while ((mht->mht_mask >> shift) != 0)
+       shift++;
+ 
+     for (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
+        * mf_get() tries to keep most recently used items at the front of
+        * each bucket.
+        *
+        * Here we strongly rely on the fact the hashes are computed modulo
+        * a power of two.
+        */
+ 
+       vim_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);
+           if (tails[j] == NULL)
+           {
+               buckets[i + (j << shift)] = mhi;
+               tails[j] = mhi;
+               mhi->mhi_prev = NULL;
+           }
+           else
+           {
+               tails[j]->mhi_next = mhi;
+               mhi->mhi_prev = tails[j];
+               tails[j] = mhi;
+           }
+       }
+ 
+       for (j = 0; j < MHT_GROWTH_FACTOR; j++)
+           if (tails[j] != NULL)
+               tails[j]->mhi_next = NULL;
+     }
+ 
+     if (mht->mht_buckets != mht->mht_small_buckets)
+       vim_free(mht->mht_buckets);
+ 
+     mht->mht_buckets = buckets;
+     mht->mht_mask = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR - 1;
+ 
+     return OK;
+ }
*** ../vim-7.3.142/src/memfile_test.c   2011-03-03 21:58:14.000000000 +0100
--- src/memfile_test.c  2011-03-03 20:40:29.000000000 +0100
***************
*** 0 ****
--- 1,145 ----
+ /* vi:set ts=8 sts=4 sw=4:
+  *
+  * VIM - Vi IMproved  by Bram Moolenaar
+  *
+  * Do ":help uganda"  in Vim to read copying and usage conditions.
+  * Do ":help credits" in Vim to see a list of people who contributed.
+  * See README.txt for an overview of the Vim source code.
+  */
+ 
+ /*
+  * memfile_test.c: Unittests for memfile.c
+  * Mostly by Ivan Krasilnikov.
+  */
+ 
+ #undef NDEBUG
+ #include <assert.h>
+ 
+ /* Must include main.c because it contains much more than just main() */
+ #define NO_VIM_MAIN
+ #include "main.c"
+ 
+ /* This file has to be included because the tested functions are static */
+ #include "memfile.c"
+ 
+ #define index_to_key(i) ((i) ^ 15167)
+ #define TEST_COUNT 50000
+ 
+ static void test_mf_hash __ARGS((void));
+ 
+ /*
+  * Test mf_hash_*() functions.
+  */
+     static void
+ test_mf_hash()
+ {
+     mf_hashtab_T   ht;
+     mf_hashitem_T  *item;
+     blocknr_T      key;
+     long_u       i;
+     long_u       num_buckets;
+ 
+     mf_hash_init(&ht);
+ 
+     /* insert some items and check invariants */
+     for (i = 0; i < TEST_COUNT; i++)
+     {
+       assert(ht.mht_count == i);
+ 
+       /* check that number of buckets is a power of 2 */
+       num_buckets = ht.mht_mask + 1;
+       assert(num_buckets > 0 && (num_buckets & (num_buckets - 1)) == 0);
+ 
+       /* check load factor */
+       assert(ht.mht_count <= (num_buckets << MHT_LOG_LOAD_FACTOR));
+ 
+       if (i < (MHT_INIT_SIZE << MHT_LOG_LOAD_FACTOR))
+       {
+           /* first expansion shouldn't have occurred yet */
+           assert(num_buckets == MHT_INIT_SIZE);
+           assert(ht.mht_buckets == ht.mht_small_buckets);
+       }
+       else
+       {
+           assert(num_buckets > MHT_INIT_SIZE);
+           assert(ht.mht_buckets != ht.mht_small_buckets);
+       }
+ 
+       key = index_to_key(i);
+       assert(mf_hash_find(&ht, key) == NULL);
+ 
+       /* allocate and add new item */
+       item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);
+       assert(item != NULL);
+       item->mhi_key = key;
+       mf_hash_add_item(&ht, item);
+ 
+       assert(mf_hash_find(&ht, key) == item);
+ 
+       if (ht.mht_mask + 1 != num_buckets)
+       {
+           /* hash table was expanded */
+           assert(ht.mht_mask + 1 == num_buckets * MHT_GROWTH_FACTOR);
+           assert(i + 1 == (num_buckets << MHT_LOG_LOAD_FACTOR));
+       }
+     }
+ 
+     /* check presence of inserted items */
+     for (i = 0; i < TEST_COUNT; i++)
+     {
+       key = index_to_key(i);
+       item = mf_hash_find(&ht, key);
+       assert(item != NULL);
+       assert(item->mhi_key == key);
+     }
+ 
+     /* delete some items */
+     for (i = 0; i < TEST_COUNT; i++)
+     {
+       if (i % 100 < 70)
+       {
+           key = index_to_key(i);
+           item = mf_hash_find(&ht, key);
+           assert(item != NULL);
+           assert(item->mhi_key == key);
+ 
+           mf_hash_rem_item(&ht, item);
+           assert(mf_hash_find(&ht, key) == NULL);
+ 
+           mf_hash_add_item(&ht, item);
+           assert(mf_hash_find(&ht, key) == item);
+ 
+           mf_hash_rem_item(&ht, item);
+           assert(mf_hash_find(&ht, key) == NULL);
+ 
+           vim_free(item);
+       }
+     }
+ 
+     /* check again */
+     for (i = 0; i < TEST_COUNT; i++)
+     {
+       key = index_to_key(i);
+       item = mf_hash_find(&ht, key);
+ 
+       if (i % 100 < 70)
+       {
+           assert(item == NULL);
+       }
+       else
+       {
+           assert(item != NULL);
+           assert(item->mhi_key == key);
+       }
+     }
+ 
+     /* free hash table and all remaining items */
+     mf_hash_free_all(&ht);
+ }
+ 
+     int
+ main()
+ {
+     test_mf_hash();
+     return 0;
+ }
*** ../vim-7.3.142/src/structs.h        2011-02-15 17:39:14.000000000 +0100
--- src/structs.h       2011-03-03 18:49:01.000000000 +0100
***************
*** 378,383 ****
--- 378,412 ----
  typedef long              blocknr_T;
  
  /*
+  * mf_hashtab_T is a chained hashtable with blocknr_T key and arbitrary
+  * structures as items.  This is an intrusive data structure: we require
+  * that items begin with mf_hashitem_T which contains the key and linked
+  * list pointers.  List of items in each bucket is doubly-linked.
+  */
+ 
+ typedef struct mf_hashitem_S mf_hashitem_T;
+ 
+ struct mf_hashitem_S
+ {
+     mf_hashitem_T   *mhi_next;
+     mf_hashitem_T   *mhi_prev;
+     blocknr_T     mhi_key;
+ };
+ 
+ #define MHT_INIT_SIZE   64
+ 
+ typedef struct mf_hashtab_S
+ {
+     long_u        mht_mask;       /* mask used for hash value (nr of items
+                                    * in array is "mht_mask" + 1) */
+     long_u        mht_count;      /* nr of items inserted into hashtable */
+     mf_hashitem_T   **mht_buckets;  /* points to mht_small_buckets or
+                                    *dynamically allocated array */
+     mf_hashitem_T   *mht_small_buckets[MHT_INIT_SIZE];   /* initial buckets */
+     char          mht_fixed;      /* non-zero value forbids growth */
+ } mf_hashtab_T;
+ 
+ /*
   * for each (previously) used block in the memfile there is one block header.
   *
   * The block may be linked in the used list OR in the free list.
***************
*** 394,404 ****
  
  struct block_hdr
  {
      bhdr_T    *bh_next;           /* next block_hdr in free or used list */
      bhdr_T    *bh_prev;           /* previous block_hdr in used list */
-     bhdr_T    *bh_hash_next;      /* next block_hdr in hash list */
-     bhdr_T    *bh_hash_prev;      /* previous block_hdr in hash list */
-     blocknr_T bh_bnum;            /* block number */
      char_u    *bh_data;           /* pointer to memory (for used block) */
      int               bh_page_count;      /* number of pages in this block */
  
--- 423,433 ----
  
  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 */
      char_u    *bh_data;           /* pointer to memory (for used block) */
      int               bh_page_count;      /* number of pages in this block */
  
***************
*** 417,425 ****
  
  struct nr_trans
  {
!     NR_TRANS  *nt_next;               /* next nr_trans in hash list */
!     NR_TRANS  *nt_prev;               /* previous nr_trans in hash list */
!     blocknr_T nt_old_bnum;            /* old, negative, number */
      blocknr_T nt_new_bnum;            /* new, positive, number */
  };
  
--- 446,454 ----
  
  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 */
  };
  
***************
*** 499,510 ****
  
  typedef struct file_buffer buf_T;  /* forward declaration */
  
- /*
-  * Simplistic hashing scheme to quickly locate the blocks in the used list.
-  * 64 blocks are found directly (64 * 4K = 256K, most files are smaller).
-  */
- #define MEMHASHSIZE   64
- #define MEMHASH(nr)   ((nr) & (MEMHASHSIZE - 1))
  #define MF_SEED_LEN   8
  
  struct memfile
--- 528,533 ----
***************
*** 517,524 ****
      bhdr_T    *mf_used_last;          /* lru block_hdr in used list */
      unsigned  mf_used_count;          /* number of pages in used list */
      unsigned  mf_used_count_max;      /* maximum number of pages in memory */
!     bhdr_T    *mf_hash[MEMHASHSIZE];  /* array of hash lists */
!     NR_TRANS  *mf_trans[MEMHASHSIZE]; /* array of trans lists */
      blocknr_T mf_blocknr_max;         /* highest positive block number + 1*/
      blocknr_T mf_blocknr_min;         /* lowest negative block number - 1 */
      blocknr_T mf_neg_count;           /* number of negative blocks numbers */
--- 540,547 ----
      bhdr_T    *mf_used_last;          /* lru block_hdr in used list */
      unsigned  mf_used_count;          /* number of pages in used list */
      unsigned  mf_used_count_max;      /* maximum number of pages in memory */
!     mf_hashtab_T mf_hash;             /* hash lists */
!     mf_hashtab_T mf_trans;            /* trans lists */
      blocknr_T mf_blocknr_max;         /* highest positive block number + 1*/
      blocknr_T mf_blocknr_min;         /* lowest negative block number - 1 */
      blocknr_T mf_neg_count;           /* number of negative blocks numbers */
*** ../vim-7.3.142/src/testdir/Make_amiga.mak   2010-11-10 16:54:16.000000000 
+0100
--- src/testdir/Make_amiga.mak  2011-03-03 17:04:14.000000000 +0100
***************
*** 28,34 ****
                test61.out test62.out test63.out test64.out test65.out \
                test66.out test67.out test68.out test69.out test70.out \
                test71.out test72.out test73.out test74.out test75.out \
!               test76.out
  
  .SUFFIXES: .in .out
  
--- 28,34 ----
                test61.out test62.out test63.out test64.out test65.out \
                test66.out test67.out test68.out test69.out test70.out \
                test71.out test72.out test73.out test74.out test75.out \
!               test76.out test77.out
  
  .SUFFIXES: .in .out
  
***************
*** 124,126 ****
--- 124,127 ----
  test74.out: test74.in
  test75.out: test75.in
  test76.out: test76.in
+ test77.out: test77.in
*** ../vim-7.3.142/src/testdir/Make_dos.mak     2010-11-10 16:54:16.000000000 
+0100
--- src/testdir/Make_dos.mak    2011-03-03 17:04:20.000000000 +0100
***************
*** 28,34 ****
                test37.out test38.out test39.out test40.out test41.out \
                test42.out test52.out test65.out test66.out test67.out \
                test68.out test69.out test71.out test72.out test73.out \
!               test74.out test75.out test76.out
  
  SCRIPTS32 =   test50.out test70.out
  
--- 28,34 ----
                test37.out test38.out test39.out test40.out test41.out \
                test42.out test52.out test65.out test66.out test67.out \
                test68.out test69.out test71.out test72.out test73.out \
!               test74.out test75.out test76.out test77.out
  
  SCRIPTS32 =   test50.out test70.out
  
*** ../vim-7.3.142/src/testdir/Make_ming.mak    2010-11-10 16:54:16.000000000 
+0100
--- src/testdir/Make_ming.mak   2011-03-03 17:04:32.000000000 +0100
***************
*** 48,54 ****
                test37.out test38.out test39.out test40.out test41.out \
                test42.out test52.out test65.out test66.out test67.out \
                test68.out test69.out test71.out test72.out test73.out \
!               test74.out test75.out test76.out
  
  SCRIPTS32 =   test50.out test70.out
  
--- 48,54 ----
                test37.out test38.out test39.out test40.out test41.out \
                test42.out test52.out test65.out test66.out test67.out \
                test68.out test69.out test71.out test72.out test73.out \
!               test74.out test75.out test76.out test77.out
  
  SCRIPTS32 =   test50.out test70.out
  
*** ../vim-7.3.142/src/testdir/Make_os2.mak     2010-11-10 16:54:16.000000000 
+0100
--- src/testdir/Make_os2.mak    2011-03-03 17:04:48.000000000 +0100
***************
*** 28,34 ****
                test61.out test62.out test63.out test64.out test65.out \
                test66.out test67.out test68.out test69.out test70.out \
                test71.out test72.out test73.out test74.out test75.out \
!               test76.out
  
  .SUFFIXES: .in .out
  
--- 28,34 ----
                test61.out test62.out test63.out test64.out test65.out \
                test66.out test67.out test68.out test69.out test70.out \
                test71.out test72.out test73.out test74.out test75.out \
!               test76.out test77.out
  
  .SUFFIXES: .in .out
  
*** ../vim-7.3.142/src/testdir/Makefile 2010-11-10 16:54:16.000000000 +0100
--- src/testdir/Makefile        2011-03-22 17:03:25.000000000 +0100
***************
*** 25,31 ****
                test59.out test60.out test61.out test62.out test63.out \
                test64.out test65.out test66.out test67.out test68.out \
                test69.out test70.out test71.out test72.out test73.out \
!               test74.out test75.out test76.out
  
  SCRIPTS_GUI = test16.out
  
--- 25,31 ----
                test59.out test60.out test61.out test62.out test63.out \
                test64.out test65.out test66.out test67.out test68.out \
                test69.out test70.out test71.out test72.out test73.out \
!               test74.out test75.out test76.out test77.out
  
  SCRIPTS_GUI = test16.out
  
***************
*** 71,77 ****
                  fi \
                else echo $* NO OUTPUT >>test.log; \
                fi"
!       -rm -rf X* test.ok viminfo
  
  test49.out: test49.vim
  
--- 71,77 ----
                  fi \
                else echo $* NO OUTPUT >>test.log; \
                fi"
! #     -rm -rf X* test.ok viminfo
  
  test49.out: test49.vim
  
*** ../vim-7.3.142/src/testdir/test77.in        2011-03-03 21:59:10.000000000 
+0100
--- src/testdir/test77.in       2011-03-22 17:12:38.000000000 +0100
***************
*** 0 ****
--- 1,27 ----
+ Inserts 2 million lines with consecutive integers starting from 1
+ (essentially, the output of GNU's seq 1 2000000), writes them to Xtest
+ and writes its cksum to test.out.
+ 
+ We need 2 million lines to trigger a call to mf_hash_grow().  If it would mess
+ up the lines the checksum would differ.
+ 
+ cksum is part of POSIX and so should be available on most Unixes.
+ If it isn't available then the test will be skipped.
+ 
+ STARTTEST
+ :so small.vim
+ :if !executable("cksum")
+ : e! test.ok
+ : w! test.out
+ : qa!
+ :endif
+ :set fileformat=unix undolevels=-1
+ ggdG
+ :let i = 1
+ :while i <= 2000000 | call append(i, range(i, i + 99)) | let i += 100 | 
endwhile
+ ggdd
+ :w! Xtest
+ :!cksum Xtest > test.out
+ :qa!
+ ENDTEST
+ 
*** ../vim-7.3.142/src/testdir/test77.ok        2011-03-03 21:59:10.000000000 
+0100
--- src/testdir/test77.ok       2011-03-22 17:10:14.000000000 +0100
***************
*** 0 ****
--- 1 ----
+ 3678979763 14888896 Xtest
*** ../vim-7.3.142/src/version.c        2011-03-22 15:47:18.000000000 +0100
--- src/version.c       2011-03-22 18:01:48.000000000 +0100
***************
*** 716,717 ****
--- 716,719 ----
  {   /* Add new patch number below this line */
+ /**/
+     143,
  /**/

-- 
SIGIRO -- irony detected (iron core dumped)

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui