Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing Reindexer core #641

Merged
merged 51 commits into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2fc9a41
Copy over relevant work to start
Feb 12, 2021
6f62ced
Remove sequential_reindexer
Feb 12, 2021
9fbc439
Switching to reader for metadata queries.
Feb 12, 2021
01b15c1
Properly construct reader.
Feb 12, 2021
59c71d5
Add test bags for unit testing
Feb 12, 2021
2f46dc2
Starting framework for unit test.
Feb 12, 2021
8cc901f
Ignore __pycache__
Feb 12, 2021
32b7c91
Ignore temp database files
Feb 12, 2021
7d02170
Debugging reindexing not reading multiple files
Feb 12, 2021
7ebdad6
Fix metadata writer
Feb 12, 2021
67dbb25
Begin moving metadata target files over
Feb 12, 2021
42631b0
Add other two target files
Feb 12, 2021
cbfee13
First working version of unit tests
Feb 12, 2021
4f224c4
Convert to rcutils directory iterator
Feb 12, 2021
f65c1f2
Remove debug code
Feb 12, 2021
532c3e1
Linting fix
Feb 12, 2021
afb7c82
Clean comments, switch to exceptions
Feb 12, 2021
08c6aae
Re-add Mutex
Feb 12, 2021
46b4118
Remove nested namespace
Feb 12, 2021
9423087
Remove converter, commenting changes
Feb 12, 2021
24c1393
Use map in creating topic metadata section
Feb 12, 2021
433c9c8
Remove unneeded database files
Feb 12, 2021
3036ea5
Trim unneeded functions and members
Feb 12, 2021
d5c4634
Re-add mutex, take 2
Feb 12, 2021
78f7a5c
Missed a rename and remove
Feb 12, 2021
f58d7e4
Re add missing functions
Feb 12, 2021
957d8c3
Documentation changes
Feb 15, 2021
cf10097
Improve error messages, and put them in proper level
Feb 15, 2021
d9b6f30
Remove dead function
Feb 15, 2021
3ad12b7
Convert regex pattern to member variable
Feb 15, 2021
8bc20de
Extend documentation
Feb 15, 2021
6ea7312
Properly capture bag size
Feb 15, 2021
e93fdf7
Allow rosbag2 storage to return expected file extension
Feb 15, 2021
a0d3590
[WIP] [DOES NOT COMPILE]
Feb 15, 2021
6caf3c3
Revert storage extension attempt.
Feb 19, 2021
7a08e29
Remove unused function from header
Feb 19, 2021
443d2f9
Remove unneeded comments
Feb 19, 2021
53f70ea
Fixed comment typo
Feb 19, 2021
7b16136
Remove API for get_storage_extension
Feb 23, 2021
9cd7a50
Comment improvements
Feb 23, 2021
4352cc2
Use default destructor
Feb 23, 2021
0959261
Bring documentation comments in-line with
Feb 23, 2021
9e3056b
Try to fix undeclared identifier in Windows build
Feb 26, 2021
c57b41e
Fix error being logged to debug
Mar 2, 2021
7a6b6cd
Move testing code to its new home in rosbag2_tests
Mar 3, 2021
f0b798a
Merge branch 'master' into feature/reindexer_core
emersonknapp Mar 3, 2021
3ee2876
Revert stream logging change
Mar 12, 2021
0f794d4
Make sure variable is initialized before displaying
Mar 15, 2021
d82e8eb
Add in possibly-missing dependency
Mar 15, 2021
d05f224
Merge remote-tracking branch 'origin/master' into emersonknapp/rebase…
emersonknapp Mar 25, 2021
887cc86
Fix test by creating a new bagfile - it seems like it was corrupted i…
emersonknapp Mar 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ build/
venv/
**/.pytest_cache/
__pycache__/
*.db3-*

Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class MockStorage : public rosbag2_storage::storage_interfaces::ReadWriteInterfa
MOCK_CONST_METHOD0(get_bagfile_size, uint64_t());
MOCK_CONST_METHOD0(get_relative_file_path, std::string());
MOCK_CONST_METHOD0(get_storage_identifier, std::string());
MOCK_CONST_METHOD0(get_storage_extension, std::string());
MOCK_CONST_METHOD0(get_minimum_split_file_size, uint64_t());
};

Expand Down
7 changes: 6 additions & 1 deletion rosbag2_cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.5)
project(rosbag2_cpp)

add_definitions(-D_SRC_REINDEX_DIR_PATH="${CMAKE_CURRENT_SOURCE_DIR}/test/rosbag2_cpp/reindex_test_bags")

# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
Expand Down Expand Up @@ -60,9 +62,11 @@ add_library(${PROJECT_NAME} SHARED
src/rosbag2_cpp/typesupport_helpers.cpp
src/rosbag2_cpp/types/introspection_message.cpp
src/rosbag2_cpp/writer.cpp
src/rosbag2_cpp/writers/sequential_writer.cpp)
src/rosbag2_cpp/writers/sequential_writer.cpp
src/rosbag2_cpp/reindexer.cpp)

