I have now tested this. First number is mmap CRC. Second number is 
istream_iterator CRC. They seem to fail differently on directories - in 
this case, I think that istream_iterator version is wrong.

This patch only applies to BRANCH_1_1_6. I will send another for 1.2.

I haven't compiled the whole of LyX with this because cvs is broken atm 
(see my other mail), but I have compiled it in 2 different ways as per 
JML's request.

$ checkCRC /boot/*
/boot/boot.0300 1729887102 1729887102 OK
/boot/boot.b 2073074794 2073074794 OK
/boot/chain.b 361202963 361202963 OK
/boot/kernel.h 1951086079 1951086079 OK
/boot/kernel.h-2.4.2 1951086079 1951086079 OK
/boot/lost+found 0 4294967295 FAIL
/boot/map 0 0 OK
/boot/message 4218120946 4218120946 OK
/boot/module-info 3046675311 3046675311 OK
/boot/module-info-2.4.2-2 3046675311 3046675311 OK
/boot/os2_d.b 679864059 679864059 OK
/boot/System.map 3662491832 3662491832 OK
/boot/System.map-2.4.2-2 3542708047 3542708047 OK
/boot/System.map-2.4.4 279845350 279845350 OK
/boot/System.map-2.4.5-ac5 1886247741 1886247741 OK
/boot/System.map-2.4.6 3662491832 3662491832 OK
/boot/System.map.old 583674341 583674341 OK
/boot/vmlinux-2.4.2-2 3009846913 3009846913 OK
/boot/vmlinuz 1730371782 1730371782 OK
/boot/vmlinuz-2.4.2-2 3873679430 3873679430 OK
/boot/vmlinuz-2.4.4 1055800826 1055800826 OK
/boot/vmlinuz-2.4.5-ac5 3968027610 3968027610 OK
/boot/vmlinuz-2.4.6 1730371782 1730371782 OK
/boot/vmlinuz.old 3071668570 3071668570 OK
There was 1 failure.
/boot/lost+found

$ cat checkCRC
#!/bin/sh
# Runs the lyxsum programs on every file given in the argument list and
# records any failures.

PROG1=lyxsum.mmap
PROG2=lyxsum.istream_iterator

FAILCOUNT=0;
FAILLIST=""

for file in $@
do
  CRC1=`$PROG1 $file | awk -- '{print $2}'`
  CRC2=`$PROG2 $file | awk -- '{print $2}'`

  if [ $CRC1 -eq $CRC2 ]
  then
      RESULT="OK"
  else
      RESULT="FAIL"
      FAILCOUNT=`echo $FAILCOUNT + 1 | bc`
      FAILLIST="$FAILLIST $file"
  fi
  echo $file $CRC1 $CRC2 $RESULT
done

if [ $FAILCOUNT -ne 0 ]
then
    if [ $FAILCOUNT -eq 1 ]
    then
        echo There was 1 failure.
    else
        echo "There were $FAILCOUNT failures."
    fi
    echo $FAILLIST
else
    echo "All tests passed"
fi

--- lyx-devel-orig/src/support/lyxsum.C Wed Jun  6 02:52:55 2001
+++ lyx-devel/src/support/lyxsum.C      Thu Nov 29 02:01:41 2001
@@ -1,7 +1,7 @@
 /* This file is part of
  * ======================================================
- * 
- *           LyX, The Document Processor        
+ *
+ *           LyX, The Document Processor
  *
  *    The function lyx::sum is taken from GNU textutill-1.22
  *    and is there part of the program chsum. The chsum program
@@ -15,14 +15,8 @@
 
 #include <config.h>
 
-#include <fstream>
-#include <iterator>
-
 #include "support/lyxlib.h"
 
-using std::ifstream;
-using std::ios;
-
 // DO _NOT_ CHANGE _ANYTHING_ IN THIS TABLE
 static
 unsigned long const crctab[256] =
@@ -83,7 +77,7 @@
 
 /* Calculate the checksum of file FILE.
    Return crc if successful, 0 if an error occurs. */
- 
+
 template<typename InputIterator>
 static inline
 unsigned long do_crc(InputIterator first, InputIterator last)
@@ -104,23 +98,86 @@
 }
 
 
-// And this would be the file interface.
-unsigned long lyx::sum(string const & file)
-{
-       std::ifstream ifs(file.c_str());
-       if (!ifs) return 0;
-       
-#ifdef HAVE_DECL_ISTREAMBUF_ITERATOR
-       // This is a lot faster...
-       std::istreambuf_iterator<char> beg(ifs);
-       std::istreambuf_iterator<char> end;
+// Various implementations of lyx::sum(), depending on what methods
+// are available. Order is faster to slowest.
+#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
+       #ifdef WITH_WARNINGS
+               #warning lyx::sum() using mmap (lightning fast but untested)
+       #endif
+
+       #include <sys/types.h>
+       #include <sys/stat.h>
+       #include <fcntl.h>
+       #include <unistd.h>
+       #include <sys/mman.h>
+
+       unsigned long lyx::sum(string const & file)
+       {
+               int fd = open(file.c_str(), O_RDONLY);
+               if( !fd ) return 0;
+
+               struct stat info;
+               fstat(fd, &info);
+
+               void * mm = mmap(0, info.st_size, PROT_READ,
+                                MAP_PRIVATE, fd, 0);
+               if (mm == MAP_FAILED) {
+                       close(fd);
+                       return 0;
+               }
+               char *beg = static_cast<char*>(mm);
+               char *end = beg + info.st_size;
+
+               unsigned long result = do_crc(beg,end);
+
+               munmap( mm, info.st_size );
+               close(fd);
+
+               return result;
+       }
 #else
-       // than this.
-       ifs.unsetf(std::ios::skipws);
-       std::istream_iterator<char> beg(ifs);
-       std::istream_iterator<char> end;
+       #include <fstream>
+       #include <iterator>
+
+       #if HAVE_DECL_ISTREAMBUF_ITERATOR
+               #ifdef WITH_WARNINGS
+                       #warning lyx::sum() using istreambuf_iterator (fast)
+               #endif
+               unsigned long lyx::sum(string const & file)
+               {
+                       std::ifstream ifs(file.c_str());
+                       if (!ifs) return 0;
+
+                       std::istreambuf_iterator<char> beg(ifs);
+                       std::istreambuf_iterator<char> end;
+
+                       return do_crc(beg,end);
+               }
+       #else
+               #ifdef WITH_WARNINGS
+                       #warning lyx::sum() using istream_iterator (slow as a snail)
+               #endif
+               unsigned long lyx::sum(string const & file)
+               {
+                       std::ifstream ifs(file.c_str());
+                       if (!ifs) return 0;
+
+                       ifs.unsetf(std::ios::skipws);
+                       std::istream_iterator<char> beg(ifs);
+                       std::istream_iterator<char> end;
+
+                       return do_crc(beg,end);
+               }
+       #endif
 #endif
 
-       return do_crc(beg, end);
+#if 0
+#include <iostream>
+int main(int /*argc*/, char * argv[])
+{
+       std::string const fil(argv[1]);
+
+       std::cout << "CRC: " << lyx::sum(fil) << std::endl;
 }
+#endif
 

Reply via email to