Return if we handle any error messages to avoid unnecessarily calling recv/send
[folly.git] / folly / io / RecordIO-inl.h
1 /*
2  * Copyright 2017 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
17 #ifndef FOLLY_IO_RECORDIO_H_
18 #error This file may only be included from folly/io/RecordIO.h
19 #endif
20
21 #include <boost/iterator/iterator_facade.hpp>
22
23 #include <folly/hash/SpookyHashV2.h>
24
25 namespace folly {
26
27 class RecordIOReader::Iterator : public boost::iterator_facade<
28     RecordIOReader::Iterator,
29     const std::pair<ByteRange, off_t>,
30     boost::forward_traversal_tag> {
31   friend class boost::iterator_core_access;
32   friend class RecordIOReader;
33  private:
34   Iterator(ByteRange range, uint32_t fileId, off_t pos);
35
36   reference dereference() const { return recordAndPos_; }
37   bool equal(const Iterator& other) const { return range_ == other.range_; }
38   void increment() {
39     size_t skip = recordio_helpers::headerSize() + recordAndPos_.first.size();
40     recordAndPos_.second += off_t(skip);
41     range_.advance(skip);
42     advanceToValid();
43   }
44
45   void advanceToValid();
46   ByteRange range_;
47   uint32_t fileId_;
48   // stored as a pair so we can return by reference in dereference()
49   std::pair<ByteRange, off_t> recordAndPos_;
50 };
51
52 inline auto RecordIOReader::cbegin() const -> Iterator { return seek(0); }
53 inline auto RecordIOReader::begin() const -> Iterator { return cbegin(); }
54 inline auto RecordIOReader::cend() const -> Iterator { return seek(off_t(-1)); }
55 inline auto RecordIOReader::end() const -> Iterator { return cend(); }
56 inline auto RecordIOReader::seek(off_t pos) const -> Iterator {
57   return Iterator(map_.range(), fileId_, pos);
58 }
59
60 namespace recordio_helpers {
61
62 namespace detail {
63
64 FOLLY_PACK_PUSH
65 struct Header {
66   // First 4 bytes of SHA1("zuck"), big-endian
67   // Any values will do, except that the sequence must not have a
68   // repeated prefix (that is, if we see kMagic, we know that the next
69   // occurrence must start at least 4 bytes later)
70   static constexpr uint32_t kMagic = 0xeac313a1;
71   uint32_t magic;
72   uint8_t  version;       // backwards incompatible version, currently 0
73   uint8_t  hashFunction;  // 0 = SpookyHashV2
74   uint16_t flags;         // reserved (must be 0)
75   uint32_t fileId;        // unique file ID
76   uint32_t dataLength;
77   uint64_t dataHash;
78   uint32_t headerHash;  // must be last
79 } FOLLY_PACK_ATTR;
80 FOLLY_PACK_POP
81
82 static_assert(offsetof(Header, headerHash) + sizeof(Header::headerHash) ==
83               sizeof(Header), "invalid header layout");
84
85 } // namespace detail
86
87 constexpr size_t headerSize() { return sizeof(detail::Header); }
88
89 inline RecordInfo findRecord(ByteRange range, uint32_t fileId) {
90   return findRecord(range, range, fileId);
91 }
92
93 } // namespace recordio_helpers
94
95 } // namespace folly