proxygen
folly::recordio_helpers Namespace Reference

Namespaces

 recordio_detail
 

Classes

struct  RecordInfo
 

Functions

constexpr size_t headerSize ()
 
RecordInfo findRecord (ByteRange range, uint32_t fileId)
 
size_t prependHeader (std::unique_ptr< IOBuf > &buf, uint32_t fileId)
 
RecordInfo validateRecord (ByteRange range, uint32_t fileId)
 
RecordInfo findRecord (ByteRange searchRange, ByteRange wholeRange, uint32_t fileId)
 

Function Documentation

RecordInfo folly::recordio_helpers::findRecord ( ByteRange  range,
uint32_t  fileId 
)
inline

Search for the first valid record in range.

Definition at line 105 of file RecordIO-inl.h.

105  {
106  return findRecord(range, range, fileId);
107 }
Gen range(Value begin, Value end)
Definition: Base.h:467
RecordInfo findRecord(ByteRange range, uint32_t fileId)
Definition: RecordIO-inl.h:105
RecordInfo folly::recordio_helpers::findRecord ( ByteRange  searchRange,
ByteRange  wholeRange,
uint32_t  fileId 
)

Definition at line 193 of file RecordIO.cpp.

References folly::Range< Iter >::begin(), folly::RecordIOReader::end(), folly::Range< Iter >::end(), folly::Range< Iter >::find(), folly::bser::kMagic, min, folly::Range< const unsigned char * >::npos, start, uint32_t, uint8_t, and validateRecord().

Referenced by folly::RecordIOReader::Iterator::advanceToValid().

193  {
194  static const uint32_t magic = Header::kMagic;
195  static const ByteRange magicRange(
196  reinterpret_cast<const uint8_t*>(&magic), sizeof(magic));
197 
198  DCHECK_GE(searchRange.begin(), wholeRange.begin());
199  DCHECK_LE(searchRange.end(), wholeRange.end());
200 
201  const uint8_t* start = searchRange.begin();
202  const uint8_t* end =
203  std::min(searchRange.end(), wholeRange.end() - sizeof(Header));
204  // end-1: the last place where a Header could start
205  while (start < end) {
206  auto p = ByteRange(start, end + sizeof(magic)).find(magicRange);
207  if (p == ByteRange::npos) {
208  break;
209  }
210 
211  start += p;
212  auto r = validateRecord(ByteRange(start, wholeRange.end()), fileId);
213  if (!r.record.empty()) {
214  return r;
215  }
216 
217  // No repeated prefix in magic, so we can do better than start++
218  start += sizeof(magic);
219  }
220 
221  return {0, {}};
222 }
size_type find(const_range_type str) const
Definition: Range.h:721
RecordInfo validateRecord(ByteRange range, uint32_t fileId)
Definition: RecordIO.cpp:170
LogLevel min
Definition: LogLevel.cpp:30
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
auto start
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
const uint8_t kMagic[2]
Definition: Dump.cpp:28
constexpr size_t folly::recordio_helpers::headerSize ( )
size_t folly::recordio_helpers::prependHeader ( std::unique_ptr< IOBuf > &  buf,
uint32_t  fileId = 1 
)

Write a header in the buffer. We will prepend the header to the front of the chain. Do not write the buffer if empty (we don't allow empty records). Returns the total length, including header (0 if empty) (same as buf->computeChainDataLength(), but likely faster)

The fileId should be unique per stream and allows you to have RecordIO headers stored inside the data (for example, have an entire RecordIO file stored as a record inside another RecordIO file). The fileId may not be 0.

Definition at line 139 of file RecordIO.cpp.

References b, folly::IOBuf::create(), headerSize(), folly::bser::kMagic, folly::gen::move, and uint32_t.

Referenced by folly::RecordIOWriter::write().

139  {
140  if (fileId == 0) {
141  throw std::invalid_argument("invalid file id");
142  }
143  auto lengthAndHash = dataLengthAndHash(buf.get());
144  if (lengthAndHash.first == 0) {
145  return 0; // empty, nothing to do, no zero-length records
146  }
147 
148  // Prepend to the first buffer in the chain if we have room, otherwise
149  // prepend a new buffer.
150  if (buf->headroom() >= headerSize()) {
151  buf->unshareOne();
152  buf->prepend(headerSize());
153  } else {
154  auto b = IOBuf::create(headerSize());
155  b->append(headerSize());
156  b->appendChain(std::move(buf));
157  buf = std::move(b);
158  }
159  Header* header = reinterpret_cast<Header*>(buf->writableData());
160  memset(header, 0, sizeof(Header));
161  header->magic = Header::kMagic;
162  header->fileId = fileId;
163  header->dataLength = uint32_t(lengthAndHash.first);
164  header->dataHash = lengthAndHash.second;
165  header->headerHash = headerHash(*header);
166 
167  return lengthAndHash.first + headerSize();
168 }
constexpr size_t headerSize()
Definition: RecordIO-inl.h:101
char b
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const uint8_t kMagic[2]
Definition: Dump.cpp:28
RecordInfo folly::recordio_helpers::validateRecord ( ByteRange  range,
uint32_t  fileId 
)

Check if there is a valid record at the beginning of range. Returns the record data (not the header) if the record is valid, ByteRange() otherwise.

Definition at line 170 of file RecordIO.cpp.

References folly::Range< Iter >::advance(), folly::Range< Iter >::begin(), headerSize(), folly::bser::kMagic, folly::Range< Iter >::reset(), and folly::Range< Iter >::size().

Referenced by findRecord().

170  {
171  if (range.size() <= headerSize()) { // records may not be empty
172  return {0, {}};
173  }
174  const Header* header = reinterpret_cast<const Header*>(range.begin());
175  range.advance(sizeof(Header));
176  if (header->magic != Header::kMagic || header->version != 0 ||
177  header->hashFunction != 0 || header->flags != 0 ||
178  (fileId != 0 && header->fileId != fileId) ||
179  header->dataLength > range.size()) {
180  return {0, {}};
181  }
182  if (headerHash(*header) != header->headerHash) {
183  return {0, {}};
184  }
185  range.reset(range.begin(), header->dataLength);
186  if (dataHash(range) != header->dataHash) {
187  return {0, {}};
188  }
189  return {header->fileId, range};
190 }
constexpr size_t headerSize()
Definition: RecordIO-inl.h:101
Gen range(Value begin, Value end)
Definition: Base.h:467
const uint8_t kMagic[2]
Definition: Dump.cpp:28