Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bf4c544907c5
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bb48ea11c136
Choose a head ref
  • 10 commits
  • 11 files changed
  • 1 contributor

Commits on Jul 14, 2021

  1. Copy the full SHA
    de802cc View commit details
  2. Copy the full SHA
    b7c0d9f View commit details
  3. Exclusion.

    pleroy committed Jul 14, 2021
    Copy the full SHA
    8bf2466 View commit details
  4. Bring'em back alive.

    pleroy committed Jul 14, 2021
    Copy the full SHA
    5757040 View commit details
  5. Fix the clients.

    pleroy committed Jul 14, 2021
    Copy the full SHA
    2315a17 View commit details
  6. Parameter names.

    pleroy committed Jul 14, 2021
    Copy the full SHA
    e7e317e View commit details

Commits on Jul 15, 2021

  1. After egg's review.

    pleroy committed Jul 15, 2021
    Copy the full SHA
    080d176 View commit details
  2. Lint.

    pleroy committed Jul 15, 2021
    Copy the full SHA
    0a55f5a View commit details
  3. Typo.

    pleroy committed Jul 15, 2021
    Copy the full SHA
    0e64020 View commit details
  4. Merge pull request #3063 from pleroy/TrackedForks

    Add a mechanism to exclude forks at serialization time
    pleroy authored Jul 15, 2021
    Copy the full SHA
    bb48ea1 View commit details
7 changes: 4 additions & 3 deletions ksp_plugin/part.cpp
Original file line number Diff line number Diff line change
@@ -253,7 +253,8 @@ void Part::WriteToMessage(not_null<serialization::Part*> const message,
}
rigid_motion_.WriteToMessage(message->mutable_rigid_motion());
prehistory_->WriteToMessage(message->mutable_prehistory(),
/*forks=*/{history_, psychohistory_});
/*excluded=*/{},
/*tracked=*/{history_, psychohistory_});
}

not_null<std::unique_ptr<Part>> Part::ReadFromMessage(
@@ -320,7 +321,7 @@ not_null<std::unique_ptr<Part>> Part::ReadFromMessage(
if (is_pre_cesàro) {
auto tail = DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.prehistory(),
/*forks=*/{});
/*tracked=*/{});
// The |prehistory_| and |history_| have been created by the constructor
// above. Construct the various trajectories from the |tail|.
for (auto it = tail->begin(); it != tail->end();) {
@@ -336,7 +337,7 @@ not_null<std::unique_ptr<Part>> Part::ReadFromMessage(
part->history_ = nullptr;
part->prehistory_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.prehistory(),
/*forks=*/{&part->history_, &part->psychohistory_});
/*tracked=*/{&part->history_, &part->psychohistory_});
}
return std::move(part);
}
9 changes: 5 additions & 4 deletions ksp_plugin/pile_up.cpp
Original file line number Diff line number Diff line change
@@ -177,7 +177,8 @@ void PileUp::WriteToMessage(not_null<serialization::PileUp*> message) const {
message->add_part_id(part->part_id());
}
history_->WriteToMessage(message->mutable_history(),
/*forks=*/{psychohistory_});
/*excluded=*/{},
/*tracked=*/{psychohistory_});
for (auto const& [part, rigid_motion] : actual_part_rigid_motion_) {
rigid_motion.WriteToMessage(&(
(*message->mutable_actual_part_rigid_motion())[part->part_id()]));
@@ -226,7 +227,7 @@ not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
DefaultHistoryParameters(),
DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{}),
/*tracked=*/{}),
/*psychohistory=*/nullptr,
/*angular_momentum=*/{},
ephemeris,
@@ -241,7 +242,7 @@ not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
message.fixed_step_parameters()),
DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{}),
/*tracked=*/{}),
/*psychohistory=*/nullptr,
/*angular_momentum=*/{},
ephemeris,
@@ -262,7 +263,7 @@ not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
not_null<std::unique_ptr<DiscreteTrajectory<Barycentric>>> history =
DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{&psychohistory});
/*tracked=*/{&psychohistory});
if (is_pre_frobenius) {
pile_up = std::unique_ptr<PileUp>(
new PileUp(
21 changes: 11 additions & 10 deletions ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
@@ -426,14 +426,10 @@ void Vessel::WriteToMessage(not_null<serialization::Vessel*> const message,
CHECK(Contains(parts_, part_id));
message->add_kept_parts(part_id);
}
// Starting with Gateaux we don't save the prediction, see #2685. Instead we
// save an empty prediction that we re-read as a prediction. This is a bit
// hacky, but hopefully we can remove this hack once #2400 is solved.
DiscreteTrajectory<Barycentric>* empty_prediction =
psychohistory_->NewForkAtLast();
// Starting with Gateaux we don't save the prediction, see #2685.
history_->WriteToMessage(message->mutable_history(),
/*forks=*/{psychohistory_, empty_prediction});
psychohistory_->DeleteFork(empty_prediction);
/*exclude=*/{prediction_},
/*tracked=*/{psychohistory_});
if (flight_plan_ != nullptr) {
flight_plan_->WriteToMessage(message->mutable_flight_plan());
}
@@ -475,7 +471,7 @@ not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
if (is_pre_cesàro) {
auto const psychohistory =
DiscreteTrajectory<Barycentric>::ReadFromMessage(message.history(),
/*forks=*/{});
/*tracked=*/{});
// The |history_| has been created by the constructor above. Reconstruct
// it from the |psychohistory|.
for (auto it = psychohistory->begin(); it != psychohistory->end();) {
@@ -496,12 +492,17 @@ not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
} else if (is_pre_chasles) {
vessel->history_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{&vessel->psychohistory_});
/*tracked=*/{&vessel->psychohistory_});
vessel->prediction_ = vessel->psychohistory_->NewForkAtLast();
} else {
vessel->history_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{&vessel->psychohistory_, &vessel->prediction_});
/*tracked=*/{&vessel->psychohistory_, &vessel->prediction_});
// After Grothendieck/Haar there is no empty prediction so we must create
// one here.
if (vessel->prediction_ == nullptr) {
vessel->prediction_ = vessel->psychohistory_->NewForkAtLast();
}
// Necessary after Εὔδοξος because the ephemeris has not been prolonged
// during deserialization. Doesn't hurt prior to Εὔδοξος.
ephemeris->Prolong(vessel->prediction_->back().time);
2 changes: 1 addition & 1 deletion ksp_plugin_test/planetarium_test.cpp
Original file line number Diff line number Diff line change
@@ -257,7 +257,7 @@ TEST_F(PlanetariumTest, RealSolarSystem) {
ParseFromBytes<serialization::DiscreteTrajectory>(
ReadFromBinaryFile(SOLUTION_DIR / "ksp_plugin_test" /
"planetarium_trajectory.proto.bin")),
/*forks=*/{});
/*tracked=*/{});

