filelistdb.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: filelistdb.cc,v 1.4 1999/02/27 08:00:05 jgg Exp $
  4. /* ######################################################################
  5. File List Database
  6. The mmap class should probably go someplace else..
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include files /*{{{*/
  10. #ifdef __GNUG__
  11. #pragma implementation "dsync/filelistdb.h"
  12. #endif
  13. #include <dsync/filelistdb.h>
  14. #include <dsync/error.h>
  15. #include <string.h>
  16. /*}}}*/
  17. // FileListDB::dsFileListDB - Constructor /*{{{*/
  18. // ---------------------------------------------------------------------
  19. /* */
  20. dsFileListDB::dsFileListDB()
  21. {
  22. }
  23. /*}}}*/
  24. // FileListDB::Generate - Build the directory map /*{{{*/
  25. // ---------------------------------------------------------------------
  26. /* This sucks the offset of every directory record into a stl map for
  27. quick lookup. */
  28. bool dsFileListDB::Generate(dsFList::IO &IO)
  29. {
  30. // Iterate over the file
  31. dsFList List;
  32. while (List.Step(IO) == true)
  33. {
  34. // Record the current location so we can jump to it
  35. unsigned long Pos = IO.Tell();
  36. string LastSymlink = IO.LastSymlink;
  37. if (List.Tag == dsFList::tTrailer)
  38. return true;
  39. // We only index directory start records
  40. if (List.Tag != dsFList::tDirStart)
  41. continue;
  42. // Store it in the map
  43. Location &Loc = Map[List.Dir.Name];
  44. Loc.Offset = Pos;
  45. Loc.LastSymlink = LastSymlink;
  46. }
  47. return false;
  48. }
  49. /*}}}*/
  50. // FileListDB::Lookup - Find a directory and file /*{{{*/
  51. // ---------------------------------------------------------------------
  52. /* We use a caching scheme, if the last lookup is in the same directory
  53. we do not re-seek but mearly look at the next entries till termination
  54. then wraps around. In the case of a largely unchanged directory this
  55. gives huge speed increases. */
  56. bool dsFileListDB::Lookup(dsFList::IO &IO,const char *Dir,const char *File,
  57. dsFList &List)
  58. {
  59. map<string,Location>::const_iterator I = Map.find(Dir);
  60. if (I == Map.end())
  61. return false;
  62. // See if we should reseek
  63. bool Restart = true;
  64. if (LastDir != Dir || LastDir.empty() == true)
  65. {
  66. Restart = false;
  67. IO.LastSymlink = I->second.LastSymlink;
  68. if (IO.Seek(I->second.Offset) == false)
  69. return false;
  70. LastDir = Dir;
  71. }
  72. List.Head = IO.Header;
  73. while (List.Step(IO) == true)
  74. {
  75. // Oops, ran out of directories
  76. if (List.Tag == dsFList::tDirEnd ||
  77. List.Tag == dsFList::tDirStart ||
  78. List.Tag == dsFList::tTrailer)
  79. {
  80. if (Restart == false)
  81. {
  82. LastDir = string();
  83. return false;
  84. }
  85. Restart = false;
  86. IO.LastSymlink = I->second.LastSymlink;
  87. if (IO.Seek(I->second.Offset) == false)
  88. return false;
  89. LastDir = Dir;
  90. continue;
  91. }
  92. // Skip over non directory contents
  93. if (List.Tag == dsFList::tDirMarker ||
  94. List.Tag == dsFList::tDirEnd ||
  95. List.Tag == dsFList::tDirStart ||
  96. List.Entity == 0)
  97. continue;
  98. if (List.Entity->Name == File)
  99. return true;
  100. }
  101. return false;
  102. }
  103. /*}}}*/
  104. // MMapIO::dsMMapIO - Constructor /*{{{*/
  105. // ---------------------------------------------------------------------
  106. /* */
  107. dsMMapIO::dsMMapIO(string File) : Fd(File,FileFd::ReadOnly),
  108. Map(Fd,MMap::Public | MMap::ReadOnly)
  109. {
  110. Pos = 0;
  111. }
  112. /*}}}*/
  113. // MMapIO::Read - Read bytes from the map /*{{{*/
  114. // ---------------------------------------------------------------------
  115. /* */
  116. bool dsMMapIO::Read(void *Buf,unsigned long Len)
  117. {
  118. if (Pos + Len > Map.Size())
  119. return _error->Error("Attempt to read past end of mmap");
  120. memcpy(Buf,(unsigned char *)Map.Data() + Pos,Len);
  121. Pos += Len;
  122. return true;
  123. }
  124. /*}}}*/
  125. // MMapIO::Write - Write bytes (fail) /*{{{*/
  126. // ---------------------------------------------------------------------
  127. /* */
  128. bool dsMMapIO::Write(const void *Buf,unsigned long Len)
  129. {
  130. return _error->Error("Attempt to write to read only mmap");
  131. }
  132. /*}}}*/
  133. // MMapIO::Seek - Jump to a spot /*{{{*/
  134. // ---------------------------------------------------------------------
  135. /* */
  136. bool dsMMapIO::Seek(unsigned long Bytes)
  137. {
  138. if (Bytes > Map.Size())
  139. return _error->Error("Attempt to seek past end of mmap");
  140. Pos = Bytes;
  141. return true;
  142. }
  143. /*}}}*/
  144. // MMapIO::Tell - Return the current location /*{{{*/
  145. // ---------------------------------------------------------------------
  146. /* */
  147. unsigned long dsMMapIO::Tell()
  148. {
  149. return Pos;
  150. }
  151. /*}}}*/