ament_target_dependencies(${PROJECT_NAME}
PUBLIC
ament_index_cpp
pluginlib
rcpputils
Expand Down Expand Up @@ -175,6 +179,7 @@ if(BUILD_TESTING)
target_link_libraries(test_message_cache ${PROJECT_NAME})
endif()


# If compiling with gcc, run this test with sanitizers enabled
ament_add_gmock(test_ros2_message
test/rosbag2_cpp/types/test_ros2_message.cpp
Expand Down
127 changes: 127 additions & 0 deletions rosbag2_cpp/include/rosbag2_cpp/reindexer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2020 DCS Corporation, All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// DISTRIBUTION A. Approved for public release; distribution unlimited.
// OPSEC #4584.
//
// Delivered to the U.S. Government with Unlimited Rights, as defined in DFARS
// Part 252.227-7013 or 7014 (Feb 2014).
//
// This notice must appear in all copies of this file and its derivatives.

#ifndef ROSBAG2_CPP__REINDEXER_HPP_
#define ROSBAG2_CPP__REINDEXER_HPP_

#include <memory>
#include <regex>
#include <string>
#include <vector>

#include "rcpputils/filesystem_helper.hpp"

#include "rosbag2_cpp/converter.hpp"
#include "rosbag2_cpp/reader.hpp"
#include "rosbag2_cpp/serialization_format_converter_factory.hpp"
#include "rosbag2_cpp/serialization_format_converter_factory_interface.hpp"
#include "rosbag2_cpp/visibility_control.hpp"

#include "rosbag2_storage/metadata_io.hpp"
#include "rosbag2_storage/storage_factory.hpp"
#include "rosbag2_storage/storage_factory_interface.hpp"
#include "rosbag2_storage/storage_options.hpp"
#include "rosbag2_storage/storage_filter.hpp"
#include "rosbag2_storage/storage_interfaces/read_only_interface.hpp"

// This is necessary because of using stl types here. It is completely safe, because
// a) the member is not accessible from the outside
// b) there are no inline functions.
#ifdef _WIN32
# pragma warning(push)
# pragma warning(disable:4251)
#endif

namespace rosbag2_cpp
{

/**
* Tool to reconstruct bag metadata files in the event of loss or corruption
*
* Reindexing is an operation where a bag that is missing a metadata.yaml file can have a new
* file created through parsing of the metadata stored within the actual files of the bag.
* For instance: Imagine we are working with SQL databases (.db3). We can open the individual
* .db3 files within the bag and read their metadata (not the messages themselves) to replicate
* a usable metadata.yaml file, so that the bag can once again be read by the standard read
* command.
*
* Reindexing has some limitations - It cannot perfectly replicate the original metadata file,
* since some information known by the program from the start up command cannot be found
* within the metadata. But it should at least repair a bag to the point it can be read
* again.
*
*/
class ROSBAG2_CPP_PUBLIC Reindexer
{
public:
Reindexer(
std::unique_ptr<rosbag2_storage::StorageFactoryInterface> storage_factory =
std::make_unique<rosbag2_storage::StorageFactory>(),
std::unique_ptr<rosbag2_storage::MetadataIo> metadata_io =
std::make_unique<rosbag2_storage::MetadataIo>());

virtual ~Reindexer() = default;

/// Use the supplied storage options to reindex a bag defined by the storage options URI.
/*
* \param storage_options Provides best-guess parameters for the bag's original settings.
*/
void reindex(const rosbag2_storage::StorageOptions & storage_options);

protected:
std::unique_ptr<rosbag2_storage::StorageFactoryInterface> storage_factory_{};
std::unique_ptr<rosbag2_storage::MetadataIo> metadata_io_{};
rosbag2_storage::BagMetadata metadata_{};
std::vector<rosbag2_storage::TopicMetadata> topics_metadata_{};

private:
std::string regex_bag_pattern_;
rcpputils::fs::path base_folder_; // The folder that the bag files are in
std::shared_ptr<SerializationFormatConverterFactoryInterface> converter_factory_{};
void get_bag_files(
const rcpputils::fs::path & base_folder,
std::vector<rcpputils::fs::path> & output);

// Prepares the metadata by setting initial values.
void init_metadata(
const std::vector<rcpputils::fs::path> & files,
const rosbag2_storage::StorageOptions & storage_options);

// Attempts to harvest metadata from all bag files, and aggregates the result
void aggregate_metadata(
const std::vector<rcpputils::fs::path> & files,
const std::unique_ptr<rosbag2_cpp::readers::SequentialReader> & bag_reader,
const rosbag2_storage::StorageOptions & storage_options);

// Comparison function for std::sort with our filepath convention
bool compare_relative_file(
const rcpputils::fs::path & first_path,
const rcpputils::fs::path & second_path);
};

} // namespace rosbag2_cpp

#ifdef _WIN32
# pragma warning(pop)
#endif

#endif // ROSBAG2_CPP__REINDEXER_HPP_
Loading