* Merged in jbm's changes for Linux compatibility, fixing Mac compatibility in the process :) default tip
authorJens Alfke <jens@mooseyard.com>
Tue Sep 29 15:46:42 2009 -0700 (2009-09-29)
changeset 9629f61203db1
parent 8 21a6c17f4e3e
* Merged in jbm's changes for Linux compatibility, fixing Mac compatibility in the process :)
* Fixed two regressions having to do with the _previousTrailerPosition in VersionDictionary.cpp.
* Made sure RTTI is enabled in the OttomanTest target because gtest requires it.
Ottoman.xcodeproj/project.pbxproj
include/Base.h
include/File.h
src/File.cpp
src/Index.cpp
src/Ottoman.cpp
src/VersionDictionary.cpp
test/TestUtils.cpp
test/VersionDictionary_test.cpp
     1.1 --- a/Ottoman.xcodeproj/project.pbxproj	Mon Sep 28 23:39:08 2009 -0700
     1.2 +++ b/Ottoman.xcodeproj/project.pbxproj	Tue Sep 29 15:46:42 2009 -0700
     1.3 @@ -409,6 +409,7 @@
     1.4  				ALWAYS_SEARCH_USER_PATHS = NO;
     1.5  				COPY_PHASE_STRIP = NO;
     1.6  				GCC_DYNAMIC_NO_PIC = NO;
     1.7 +				GCC_ENABLE_CPP_RTTI = YES;
     1.8  				GCC_ENABLE_FIX_AND_CONTINUE = YES;
     1.9  				GCC_MODEL_TUNING = G5;
    1.10  				GCC_OPTIMIZATION_LEVEL = 0;
    1.11 @@ -423,6 +424,7 @@
    1.12  			buildSettings = {
    1.13  				ALWAYS_SEARCH_USER_PATHS = NO;
    1.14  				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
    1.15 +				GCC_ENABLE_CPP_RTTI = YES;
    1.16  				GCC_MODEL_TUNING = G5;
    1.17  				INSTALL_PATH = /usr/local/bin;
    1.18  				PRODUCT_NAME = OttomanTest;
    1.19 @@ -434,6 +436,7 @@
    1.20  			buildSettings = {
    1.21  				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
    1.22  				GCC_C_LANGUAGE_STANDARD = c99;
    1.23 +				GCC_ENABLE_CPP_RTTI = NO;
    1.24  				GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
    1.25  				GCC_OPTIMIZATION_LEVEL = 0;
    1.26  				GCC_PRECOMPILE_PREFIX_HEADER = YES;
     2.1 --- a/include/Base.h	Mon Sep 28 23:39:08 2009 -0700
     2.2 +++ b/include/Base.h	Tue Sep 29 15:46:42 2009 -0700
     2.3 @@ -13,17 +13,8 @@
     2.4  #include <stdint.h>
     2.5  #include <string.h>
     2.6  
     2.7 -#if OSX
     2.8 -/* OS X specific bits */
     2.9 -#include <libkern/OSByteOrder.h>
    2.10 +#ifdef __MACH__ /* OS X specific bits */
    2.11  #include <CoreFoundation/CFByteOrder.h>
    2.12 -
    2.13 -#else
    2.14 -/* OS X fixup kludge bits */
    2.15 -
    2.16 -#include <cf_fixup.h>
    2.17 -#include <stdint.h>
    2.18 -
    2.19  #endif
    2.20  
    2.21  namespace Mooseyard {
    2.22 @@ -105,7 +96,8 @@
    2.23          _value = p._value;
    2.24          return *this;
    2.25      }
    2.26 -    
    2.27 +   
    2.28 +#ifdef __COREFOUNDATION_CFBYTEORDER__
    2.29      template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i) 
    2.30      {return OSSwapHostToLittleInt32(i);}
    2.31      template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i) 
    2.32 @@ -118,7 +110,21 @@
    2.33      {return CFConvertDoubleHostToSwapped(d);}
    2.34      template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d) 
    2.35      {return CFConvertDoubleSwappedToHost(d);}
    2.36 -    
    2.37 +#else
    2.38 +    //FIXME: Not implemented yet for non-Mac platforms
    2.39 +    template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i) 
    2.40 +    {return i;}
    2.41 +    template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i) 
    2.42 +    {return i;}
    2.43 +    template <> inline uint16_t LittleEndian<uint16_t>::makeLittle (uint16_t i) 
    2.44 +    {return i;}
    2.45 +    template <> inline uint16_t LittleEndian<uint16_t>::makeNative (uint16_t i) 
    2.46 +    {return i;}
    2.47 +    template <> inline CFSwappedFloat64 LittleEndian<double,CFSwappedFloat64>::makeLittle (double d) 
    2.48 +    {return d;}
    2.49 +    template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d) 
    2.50 +    {return d;}
    2.51 +#endif
    2.52  }
    2.53  
    2.54  #endif /* _MOOSEYARD_BASE_ */
     3.1 --- a/include/File.h	Mon Sep 28 23:39:08 2009 -0700
     3.2 +++ b/include/File.h	Tue Sep 29 15:46:42 2009 -0700
     3.3 @@ -30,8 +30,7 @@
     3.4      static const int kEOF = 10001;
     3.5      
     3.6      
     3.7 -    File (const char *filename, bool writeable =false, bool create =false)  throw(Error);
     3.8 -    File (const char *filename, int oflag, bool locked)  throw(Error);
     3.9 +    File (const char *filename, int oflag, bool locked =false)  throw(Error);
    3.10      ~File();
    3.11      
    3.12      off_t length() const  throw(Error);
    3.13 @@ -90,10 +89,6 @@
    3.14  private:
    3.15      static int _open (const char *filename, int posixMode)  throw(Error);
    3.16      static int _check (int result)  throw(Error);
    3.17 -#ifdef OSX /* On linux, these are the same type signature to gcc */
    3.18 -    static ssize_t _check (ssize_t result)  throw(Error)    {_check((int)result); return result;}
    3.19 -    static off_t _check (off_t result)  throw(Error)    {_check((int)result); return result;}
    3.20 -#endif
    3.21      static void _checkRead (ssize_t result, size_t expectedSize)  throw(Error);
    3.22      bool _lock (bool block);
    3.23      void _unlock();
     4.1 --- a/src/File.cpp	Mon Sep 28 23:39:08 2009 -0700
     4.2 +++ b/src/File.cpp	Tue Sep 29 15:46:42 2009 -0700
     4.3 @@ -21,14 +21,8 @@
     4.4  
     4.5  namespace Mooseyard {
     4.6      
     4.7 -    File::File (const char *filename, bool writeable, bool create)  throw(Error)
     4.8 -        :_fd(_check( ::open(filename, writeable ?(create ?O_RDWR|O_CREAT :O_RDWR) :O_RDONLY, 0644) )),
     4.9 -         _memoryMap(NULL),
    4.10 -         _locked(0)
    4.11 -    { }
    4.12 -
    4.13      File::File (const char *filename, int oflag, bool locked)  throw(Error)
    4.14 -#if BSD
    4.15 +#ifdef _DARWIN_C_SOURCE
    4.16          :_fd(_check( ::open(filename, oflag | (locked ? O_EXLOCK : 0), 0644) )),
    4.17  #else
    4.18          :_fd(_check( ::open(filename, oflag, 0644) )),
    4.19 @@ -36,7 +30,7 @@
    4.20           _memoryMap(NULL),
    4.21           _locked( locked ? 1 : 0)
    4.22      {
    4.23 -#if !BSDISH
    4.24 +#ifndef _DARWIN_C_SOURCE
    4.25        _check( ::flock(_fd, LOCK_EX) );
    4.26  #endif
    4.27      }
    4.28 @@ -59,15 +53,21 @@
    4.29      }
    4.30  
    4.31      off_t File::position() const  throw(Error) {
    4.32 -        return _check( lseek(_fd,0,SEEK_CUR) );
    4.33 +        off_t pos = lseek(_fd,0,SEEK_CUR);
    4.34 +        if (pos < 0)
    4.35 +            _check(-1);
    4.36 +        return pos;
    4.37      }
    4.38      
    4.39      void File::setPosition (off_t pos)  throw(Error) {
    4.40 -        _check( lseek(_fd,pos,SEEK_SET) );
    4.41 +        _check( (int) lseek(_fd,pos,SEEK_SET) );
    4.42      }
    4.43      
    4.44      off_t File::setPositionToEnd (off_t bytesBefore)  throw(Error) {
    4.45 -        return _check( lseek(_fd,-bytesBefore,SEEK_END) );
    4.46 +        off_t pos = lseek(_fd,-bytesBefore,SEEK_END);
    4.47 +        if (pos < 0)
    4.48 +            _check(-1);
    4.49 +        return pos;
    4.50      }
    4.51      
    4.52      void File::read (void *dst, size_t size)  throw(Error) {
    4.53 @@ -111,7 +111,13 @@
    4.54      }
    4.55      
    4.56      void File::flushDisk()  throw(Error) {
    4.57 -#if OSX
    4.58 +#if _DARWIN_C_SOURCE
    4.59 +        /* F_FULLFSYNC is Mac/Darwin specific. From the man page:
    4.60 +         Does the same thing as fsync(2) then asks the drive to flush all buffered data to
    4.61 +         the permanent storage device (arg is ignored).  This is currently implemented on
    4.62 +         HFS, MS-DOS (FAT), and Universal Disk Format (UDF) file systems.  The operation may
    4.63 +         take quite a while to complete.  Certain FireWire drives have also been known to
    4.64 +         ignore the request to flush their buffered data. */
    4.65          _check( ::fcntl(_fd,F_FULLFSYNC) );
    4.66  #else
    4.67          _check( fsync(_fd) );
     5.1 --- a/src/Index.cpp	Mon Sep 28 23:39:08 2009 -0700
     5.2 +++ b/src/Index.cpp	Tue Sep 29 15:46:42 2009 -0700
     5.3 @@ -15,10 +15,6 @@
     5.4  #include <errno.h>
     5.5  #include <algorithm>
     5.6  #include <math.h>
     5.7 -
     5.8 -#define __STDC_LIMIT_MACROS /* I <3 you, C99 */
     5.9 -# define UINT32_MAX             (4294967295U)
    5.10 - 
    5.11  #include <stdint.h>
    5.12  
    5.13  
     6.1 --- a/src/Ottoman.cpp	Mon Sep 28 23:39:08 2009 -0700
     6.2 +++ b/src/Ottoman.cpp	Tue Sep 29 15:46:42 2009 -0700
     6.3 @@ -42,6 +42,7 @@
     6.4      
     6.5      Ottoman::Ottoman()
     6.6      :_writeable(true),
     6.7 +     _file(NULL),
     6.8       _filename(NULL),
     6.9       _lastVersion(NULL),
    6.10       _current( new OverlayDictionary(&Dictionary::kEmpty) )
    6.11 @@ -96,6 +97,9 @@
    6.12              delete _file;
    6.13              _file = curFile;
    6.14          }
    6.15 +        
    6.16 +        if (changed)
    6.17 +            versionsChanged();
    6.18          return changed;
    6.19      }
    6.20      
    6.21 @@ -196,11 +200,12 @@
    6.22          if (!lastVersion)
    6.23              lastVersion = new VersionDictionary(dstFile);
    6.24          VersionDictionary *saved = lastVersion->_appendAndOpen(_current->overlay(), 
    6.25 -                                                            dstFile,
    6.26 -                                                            _current->baseReplaced());
    6.27 +                                                               dstFile,
    6.28 +                                                               _current->baseReplaced());
    6.29          // (don't delete _lastVersion: saved->_previousVersion now points to it.)
    6.30          _lastVersion = saved;
    6.31          _current->revertTo(_lastVersion);
    6.32 +        versionsChanged();
    6.33      }
    6.34      
    6.35      bool Ottoman::save() {
    6.36 @@ -235,6 +240,7 @@
    6.37          File *dstFile = _writeTo(dstFileName, overwriteAllowed);
    6.38          free(_filename);
    6.39          _filename = strdup(dstFileName);
    6.40 +        delete _file;
    6.41          _file = dstFile;
    6.42      }
    6.43  
    6.44 @@ -242,8 +248,13 @@
    6.45          if (!_file)
    6.46              return false;
    6.47          char tempFileName[1024];
    6.48 +#ifdef _DARWIN_C_SOURCE
    6.49 +        ::strlcpy(tempFileName, _filename, sizeof(tempFileName)-1);
    6.50 +        ::strlcat(tempFileName, "~", sizeof(tempFileName));
    6.51 +#else
    6.52          ::strncpy(tempFileName, _filename, sizeof(tempFileName)-1);
    6.53          ::strncat(tempFileName, "~", sizeof(tempFileName));
    6.54 +#endif
    6.55          File *tempFile;
    6.56          {
    6.57              // Check for conflict in existing file:
     7.1 --- a/src/VersionDictionary.cpp	Mon Sep 28 23:39:08 2009 -0700
     7.2 +++ b/src/VersionDictionary.cpp	Tue Sep 29 15:46:42 2009 -0700
     7.3 @@ -12,13 +12,12 @@
     7.4  #include "Index.h"
     7.5  #include "File.h"
     7.6  #include "Chunk.h"
     7.7 +#include <algorithm>
     7.8  #include <assert.h>
     7.9  #include <errno.h>
    7.10 -#include <algorithm>
    7.11 +#include <stdint.h>
    7.12  #include <time.h>
    7.13  
    7.14 -# define UINT32_MAX             (4294967295U)
    7.15 -
    7.16  
    7.17  namespace Mooseyard {
    7.18              
    7.19 @@ -153,9 +152,8 @@
    7.20  
    7.21          // Verify Indexes:
    7.22          for (int i=0; i<256; i++) {
    7.23 -            if (_indexPositions[i] > 0)
    7.24 -                if (_indexPositions[i] < _previousTrailerPosition || _indexPositions[i] >= _trailerPosition)
    7.25 -                    throw File::Error("Bad VersionDictionary trailer (illegal index position)");
    7.26 +            if (_indexPositions[i] >= _trailerPosition)
    7.27 +                throw File::Error("Bad VersionDictionary trailer (illegal index position)");
    7.28              const Index *index = _index(i);
    7.29              if (index)
    7.30                  index->validate();
    7.31 @@ -289,10 +287,13 @@
    7.32              dstFile->flushDisk();
    7.33              
    7.34              // Write the trailer:
    7.35 +            FilePosition previousTrailerPosition = 0;
    7.36 +            if (dstFile==srcFile)
    7.37 +                previousTrailerPosition = baseDict->_trailerPosition;
    7.38              FilePosition newTrailerPosition = pos;
    7.39              VersionDictionary::Trailer trailer(newCount,
    7.40                                              newIndexPositions,
    7.41 -                                            baseDict->_trailerPosition,
    7.42 +                                            previousTrailerPosition,
    7.43                                              baseDict->generation() + 1);
    7.44              pos += dstFile->write(trailer);
    7.45              
    7.46 @@ -312,10 +313,7 @@
    7.47          }
    7.48      }
    7.49   
    7.50 -    
    7.51 -#pragma mark -
    7.52 -#pragma mark TESTING-ONLY:
    7.53 -    
    7.54 +
    7.55      VersionDictionary* VersionDictionary::_appendAndOpen (const Dictionary *addDict,
    7.56                                                      File *dstFile, 
    7.57                                                      bool replace) const
    7.58 @@ -326,6 +324,10 @@
    7.59          return nextVersion;
    7.60      }
    7.61      
    7.62 +    
    7.63 +#pragma mark -
    7.64 +#pragma mark TESTING-ONLY:
    7.65 +
    7.66      VersionDictionary* VersionDictionary::create (File *file, const Dictionary *srcDict) {
    7.67          return VersionDictionary(file)._appendAndOpen(srcDict, file, true);
    7.68      }
     8.1 --- a/test/TestUtils.cpp	Mon Sep 28 23:39:08 2009 -0700
     8.2 +++ b/test/TestUtils.cpp	Tue Sep 29 15:46:42 2009 -0700
     8.3 @@ -25,7 +25,7 @@
     8.4      
     8.5      void shuffle(int a[], int n, unsigned seed) {
     8.6          if (seed==0) {
     8.7 -#ifdef BSD
     8.8 +#ifdef _DARWIN_C_SOURCE
     8.9              srandomdev();
    8.10  #endif
    8.11              seed = random();
    8.12 @@ -54,16 +54,11 @@
    8.13              while (NULL != ::fgets(word, 4096, in)) {
    8.14                  wordLen = ::strlen(word);
    8.15                  if (word[wordLen-1]=='\n') {
    8.16 -		  word[wordLen-1] = '\0';
    8.17 -		  wordLen--;
    8.18 -		}
    8.19 -
    8.20 -                if (wordLen == 0) continue;
    8.21 -
    8.22 -                sWords[sNWords] = strdup(word); 
    8.23 -                //if( sNWords % 10000 == 0)
    8.24 -                //    printf("'%s' ... ", sWords[sNWords]->string());
    8.25 -                sNWords++;
    8.26 +                    word[wordLen-1] = '\0';
    8.27 +                    wordLen--;
    8.28 +                }
    8.29 +                if (wordLen > 0)
    8.30 +                    sWords[sNWords++] = strdup(word); 
    8.31              }
    8.32          }
    8.33      }
    8.34 @@ -99,7 +94,7 @@
    8.35  using namespace Mooseyard;
    8.36  
    8.37  int main(int argc, char **argv) {
    8.38 -#if BSD
    8.39 +#ifdef _DARWIN_C_SOURCE
    8.40      srandomdev();
    8.41  #endif
    8.42      try {
     9.1 --- a/test/VersionDictionary_test.cpp	Mon Sep 28 23:39:08 2009 -0700
     9.2 +++ b/test/VersionDictionary_test.cpp	Tue Sep 29 15:46:42 2009 -0700
     9.3 @@ -46,16 +46,16 @@
     9.4  
     9.5  TEST(File,HasPath) {
     9.6      {
     9.7 -        File f("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC, true);
     9.8 +        File f("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC);
     9.9          f.write("howdy");
    9.10      }
    9.11      {
    9.12 -        File f("/tmp/jubba", O_RDWR, true);
    9.13 +        File f("/tmp/jubba", O_RDWR);
    9.14          EXPECT_TRUE(f.hasPath("/tmp/jubba"));
    9.15          File::unlink("/tmp/jubba");
    9.16          EXPECT_FALSE(f.hasPath("/tmp/jubba"));
    9.17  
    9.18 -        File f2("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC, true);
    9.19 +        File f2("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC);
    9.20          f2.write("howdy");
    9.21          f2.flush();
    9.22  
    9.23 @@ -108,7 +108,7 @@
    9.24      time_t startTime = ::time(NULL);
    9.25      time_t createTime;
    9.26      {
    9.27 -        File file("/tmp/hashfiletest", O_RDWR | O_CREAT | O_TRUNC, true);
    9.28 +        File file("/tmp/hashfiletest", O_RDWR | O_CREAT | O_TRUNC);
    9.29          VersionDictionary *hf;
    9.30          {
    9.31              Timer t("Creating & writing VersionDictionary", nWords);
    9.32 @@ -124,7 +124,7 @@
    9.33          delete hf;
    9.34      }
    9.35      {
    9.36 -        File file("/tmp/hashfiletest");
    9.37 +        File file("/tmp/hashfiletest", O_RDONLY);
    9.38          VersionDictionary hf(&file);
    9.39          ASSERT_EQ(0, hf.generation());
    9.40          ASSERT_EQ(createTime, hf.timestamp());
    9.41 @@ -152,7 +152,7 @@
    9.42      }
    9.43      {
    9.44          printf("Opening OverlayVersionDictionary...\n");
    9.45 -        File file("/tmp/hashfiletest", O_RDWR, true);
    9.46 +        File file("/tmp/hashfiletest", O_RDWR);
    9.47          OverlayVersionDictionary hf(&file);
    9.48          EXPECT_EQ( nWords ,  hf.count() );
    9.49          EXPECT_TRUE(hf.get("abatement").equals("abatement"));
    9.50 @@ -196,7 +196,7 @@
    9.51      }
    9.52      {
    9.53          printf("Re-opening OverlayVersionDictionary...\n");
    9.54 -        File file("/tmp/hashfiletest");
    9.55 +        File file("/tmp/hashfiletest", O_RDONLY);
    9.56          OverlayVersionDictionary hf(&file);
    9.57          
    9.58          ASSERT_EQ(1, hf.generation());
    9.59 @@ -222,17 +222,17 @@
    9.60      }
    9.61      {
    9.62          printf("Writing VersionDictionary to a new file...\n");
    9.63 -        File oldFile("/tmp/hashfiletest");
    9.64 +        File oldFile("/tmp/hashfiletest", O_RDONLY);
    9.65          OverlayVersionDictionary oldhf(&oldFile);
    9.66          
    9.67 -        File newFile("/tmp/hashfiletest2", O_RDWR | O_CREAT | O_TRUNC, true);
    9.68 +        File newFile("/tmp/hashfiletest2", O_RDWR | O_CREAT | O_TRUNC);
    9.69          newFile.write("Ha5h", 4);     // VersionDictionary won't write to an empty file
    9.70          oldhf.saveAs(&newFile);
    9.71          printf("File size: %llu bytes\n", newFile.length());
    9.72      }
    9.73      {
    9.74          printf("Opening new file...\n");
    9.75 -        File file("/tmp/hashfiletest2");
    9.76 +        File file("/tmp/hashfiletest2", O_RDONLY);
    9.77          OverlayVersionDictionary hf(&file);
    9.78          
    9.79          EXPECT_EQ( nWords ,  hf.count() );