auto ephemeris = Ephemeris<Barycentric>::ReadFromMessage(
InfiniteFuture,
21 changes: 12 additions & 9 deletions physics/discrete_trajectory.hpp
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <vector>

#include "absl/status/status.h"
@@ -162,12 +163,13 @@ class DiscreteTrajectory : public Forkable<DiscreteTrajectory<Frame>,

// End of the implementation of the interface.

// This trajectory must be a root. Only the given |forks| are serialized.
// They must be descended from this trajectory. The pointers in |forks| may
// be null at entry.
void WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
std::vector<DiscreteTrajectory<Frame>*> const& forks) const;
// This trajectory must be a root. The entire tree is traversed and the forks
// not present in |excluded| serialized. The forks in |tracked| will be
// retrieved in the same order when reading. The pointers may be null at
// entry; otherwise, they must be direct or indirect forks of this trajectory.
void WriteToMessage(not_null<serialization::DiscreteTrajectory*> message,
std::set<DiscreteTrajectory*> const& excluded,
std::vector<DiscreteTrajectory*> const& tracked) const;

// |forks| must have a size appropriate for the |message| being deserialized
// and the orders of the |forks| must be consistent during serialization and
@@ -177,7 +179,7 @@ class DiscreteTrajectory : public Forkable<DiscreteTrajectory<Frame>,
typename = std::enable_if_t<base::is_serializable_v<F>>>
static not_null<std::unique_ptr<DiscreteTrajectory>> ReadFromMessage(
serialization::DiscreteTrajectory const& message,
std::vector<DiscreteTrajectory<Frame>**> const& forks);
std::vector<DiscreteTrajectory<Frame>**> const& tracked);

protected:
using TimelineConstIterator =
@@ -253,11 +255,12 @@ class DiscreteTrajectory : public Forkable<DiscreteTrajectory<Frame>,
// This trajectory need not be a root.
void WriteSubTreeToMessage(
not_null<serialization::DiscreteTrajectory*> message,
std::vector<DiscreteTrajectory<Frame>*>& forks) const;
std::set<DiscreteTrajectory*>& excluded,
std::vector<DiscreteTrajectory*>& tracked) const;

