slidingwindow.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: slidingwindow.cc,v 1.1 1999/11/05 05:47:06 jgg Exp $
  4. /* ######################################################################
  5. Sliding Window - Implements a sliding buffer over a file.
  6. It would be possible to implement an alternate version if
  7. _POSIX_MAPPED_FILES is not defined..
  8. ##################################################################### */
  9. /*}}}*/
  10. // Include files /*{{{*/
  11. #ifdef __GNUG__
  12. #pragma implementation "dsync/slidingwindow.h"
  13. #endif
  14. #include <dsync/slidingwindow.h>
  15. #include <dsync/error.h>
  16. #include <sys/mman.h>
  17. #include <unistd.h>
  18. /*}}}*/
  19. // SlidingWindow::SlidingWindow - Constructor /*{{{*/
  20. // ---------------------------------------------------------------------
  21. /* */
  22. SlidingWindow::SlidingWindow(FileFd &Fd,unsigned long MnSize) : Buffer(0),
  23. MinSize(MnSize), Fd(Fd)
  24. {
  25. Offset = 0;
  26. Left = 0;
  27. PageSize = sysconf(_SC_PAGESIZE);
  28. if (MinSize < 1024*1024)
  29. MinSize = 1024*1024;
  30. MinSize = Align(MinSize);
  31. }
  32. /*}}}*/
  33. // SlidingWindow::~SlidingWindow - Destructor /*{{{*/
  34. // ---------------------------------------------------------------------
  35. /* Just unmap the mapping */
  36. SlidingWindow::~SlidingWindow()
  37. {
  38. if (Buffer != 0)
  39. {
  40. if (munmap((char *)Buffer,Size) != 0)
  41. _error->Warning("Unable to munmap");
  42. }
  43. }
  44. /*}}}*/
  45. // SlidingWindow::Extend - Make Start - End longer /*{{{*/
  46. // ---------------------------------------------------------------------
  47. /* Start == End when the file is exhausted, false is an IO error. */
  48. bool SlidingWindow::Extend(unsigned char *&Start,unsigned char *&End)
  49. {
  50. unsigned long Remainder = 0;
  51. // Restart
  52. if (Start == 0 || Buffer == 0)
  53. {
  54. Offset = 0;
  55. Left = Fd.Size();
  56. }
  57. else
  58. {
  59. if (AlignDn((unsigned long)(Start - Buffer)) == 0)
  60. return _error->Error("SlidingWindow::Extend called with too small a 'Start'");
  61. // Scanning is finished.
  62. if (Left < (off_t)Size)
  63. {
  64. End = Start;
  65. return true;
  66. }
  67. Offset += AlignDn((unsigned long)(Start - Buffer));
  68. Left -= AlignDn((unsigned long)(Start - Buffer));
  69. Remainder = (Start - Buffer) % PageSize;
  70. }
  71. // Release the old region
  72. if (Buffer != 0)
  73. {
  74. if (munmap((char *)Buffer,Size) != 0)
  75. return _error->Errno("munmap","Unable to munmap");
  76. Buffer = 0;
  77. }
  78. // Maximize the amount that can be mapped
  79. if (Left < (off_t)MinSize)
  80. Size = Align(Left);
  81. else
  82. Size = MinSize;
  83. // Map it
  84. Buffer = (unsigned char *)mmap(0,Size,PROT_READ,MAP_PRIVATE,Fd.Fd(),Offset);
  85. if (Buffer == (unsigned char *)-1)
  86. return _error->Errno("mmap","Couldn't make mmap %lu->%lu bytes",(unsigned long)Offset,
  87. Size);
  88. // Reposition
  89. if (Left < (off_t)Size)
  90. End = Buffer + Left;
  91. else
  92. End = Buffer + Size;
  93. Start = Buffer + Remainder;
  94. return true;
  95. }
  96. /*}}}*/