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
38namespace vrs {
39
40using std::map;
41using std::set;
42using std::string;
43using std::string_view;
44using std::vector;
45
47template <typename T>
48using EnableIfStringConvertible = std::enable_if_t<
49 !std::is_convertible_v<const T&, string_view> && std::is_convertible_v<T, string>,
50 int>;
51
52class DataLayout;
53class StreamPlayer;
54class ProgressLogger;
55
60constexpr const char* kFailFastOnIncompleteIndex = "fail_fast_on_incomplete_index";
61
76 public:
78 RecordFileReader(const RecordFileReader&) = delete;
80
81 virtual ~RecordFileReader();
82
83 RecordFileReader& operator=(const RecordFileReader&) = delete;
84 RecordFileReader& operator=(RecordFileReader&&) = delete;
85
91 bool isVrsFile(string_view filePath);
97 bool isVrsFile(const FileSpec& fileSpec);
98
106 int openFile(string_view filePath, bool autoWriteFixedIndex = false);
108 template <typename T, EnableIfStringConvertible<T> = 0>
109 inline int openFile(const T& filePath, bool autoWriteFixedIndex = false) {
110 return openFile(string_view(static_cast<string>(filePath)), autoWriteFixedIndex);
111 }
118 int openFile(const FileSpec& fileSpec, bool autoWriteFixedIndex = false);
119
122 bool isOpened() const;
123
131 void setStreamPlayer(StreamId streamId, StreamPlayer* streamPlayer);
132
135 int clearStreamPlayers();
136
152 const vector<const IndexRecord::RecordInfo*>& records,
153 bool clearSequence = true);
154
160
166 int readRecord(const IndexRecord::RecordInfo& recordInfo);
167
179 int readRecord(
180 const IndexRecord::RecordInfo& recordInfo,
181 StreamPlayer* streamPlayer,
182 bool setupPlayer = false);
183
187 int readAllRecords();
188
191 vector<std::pair<string, int64_t>> getFileChunks() const;
192
195 int64_t getTotalSourceSize() const;
196
199 int closeFile();
200
206 bool hasIndex() const;
207
210 const set<StreamId>& getStreams() const {
211 return streamIds_;
212 }
213
219 vector<StreamId> getStreams(RecordableTypeId typeId, const string& flavor = {}) const;
220
226 StreamId getStreamForType(RecordableTypeId typeId, uint32_t indexNumber = 0) const;
227
236 StreamId getStreamForName(const string& name) const;
237
244 StreamId
245 getStreamForFlavor(RecordableTypeId typeId, const string& flavor, uint32_t indexNumber = 0) const;
246
255 StreamId getStreamForTag(
256 const string& tagName,
257 const string& tag,
259
261 StreamId getStreamForSerialNumber(const string& streamSerialNumber) const;
262
266 const vector<IndexRecord::RecordInfo>& getIndex() const {
267 return recordIndex_;
268 }
269
273 const vector<const IndexRecord::RecordInfo*>& getIndex(StreamId streamId) const;
274
277 uint32_t getRecordCount() const {
278 return static_cast<uint32_t>(recordIndex_.size());
279 }
280
284 uint32_t getRecordCount(StreamId streamId) const;
285
291 uint32_t getRecordCount(StreamId streamId, Record::Type recordType) const;
292
297 const IndexRecord::RecordInfo* getRecord(uint32_t globalIndex) const;
298
304 const IndexRecord::RecordInfo* getRecord(StreamId streamId, uint32_t indexNumber) const;
305
314 getRecord(StreamId streamId, Record::Type recordType, uint32_t indexNumber) const;
315
321 const IndexRecord::RecordInfo* getLastRecord(StreamId streamId, Record::Type recordType) const;
322
326 const IndexRecord::RecordInfo* getRecordByTime(double timestamp) const;
331 const IndexRecord::RecordInfo* getRecordByTime(Record::Type recordType, double timestamp) const;
336 const IndexRecord::RecordInfo* getRecordByTime(StreamId streamId, double timestamp) const;
343 getRecordByTime(StreamId streamId, Record::Type recordType, double timestamp) const;
344
353 double timestamp,
354 double epsilon,
355 StreamId streamId = {},
356 Record::Type recordType = Record::Type::UNDEFINED) const;
357
361 uint32_t getRecordIndex(const IndexRecord::RecordInfo* record) const;
362
366 uint32_t getRecordStreamIndex(const IndexRecord::RecordInfo* record) const;
367
373 uint32_t getRecordSize(uint32_t recordIndex, bool useBoundaries = true) const;
374
377 double getFirstDataRecordTime() const;
378
381 double getLastDataRecordTime() const;
382
397 bool readFirstConfigurationRecord(StreamId streamId, StreamPlayer* streamPlayer = nullptr);
398
403 bool readFirstConfigurationRecords(StreamPlayer* streamPlayer = nullptr);
404
411 RecordableTypeId typeId,
412 StreamPlayer* streamPlayer = nullptr);
413
416 const map<string, string>& getTags() const {
417 return fileTags_;
418 }
419
423 const string& getTag(const string& name) const {
424 return getTag(fileTags_, name);
425 }
426
431 const StreamTags& getTags(StreamId streamId) const;
432
434 const map<StreamId, StreamTags>& getStreamTags() const {
435 return streamTags_;
436 }
437
442 const string& getTag(StreamId streamId, const string& name) const {
443 return getTag(getTags(streamId).user, name);
444 }
445
450 const string& getOriginalRecordableTypeName(StreamId streamId) const;
451
458 const string& getFlavor(StreamId streamId) const;
459
471 const string& getSerialNumber(StreamId streamId) const;
472
476 string getStreamsSignature() const;
477
483 bool mightContainImages(StreamId streamId) const;
484
490 bool mightContainAudio(StreamId streamId) const;
491
499 bool getRecordFormat(
500 StreamId streamId,
501 Record::Type recordType,
502 uint32_t formatVersion,
503 RecordFormat& outFormat) const;
504
510 uint32_t getRecordFormats(StreamId streamId, RecordFormatMap& outFormats) const;
511 std::unique_ptr<DataLayout> getDataLayout(StreamId streamId, const ContentBlockId& blockId) const;
512
515 void setOpenProgressLogger(ProgressLogger* progressLogger);
516
519 bool setCachingStrategy(CachingStrategy cachingStrategy) {
520 return file_->setCachingStrategy(cachingStrategy);
521 }
522 CachingStrategy getCachingStrategy() const {
523 return file_->getCachingStrategy();
524 }
525
527 bool setStatsCallback(const FileHandler::CacheStatsCallbackFunction& statsCallback) {
528 return file_->setStatsCallback(statsCallback);
529 }
530
536 return file_->purgeCache();
537 }
538
541
547 void setFileHandler(std::unique_ptr<FileHandler> fileHandler);
548
551 std::unique_ptr<FileHandler> getFileHandler() const;
552
559 static int
560 vrsFilePathToFileSpec(string_view filePath, FileSpec& outFileSpec, bool checkLocalFile = false);
561
562 class RecordTypeCounter : public std::array<uint32_t, enumCount<Record::Type>()> {
563 using ParentType = std::array<uint32_t, enumCount<Record::Type>()>;
564
565 public:
566 RecordTypeCounter() : array() {
567 fill(0);
568 }
569 inline uint32_t operator[](Record::Type recordType) const {
570 return ParentType::operator[](static_cast<uint32_t>(recordType));
571 }
572 inline uint32_t& operator[](Record::Type recordType) {
573 return ParentType::operator[](static_cast<uint32_t>(recordType));
574 }
575 uint32_t totalCount() const;
576 };
577
578 void buildRecordBoundaries(bool boundariesAndLimits = false) const;
579
580 private:
581 int doOpenFile(const FileSpec& fileSpec, bool autoWriteFixedIndex, bool checkSignatureOnly);
582 int readFileHeader(const FileSpec& fileSpec, FileFormat::FileHeader& outFileHeader);
583 int readFileDetails(
584 const FileSpec& fileSpec,
585 bool autoWriteFixedIndex,
586 FileFormat::FileHeader& fileHeader);
587 bool readConfigRecords(
588 const set<const IndexRecord::RecordInfo*>& configRecords,
589 StreamPlayer* streamPlayer);
590
591 static const string& getTag(const map<string, string>& tags, const string& name);
592 bool mightContainContentTypeInDataRecord(StreamId streamId, ContentType type) const;
593
594 int64_t getFollowingRecordOffset(uint32_t recordIndex, bool useBoundaries) const;
595 mutable vector<int64_t> recordBoundaries_;
596 mutable map<uint32_t, int64_t> recordLimits_;
597
598 // Members to read an open VRS file
599 std::unique_ptr<FileHandler> file_;
600 UncompressedRecordReader uncompressedRecordReader_;
601 CompressedRecordReader compressedRecordReader_;
602
603 // Source of truth describing the VRS file: must never change while the file is open.
604 set<StreamId> streamIds_;
605 map<StreamId, StreamTags> streamTags_;
606 map<string, string> fileTags_;
607 vector<IndexRecord::RecordInfo> recordIndex_;
608 mutable map<StreamId, RecordTypeCounter> streamRecordCounts_;
609
610 // Pointers to stream players to notify when reading records. These are NOT owned by the class.
611 map<StreamId, StreamPlayer*> streamPlayers_;
612
613 // Misc less critical members, for presentation or optimization
614 unique_ptr<ProgressLogger> defaultProgressLogger_;
615 ProgressLogger* openProgressLogger_;
616 unique_ptr<std::thread> detailsSaveThread_;
617 mutable map<StreamId, vector<const IndexRecord::RecordInfo*>> streamIndex_;
618 // Location of the last record searched for a specific stream & record type
619 // The pair: index of the record for the type (query), index of the record in the stream (result)
620 mutable map<pair<StreamId, Record::Type>, pair<uint32_t, size_t>> lastRequest_;
621 int64_t endOfUserRecordsOffset_{};
622 uint32_t recordHeaderSize_{};
623 bool fileHasAnIndex_{};
624 bool autoPrefetch_{};
625};
626
634const IndexRecord::RecordInfo* getNearestRecordByTime(
635 const std::vector<const IndexRecord::RecordInfo*>& index,
636 double timestamp,
637 double epsilon,
639
640} // namespace vrs
RecordReader specialized to read compressed records. For VRS internal usage only.
Definition RecordReaders.h:115
Helper to identify a particular content block within a file.
Definition RecordFormat.h:640
The DataLayout class describes the data stored inside a DataLayoutContentBlock.
Definition DataLayout.h:209
ProgressLogger class to be notified of some process' progress.
Definition ProgressLogger.h:31
Definition RecordFileReader.h:562
The class to read VRS files.
Definition RecordFileReader.h:75
uint32_t getRecordFormats(StreamId streamId, RecordFormatMap &outFormats) const
Definition RecordFileReader.cpp:988
int readAllRecords()
Definition RecordFileReader.cpp:1092
void setStreamPlayer(StreamId streamId, StreamPlayer *streamPlayer)
Definition RecordFileReader.cpp:107
bool purgeFileCache()
Definition RecordFileReader.h:535
uint32_t getRecordSize(uint32_t recordIndex, bool useBoundaries=true) const
Definition RecordFileReader.cpp:586
void buildRecordBoundaries(bool boundariesAndLimits=false) const
private, for testing only
Definition RecordFileReader.cpp:509
const string & getSerialNumber(StreamId streamId) const
Definition RecordFileReader.cpp:1032
int closeFile()
Definition RecordFileReader.cpp:483
bool prefetchRecordSequence(const vector< const IndexRecord::RecordInfo * > &records, bool clearSequence=true)
Definition RecordFileReader.cpp:597
const string & getTag(StreamId streamId, const string &name) const
Definition RecordFileReader.h:442
bool isRecordAvailableOrPrefetch(const IndexRecord::RecordInfo &recordInfo)
Definition RecordFileReader.cpp:1114
bool isOpened() const
Definition RecordFileReader.cpp:193
const string & getFlavor(StreamId streamId) const
Definition RecordFileReader.cpp:1028
const map< StreamId, StreamTags > & getStreamTags() const
Get the tags for all the streams at once.
Definition RecordFileReader.h:434
StreamId getStreamForType(RecordableTypeId typeId, uint32_t indexNumber=0) const
Definition RecordFileReader.cpp:630
const IndexRecord::RecordInfo * getRecord(uint32_t globalIndex) const
Definition RecordFileReader.cpp:689
vector< std::pair< string, int64_t > > getFileChunks() const
Definition RecordFileReader.cpp:1106
StreamId getStreamForFlavor(RecordableTypeId typeId, const string &flavor, uint32_t indexNumber=0) const
Definition RecordFileReader.cpp:653
bool getRecordFormat(StreamId streamId, Record::Type recordType, uint32_t formatVersion, RecordFormat &outFormat) const
Definition RecordFileReader.cpp:973
uint32_t getRecordIndex(const IndexRecord::RecordInfo *record) const
Definition RecordFileReader.cpp:855
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:109
double getLastDataRecordTime() const
Definition RecordFileReader.cpp:910
double getFirstDataRecordTime() const
Definition RecordFileReader.cpp:901
void setOpenProgressLogger(ProgressLogger *progressLogger)
Definition RecordFileReader.cpp:87
const IndexRecord::RecordInfo * getLastRecord(StreamId streamId, Record::Type recordType) const
Definition RecordFileReader.cpp:727
bool hasIndex() const
Definition RecordFileReader.cpp:615
bool readFirstConfigurationRecords(StreamPlayer *streamPlayer=nullptr)
Definition RecordFileReader.cpp:953
const vector< IndexRecord::RecordInfo > & getIndex() const
Definition RecordFileReader.h:266
bool mightContainAudio(StreamId streamId) const
Definition RecordFileReader.cpp:1060
bool isVrsFile(string_view filePath)
Definition RecordFileReader.cpp:201
bool readFirstConfigurationRecord(StreamId streamId, StreamPlayer *streamPlayer=nullptr)
Definition RecordFileReader.cpp:949
int readRecord(const IndexRecord::RecordInfo &recordInfo)
Definition RecordFileReader.cpp:1145
const string & getTag(const string &name) const
Definition RecordFileReader.h:423
int openFile(string_view filePath, bool autoWriteFixedIndex=false)
Definition RecordFileReader.cpp:118
bool setCachingStrategy(CachingStrategy cachingStrategy)
Definition RecordFileReader.h:519
bool setStatsCallback(const FileHandler::CacheStatsCallbackFunction &statsCallback)
Set callback function for cache stats.
Definition RecordFileReader.h:527
bool mightContainImages(StreamId streamId) const
Definition RecordFileReader.cpp:1056
const string & getOriginalRecordableTypeName(StreamId streamId) const
Definition RecordFileReader.cpp:1024
int clearStreamPlayers()
Definition RecordFileReader.cpp:504
StreamId getStreamForSerialNumber(const string &streamSerialNumber) const
Find the stream with the specified stream serial number.
Definition RecordFileReader.cpp:680
void setFileHandler(std::unique_ptr< FileHandler > fileHandler)
Definition RecordFileReader.cpp:97
const map< string, string > & getTags() const
Definition RecordFileReader.h:416
static int vrsFilePathToFileSpec(string_view filePath, FileSpec &outFileSpec, bool checkLocalFile=false)
Definition RecordFileReader.cpp:124
std::unique_ptr< FileHandler > getFileHandler() const
Definition RecordFileReader.cpp:103
const IndexRecord::RecordInfo * getNearestRecordByTime(double timestamp, double epsilon, StreamId streamId={}, Record::Type recordType=Record::Type::UNDEFINED) const
Definition RecordFileReader.cpp:801
bool readFirstConfigurationRecordsForType(RecordableTypeId typeId, StreamPlayer *streamPlayer=nullptr)
Definition RecordFileReader.cpp:961
StreamId getStreamForName(const string &name) const
Definition RecordFileReader.cpp:640
StreamId getStreamForTag(const string &tagName, const string &tag, RecordableTypeId typeId=RecordableTypeId::Undefined) const
Definition RecordFileReader.cpp:667
string getStreamsSignature() const
Definition RecordFileReader.cpp:1036
const set< StreamId > & getStreams() const
Definition RecordFileReader.h:210
int64_t getTotalSourceSize() const
Definition RecordFileReader.cpp:1110
const IndexRecord::RecordInfo * getRecordByTime(double timestamp) const
Definition RecordFileReader.cpp:743
uint32_t getRecordCount() const
Definition RecordFileReader.h:277
uint32_t getRecordStreamIndex(const IndexRecord::RecordInfo *record) const
Definition RecordFileReader.cpp:862
Description of the format of a VRS record as a succession of typed blocks of content.
Definition RecordFormat.h:684
Type
Definition Record.h:90
@ UNDEFINED
don't use.
VRS stream identifier class.
Definition StreamId.h:249
Class designed to receive record data when reading a VRS file.
Definition StreamPlayer.h:53
RecordReader specialized to read uncompressed records. For VRS internal usage only.
Definition RecordReaders.h:107
Definition Compressor.cpp:112
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:630
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:50
CachingStrategy
Caching strategy requests.
Definition FileHandler.h:38
RecordableTypeId
VRS stream type or class identifier enum.
Definition StreamId.h:51
@ Undefined
Value used for default initializations and marking undefined situations.
ContentType
Type of a record's block.
Definition RecordFormat.h:35
constexpr const char * kFailFastOnIncompleteIndex
Definition RecordFileReader.h:60
Every file starts with this header, which may grow but not shrink!
Definition FileFormat.h:60
Generalized file descriptor class, allowing the efficient representation of complex file objects,...
Definition FileSpec.h:40
Helper class to hold the details about a single VRS record in memory.
Definition IndexRecord.h:109
Container for a stream's tags, both user and VRS controlled.
Definition Recordable.h:37