RecordIO-inl.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright 2013-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef FOLLY_IO_RECORDIO_H_
  17. #error This file may only be included from folly/io/RecordIO.h
  18. #endif
  19. #include <boost/iterator/iterator_facade.hpp>
  20. #include <folly/hash/SpookyHashV2.h>
  21. namespace folly {
  22. class RecordIOReader::Iterator : public boost::iterator_facade<
  23. RecordIOReader::Iterator,
  24. const std::pair<ByteRange, off_t>,
  25. boost::forward_traversal_tag> {
  26. friend class boost::iterator_core_access;
  27. friend class RecordIOReader;
  28. private:
  29. Iterator(ByteRange range, uint32_t fileId, off_t pos);
  30. reference dereference() const {
  31. return recordAndPos_;
  32. }
  33. bool equal(const Iterator& other) const {
  34. return range_ == other.range_;
  35. }
  36. void increment() {
  37. size_t skip = recordio_helpers::headerSize() + recordAndPos_.first.size();
  38. recordAndPos_.second += off_t(skip);
  39. range_.advance(skip);
  40. advanceToValid();
  41. }
  42. void advanceToValid();
  43. ByteRange range_;
  44. uint32_t fileId_;
  45. // stored as a pair so we can return by reference in dereference()
  46. std::pair<ByteRange, off_t> recordAndPos_;
  47. };
  48. inline auto RecordIOReader::cbegin() const -> Iterator {
  49. return seek(0);
  50. }
  51. inline auto RecordIOReader::begin() const -> Iterator {
  52. return cbegin();
  53. }
  54. inline auto RecordIOReader::cend() const -> Iterator {
  55. return seek(off_t(-1));
  56. }
  57. inline auto RecordIOReader::end() const -> Iterator {
  58. return cend();
  59. }
  60. inline auto RecordIOReader::seek(off_t pos) const -> Iterator {
  61. return Iterator(map_.range(), fileId_, pos);
  62. }
  63. namespace recordio_helpers {
  64. namespace recordio_detail {
  65. FOLLY_PACK_PUSH
  66. struct Header {
  67. // First 4 bytes of SHA1("zuck"), big-endian
  68. // Any values will do, except that the sequence must not have a
  69. // repeated prefix (that is, if we see kMagic, we know that the next
  70. // occurrence must start at least 4 bytes later)
  71. static constexpr uint32_t kMagic = 0xeac313a1;
  72. uint32_t magic;
  73. uint8_t version; // backwards incompatible version, currently 0
  74. uint8_t hashFunction; // 0 = SpookyHashV2
  75. uint16_t flags; // reserved (must be 0)
  76. uint32_t fileId; // unique file ID
  77. uint32_t dataLength;
  78. std::size_t dataHash;
  79. uint32_t headerHash; // must be last
  80. } FOLLY_PACK_ATTR;
  81. FOLLY_PACK_POP
  82. static_assert(
  83. offsetof(Header, headerHash) + sizeof(Header::headerHash) == sizeof(Header),
  84. "invalid header layout");
  85. } // namespace recordio_detail
  86. constexpr size_t headerSize() {
  87. return sizeof(recordio_detail::Header);
  88. }
  89. inline RecordInfo findRecord(ByteRange range, uint32_t fileId) {
  90. return findRecord(range, range, fileId);
  91. }
  92. } // namespace recordio_helpers
  93. } // namespace folly