VRS
A file format for sensor data.
Loading...
Searching...
No Matches
RecordFileReader.h
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
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#pragma once
18
19#include <array>
20#include <map>
21#include <memory>
22#include <set>
23#include <string>
24#include <string_view>
25#include <thread>
26#include <type_traits>
27#include <vector>
28
29#include <vrs/FileFormat.h>
30#include <vrs/FileHandler.h>
31#include <vrs/IndexRecord.h>
32#include <vrs/Record.h>
33#include <vrs/RecordFormat.h>
34#include <vrs/RecordReaders.h>
35#include <vrs/Recordable.h>
36#include <vrs/StreamId.h>
37#include <vrs/VrsExport.h>
38
39namespace vrs {
40
41using std::map;
42using std::set;
43using std::string;
44using std::string_view;
45using std::vector;
46
48template <typename T>
49using EnableIfStringConvertible = std::enable_if_t<
50 !std::is_convertible_v<const T&, string_view> && std::is_convertible_v<T, string>,
51 int>;
52
53class DataLayout;
54class StreamPlayer;
55class ProgressLogger;
56
61constexpr const char* kFailFastOnIncompleteIndex = "fail_fast_on_incomplete_index";
62
76class VRS_API RecordFileReader {
77 public:
79 RecordFileReader(const RecordFileReader&) = delete;
81
82 virtual ~RecordFileReader();
83
84 RecordFileReader& operator=(const RecordFileReader&) = delete;
85 RecordFileReader& operator=(RecordFileReader&&) = delete;
86
92 bool isVrsFile(string_view filePath);
98 bool isVrsFile(const FileSpec& fileSpec);
99
107 int openFile(string_view filePath, bool autoWriteFixedIndex = false);
109 template <typename T, EnableIfStringConvertible<T> = 0>
110 inline int openFile(const T& filePath, bool autoWriteFixedIndex = false) {
111 return openFile(string_view(static_cast<string>(filePath)), autoWriteFixedIndex);
112 }
119 int openFile(const FileSpec& fileSpec, bool autoWriteFixedIndex = false);
120
123 bool isOpened() const;
124
132 void setStreamPlayer(StreamId streamId, StreamPlayer* streamPlayer);
133
136 int clearStreamPlayers();
137
152 bool prefetchRecordSequence(
153 const vector<const IndexRecord::RecordInfo*>& records,
154 bool clearSequence = true);
155
160 bool isRecordAvailableOrPrefetch(const IndexRecord::RecordInfo& recordInfo);
161
167 int readRecord(const IndexRecord::RecordInfo& recordInfo);
168
180 int readRecord(
181 const IndexRecord::RecordInfo& recordInfo,
182 StreamPlayer* streamPlayer,
183 bool setupPlayer = false);
184
188 int readAllRecords();
189
192 vector<std::pair<string, int64_t>> getFileChunks() const;
193
196 int64_t getTotalSourceSize() const;
197
200 int closeFile();
201
207 bool hasIndex() const;
208
211 const set<StreamId>& getStreams() const {
212 return streamIds_;
213 }
214
220 vector<StreamId> getStreams(RecordableTypeId typeId, const string& flavor = {}) const;
221
227 StreamId getStreamForType(RecordableTypeId typeId, uint32_t indexNumber = 0) const;
228
237 StreamId getStreamForName(const string& name) const;
238
245 StreamId
246 getStreamForFlavor(RecordableTypeId typeId, const string& flavor, uint32_t indexNumber = 0) const;
247
256 StreamId getStreamForTag(
257 const string& tagName,
258 const string& tag,
259 RecordableTypeId typeId = RecordableTypeId::Undefined) const;
260
262 StreamId getStreamForSerialNumber(const string& streamSerialNumber) const;
263
267 const vector<IndexRecord::RecordInfo>& getIndex() const {
268 return recordIndex_;
269 }
270
274 const vector<const IndexRecord::RecordInfo*>& getIndex(StreamId streamId) const;
275
278 uint32_t getRecordCount() const {
279 return static_cast<uint32_t>(recordIndex_.size());
280 }
281
285 uint32_t getRecordCount(StreamId streamId) const;
286
292 uint32_t getRecordCount(StreamId streamId, Record::Type recordType) const;
293
298 const IndexRecord::RecordInfo* getRecord(uint32_t globalIndex) const;
299
305 const IndexRecord::RecordInfo* getRecord(StreamId streamId, uint32_t indexNumber) const;
306
315 getRecord(StreamId streamId, Record::Type recordType, uint32_t indexNumber) const;
316
322 const IndexRecord::RecordInfo* getLastRecord(StreamId streamId, Record::Type recordType) const;
323
327 const IndexRecord::RecordInfo* getRecordByTime(double timestamp) const;
332 const IndexRecord::RecordInfo* getRecordByTime(Record::Type recordType, double timestamp) const;
337 const IndexRecord::RecordInfo* getRecordByTime(StreamId streamId, double timestamp) const;
344 getRecordByTime(StreamId streamId, Record::Type recordType, double timestamp) const;
345
353 const IndexRecord::RecordInfo* getNearestRecordByTime(
354 double timestamp,
355 double epsilon,
356 StreamId streamId = {},
357 Record::Type recordType = Record::Type::UNDEFINED) const;
358
362 uint32_t getRecordIndex(const IndexRecord::RecordInfo* record) const;
363
367 uint32_t getRecordStreamIndex(const IndexRecord::RecordInfo* record) const;
368
374 uint32_t getRecordSize(uint32_t recordIndex, bool useBoundaries = true) const;
375
378 double getFirstDataRecordTime() const;
379
382 double getLastDataRecordTime() const;
383
398 bool readFirstConfigurationRecord(StreamId streamId, StreamPlayer* streamPlayer = nullptr);
399
404 bool readFirstConfigurationRecords(StreamPlayer* streamPlayer = nullptr);
405
411 bool readFirstConfigurationRecordsForType(
412 RecordableTypeId typeId,
413 StreamPlayer* streamPlayer = nullptr);
414
417 const map<string, string>& getTags() const {
418 return fileTags_;
419 }
420
424 const string& getTag(const string& name) const {
425 return getTag(fileTags_, name);
426 }
427
432 const StreamTags& getTags(StreamId streamId) const;
433
435 const map<StreamId, StreamTags>& getStreamTags() const {
436 return streamTags_;
437 }
438
443 const string& getTag(StreamId streamId, const string& name) const {
444 return getTag(getTags(streamId).user, name);
445 }
446
451 const string& getOriginalRecordableTypeName(StreamId streamId) const;
452
459 const string& getFlavor(StreamId streamId) const;
460
472 const string& getSerialNumber(StreamId streamId) const;
473
477 string getStreamsSignature() const;
478
484 bool mightContainImages(StreamId streamId) const;
485
491 bool mightContainAudio(StreamId streamId) const;
492
500 bool getRecordFormat(
501 StreamId streamId,
502 Record::Type recordType,
503 uint32_t formatVersion,
504 RecordFormat& outFormat) const;
505
511 uint32_t getRecordFormats(StreamId streamId, RecordFormatMap& outFormats) const;
512 std::unique_ptr<DataLayout> getDataLayout(StreamId streamId, const ContentBlockId& blockId) const;
513
516 void setOpenProgressLogger(ProgressLogger* progressLogger);
517
520 bool setCachingStrategy(CachingStrategy cachingStrategy) {
521 return file_->setCachingStrategy(cachingStrategy);
522 }
523 CachingStrategy getCachingStrategy() const {
524 return file_->getCachingStrategy();
525 }
526
528 bool setStatsCallback(const FileHandler::CacheStatsCallbackFunction& statsCallback) {
529 return file_->setStatsCallback(statsCallback);
530 }
531
537 return file_->purgeCache();
538 }
539
542
548 void setFileHandler(std::unique_ptr<FileHandler> fileHandler);
549
552 std::unique_ptr<FileHandler> getFileHandler() const;
553
560 static int
561 vrsFilePathToFileSpec(string_view filePath, FileSpec& outFileSpec, bool checkLocalFile = false);
562
563 class RecordTypeCounter : public std::array<uint32_t, enumCount<Record::Type>()> {
564 using ParentType = std::array<uint32_t, enumCount<Record::Type>()>;
565
566 public:
567 RecordTypeCounter() : array() {
568 fill(0);
569 }
570 inline uint32_t operator[](Record::Type recordType) const {
571 return ParentType::operator[](static_cast<uint32_t>(recordType));
572 }
573 inline uint32_t& operator[](Record::Type recordType) {
574 return ParentType::operator[](static_cast<uint32_t>(recordType));
575 }
576 uint32_t totalCount() const;
577 };
578
579 void buildRecordBoundaries(bool boundariesAndLimits = false) const;
580
581 private:
582 int doOpenFile(const FileSpec& fileSpec, bool autoWriteFixedIndex, bool checkSignatureOnly);
583 int readFileHeader(const FileSpec& fileSpec, FileFormat::FileHeader& outFileHeader);
584 int readFileDetails(
585 const FileSpec& fileSpec,
586 bool autoWriteFixedIndex,
587 FileFormat::FileHeader& fileHeader);
588 bool readConfigRecords(
589 const set<const IndexRecord::RecordInfo*>& configRecords,
590 StreamPlayer* streamPlayer);
591
592 static const string& getTag(const map<string, string>& tags, const string& name);
593 bool mightContainContentTypeInDataRecord(StreamId streamId, ContentType type) const;
594
595 int64_t getFollowingRecordOffset(uint32_t recordIndex, bool useBoundaries) const;
596 mutable vector<int64_t> recordBoundaries_;
597 mutable map<uint32_t, int64_t> recordLimits_;
598
599 // Members to read an open VRS file
600 std::unique_ptr<FileHandler> file_;
601 UncompressedRecordReader uncompressedRecordReader_;
602 CompressedRecordReader compressedRecordReader_;
603
604 // Source of truth describing the VRS file: must never change while the file is open.
605 set<StreamId> streamIds_;
606 map<StreamId, StreamTags> streamTags_;
607 map<string, string> fileTags_;
608 vector<IndexRecord::RecordInfo> recordIndex_;
609 mutable map<StreamId, RecordTypeCounter> streamRecordCounts_;
610
611 // Pointers to stream players to notify when reading records. These are NOT owned by the class.
612 map<StreamId, StreamPlayer*> streamPlayers_;
613
614 // Misc less critical members, for presentation or optimization
615 unique_ptr<ProgressLogger> defaultProgressLogger_;
616 ProgressLogger* openProgressLogger_;
617 unique_ptr<std::thread> detailsSaveThread_;
618 mutable map<StreamId, vector<const IndexRecord::RecordInfo*>> streamIndex_;
619 // Location of the last record searched for a specific stream & record type
620 // The pair: index of the record for the type (query), index of the record in the stream (result)
621 mutable map<pair<StreamId, Record::Type>, pair<uint32_t, size_t>> lastRequest_;
622 int64_t endOfUserRecordsOffset_{};
623 uint32_t recordHeaderSize_{};
624 bool fileHasAnIndex_{};
625 bool autoPrefetch_{};
626};
627
635VRS_API const IndexRecord::RecordInfo* getNearestRecordByTime(
636 const std::vector<const IndexRecord::RecordInfo*>& index,
637 double timestamp,
638 double epsilon,
640
641} // namespace vrs
RecordReader specialized to read compressed records. For VRS internal usage only.
Definition RecordReaders.h:116
Helper to identify a particular content block within a file.
Definition RecordFormat.h:644
The DataLayout class describes the data stored inside a DataLayoutContentBlock.
Definition DataLayout.h:211
ProgressLogger class to be notified of some process' progress.
Definition ProgressLogger.h:33
Definition RecordFileReader.h:563
The class to read VRS files.
Definition RecordFileReader.h:76
bool purgeFileCache()
Definition RecordFileReader.h:536
const string & getTag(StreamId streamId, const string &name) const
Definition RecordFileReader.h:443
const map< StreamId, StreamTags > & getStreamTags() const
Get the tags for all the streams at once.
Definition RecordFileReader.h:435
int openFile(const T &filePath, bool autoWriteFixedIndex=false)
Template overload for types that convert to string but not directly to string_view.
Definition RecordFileReader.h:110
const vector< IndexRecord::RecordInfo > & getIndex() const
Definition RecordFileReader.h:267
const string & getTag(const string &name) const
Definition RecordFileReader.h:424
bool setCachingStrategy(CachingStrategy cachingStrategy)
Definition RecordFileReader.h:520
bool setStatsCallback(const FileHandler::CacheStatsCallbackFunction &statsCallback)
Set callback function for cache stats.
Definition RecordFileReader.h:528
const map< string, string > & getTags() const
Definition RecordFileReader.h:417
const set< StreamId > & getStreams() const
Definition RecordFileReader.h:211
uint32_t getRecordCount() const
Definition RecordFileReader.h:278
Description of the format of a VRS record as a succession of typed blocks of content.
Definition RecordFormat.h:688
Type
Definition Record.h:91
@ UNDEFINED
don't use.
VRS stream identifier class.
Definition StreamId.h:251
Class designed to receive record data when reading a VRS file.
Definition StreamPlayer.h:54
RecordReader specialized to read uncompressed records. For VRS internal usage only.
Definition RecordReaders.h:108
Definition Compressor.cpp:113
map< pair< Record::Type, uint32_t >, RecordFormat > RecordFormatMap
Map a pair of record type/format version to a record format, for a particular stream.
Definition RecordFormat.h:634
std::enable_if_t< !std::is_convertible_v< const T &, string_view > &&std::is_convertible_v< T, string >, int > EnableIfStringConvertible
Helper to enable overloads for types that convert to string but not directly to string_view.
Definition RecordFileReader.h:51
CachingStrategy
Caching strategy requests.
Definition FileHandler.h:38
RecordableTypeId
VRS stream type or class identifier enum.
Definition StreamId.h:51
ContentType
Type of a record's block.
Definition RecordFormat.h:36
constexpr const char * kFailFastOnIncompleteIndex
Definition RecordFileReader.h:61
Every file starts with this header, which may grow but not shrink!
Definition FileFormat.h:61
Generalized file descriptor class, allowing the efficient representation of complex file objects,...
Definition FileSpec.h:42
Helper class to hold the details about a single VRS record in memory.
Definition IndexRecord.h:110
Container for a stream's tags, both user and VRS controlled.
Definition Recordable.h:38