void FillSubTreeFromMessage(
serialization::DiscreteTrajectory const& message,
std::vector<DiscreteTrajectory<Frame>**> const& forks);
std::vector<DiscreteTrajectory<Frame>**> const& tracked);

// Returns the Hermite interpolation for the left-open, right-closed
// trajectory segment bounded above by |upper|.
28 changes: 18 additions & 10 deletions physics/discrete_trajectory_body.hpp
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#include <algorithm>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>

@@ -322,14 +323,20 @@ DegreesOfFreedom<Frame> DiscreteTrajectory<Frame>::EvaluateDegreesOfFreedom(
template<typename Frame>
void DiscreteTrajectory<Frame>::WriteToMessage(
not_null<serialization::DiscreteTrajectory*> const message,
std::vector<DiscreteTrajectory<Frame>*> const& forks)
const {
std::set<DiscreteTrajectory*> const& excluded,
std::vector<DiscreteTrajectory*> const& tracked) const {
CHECK(this->is_root());

std::vector<DiscreteTrajectory<Frame>*> mutable_forks = forks;
WriteSubTreeToMessage(message, mutable_forks);
CHECK(std::all_of(mutable_forks.begin(),
mutable_forks.end(),
std::set<DiscreteTrajectory<Frame>*> mutable_excluded = excluded;
std::vector<DiscreteTrajectory<Frame>*> mutable_tracked = tracked;
WriteSubTreeToMessage(message, mutable_excluded, mutable_tracked);
CHECK(std::all_of(mutable_excluded.begin(),
mutable_excluded.end(),
[](DiscreteTrajectory<Frame>* const fork) {
return fork == nullptr;
}));
CHECK(std::all_of(mutable_tracked.begin(),
mutable_tracked.end(),
[](DiscreteTrajectory<Frame>* const fork) {
return fork == nullptr;
}));
@@ -496,9 +503,10 @@ DiscreteTrajectory<Frame>::Downsampling::ReadFromMessage(
template<typename Frame>
void DiscreteTrajectory<Frame>::WriteSubTreeToMessage(
not_null<serialization::DiscreteTrajectory*> const message,
std::vector<DiscreteTrajectory<Frame>*>& forks) const {
std::set<DiscreteTrajectory*>& excluded,
std::vector<DiscreteTrajectory*>& tracked) const {
Forkable<DiscreteTrajectory, Iterator, DiscreteTrajectoryTraits<Frame>>::
WriteSubTreeToMessage(message, forks);
WriteSubTreeToMessage(message, excluded, tracked);
if (Flags::IsPresent("zfp", "off")) {
for (auto const& [instant, degrees_of_freedom] : timeline_) {
auto const instantaneous_degrees_of_freedom = message->add_timeline();
@@ -578,7 +586,7 @@ void DiscreteTrajectory<Frame>::WriteSubTreeToMessage(
template<typename Frame>
void DiscreteTrajectory<Frame>::FillSubTreeFromMessage(
serialization::DiscreteTrajectory const& message,
std::vector<DiscreteTrajectory<Frame>**> const& forks) {
std::vector<DiscreteTrajectory<Frame>**> const& tracked) {
bool const is_pre_frobenius = !message.has_zfp();
if (is_pre_frobenius) {
for (auto const& instantaneous_dof : message.timeline()) {
@@ -625,7 +633,7 @@ void DiscreteTrajectory<Frame>::FillSubTreeFromMessage(
Downsampling::ReadFromMessage(message.downsampling(), timeline_));
}
Forkable<DiscreteTrajectory, Iterator, DiscreteTrajectoryTraits<Frame>>::
FillSubTreeFromMessage(message, forks);
FillSubTreeFromMessage(message, tracked);
}

template<typename Frame>
16 changes: 10 additions & 6 deletions physics/discrete_trajectory_test.cpp
Original file line number Diff line number Diff line change
@@ -712,7 +712,7 @@ TEST_F(DiscreteTrajectoryDeathTest, TrajectorySerializationError) {
not_null<DiscreteTrajectory<World>*> const fork =
massive_trajectory_->NewForkWithCopy(t1_);
serialization::DiscreteTrajectory message;
fork->WriteToMessage(&message, /*forks=*/{});
fork->WriteToMessage(&message, /*excluded=*/{}, /*tracked=*/{});
}, "is_root");
}

@@ -734,10 +734,13 @@ TEST_F(DiscreteTrajectoryTest, TrajectorySerializationSuccess) {
serialization::DiscreteTrajectory message;
serialization::DiscreteTrajectory reference_message;

// Don't serialize |fork0| and |fork4|.
massive_trajectory_->WriteToMessage(&message, {fork1, fork3, fork2});
// Don't serialize |fork0|.
massive_trajectory_->WriteToMessage(&message,
/*excluded=*/{fork0},
/*tracked=*/{fork1, fork3, fork2});
massive_trajectory_->WriteToMessage(&reference_message,
{fork1, fork3, fork2});
/*excluded=*/{fork0},
/*tracked=*/{fork1, fork3, fork2});

DiscreteTrajectory<World>* deserialized_fork1 = nullptr;
DiscreteTrajectory<World>* deserialized_fork2 = nullptr;
@@ -753,6 +756,7 @@ TEST_F(DiscreteTrajectoryTest, TrajectorySerializationSuccess) {
EXPECT_EQ(t3_, deserialized_fork3->Fork()->time);
message.Clear();
deserialized_trajectory->WriteToMessage(&message,
/*excluded=*/{},
{deserialized_fork1,
deserialized_fork3,
deserialized_fork2});
@@ -942,9 +946,9 @@ TEST_F(DiscreteTrajectoryTest, DownsamplingSerialization) {
auto const circle_tmax = AppendCircularTrajectory(ω, r, Δt, t1, t2, circle);

serialization::DiscreteTrajectory message;
circle.WriteToMessage(&message, /*forks=*/{});
circle.WriteToMessage(&message, /*excluded=*/{}, /*tracked=*/{});
auto deserialized_circle =
DiscreteTrajectory<World>::ReadFromMessage(message, /*forks=*/{});
DiscreteTrajectory<World>::ReadFromMessage(message, /*tracked=*/{});

// Serialization/deserialization preserves the size, the times, and nudges the
// positions by less than the tolerance.
4 changes: 2 additions & 2 deletions physics/ephemeris_test.cpp
Original file line number Diff line number Diff line change
@@ -1067,7 +1067,7 @@ TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) {
EXPECT_EQ(1162, trajectory1.Size());

serialization::DiscreteTrajectory message;
trajectory1.WriteToMessage(&message, /*forks=*/{});
trajectory1.WriteToMessage(&message, /*excluded=*/{}, /*tracked=*/{});
std::string uncompressed;
message.SerializePartialToString(&uncompressed);
EXPECT_EQ(18'377, uncompressed.size());
@@ -1082,7 +1082,7 @@ TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) {
EXPECT_GE(16'935, compressed.size());

auto const trajectory2 =
DiscreteTrajectory<ICRS>::ReadFromMessage(message, /*forks=*/{});
DiscreteTrajectory<ICRS>::ReadFromMessage(message, /*tracked=*/{});

Length error;
for (Instant t = t0; t < t1; t += 10 * Second) {
15 changes: 11 additions & 4 deletions physics/forkable.hpp
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <vector>

#include "absl/container/inlined_vector.h"
@@ -199,14 +200,20 @@ class Forkable {
// This trajectory must be a root.
void CheckNoForksBefore(Instant const& time);

// This trajectory need not be a root. As forks are encountered during tree
// traversal their pointer is nulled-out in |forks|.
// This trajectory need not be a root. The entire tree rooted at this
// trajectory is traversed and the forks not present in |excluded| are
// serialized. The forks in |tracked| will be retrieved in the same order
// when reading. The pointers in |excluded| are removed, the pointers in
// |tracked| are nulled-out as they are used.
// Note that prior to Grothendieck/Haar all forks that were not tracked were
// implicitly excluded (so the serialized-but-not-tracked case didn't happen).
void WriteSubTreeToMessage(
not_null<serialization::DiscreteTrajectory*> message,
std::vector<Tr4jectory*>& forks) const;
std::set<Tr4jectory*>& excluded,
std::vector<Tr4jectory*>& tracked) const;

void FillSubTreeFromMessage(serialization::DiscreteTrajectory const& message,
std::vector<Tr4jectory**> const& forks);
std::vector<Tr4jectory**> const& tracked);

private:
// Constructs an Iterator by wrapping the timeline iterator
Loading