| 78 | |
| 79 | template <class Sink> |
| 80 | static void Serialize(std::vector<FeatureSpeedMacro> const & featureSpeeds, HW2SpeedMap typeSpeeds[], Sink & sink) |
| 81 | { |
| 82 | CHECK(base::IsSortedAndUnique(featureSpeeds.cbegin(), featureSpeeds.cend(), |
| 83 | [](FeatureSpeedMacro const & l, FeatureSpeedMacro const & r) |
| 84 | { return l.m_featureID < r.m_featureID; }), |
| 85 | ()); |
| 86 | |
| 87 | // Version |
| 88 | auto const startOffset = sink.Pos(); |
| 89 | WriteToSink(sink, kVersion); |
| 90 | |
| 91 | // Header |
| 92 | auto const headerOffset = sink.Pos(); |
| 93 | Header header; |
| 94 | header.Serialize(sink); |
| 95 | |
| 96 | auto const forwardMaxspeedTableOffset = sink.Pos(); |
| 97 | |
| 98 | // Saving forward (one direction) maxspeeds. |
| 99 | uint32_t maxFeatureID; |
| 100 | std::vector<uint8_t> forwardMaxspeeds = GetForwardMaxspeeds(featureSpeeds, maxFeatureID); |
| 101 | |
| 102 | size_t forwardCount = forwardMaxspeeds.size(); |
| 103 | if (forwardCount > 0) |
| 104 | { |
| 105 | succinct::elias_fano::elias_fano_builder builder(maxFeatureID + 1, forwardCount); |
| 106 | for (auto const & e : featureSpeeds) |
| 107 | if (!e.IsBidirectional()) |
| 108 | builder.push_back(e.m_featureID); |
| 109 | |
| 110 | coding::FreezeVisitor<Writer> visitor(sink); |
| 111 | succinct::elias_fano(&builder).map(visitor); |
| 112 | |
| 113 | header.m_forwardMaxspeedOffset = static_cast<uint32_t>(sink.Pos() - forwardMaxspeedTableOffset); |
| 114 | |
| 115 | coding::SimpleDenseCoding simpleDenseCoding(forwardMaxspeeds); |
| 116 | coding::Freeze(simpleDenseCoding, sink, "ForwardMaxspeeds"); |
| 117 | } |
| 118 | else |
| 119 | { |
| 120 | header.m_forwardMaxspeedOffset = 0; |
| 121 | } |
| 122 | header.m_bidirectionalMaxspeedOffset = static_cast<uint32_t>(sink.Pos() - forwardMaxspeedTableOffset); |
| 123 | |
| 124 | // Saving bidirectional maxspeeds. |
| 125 | uint32_t prevFeatureId = 0; |
| 126 | for (auto const & s : featureSpeeds) |
| 127 | { |
| 128 | if (!s.IsBidirectional()) |
| 129 | continue; |
| 130 | |
| 131 | ++header.m_bidirectionalMaxspeedNumber; |
| 132 | |
| 133 | // Valid, because we did base::IsSortedAndUnique in the beginning. |
| 134 | WriteVarUint(sink, s.m_featureID - prevFeatureId); |
| 135 | prevFeatureId = s.m_featureID; |
| 136 | |
| 137 | WriteToSink(sink, static_cast<uint8_t>(s.m_forward)); |
nothing calls this directly
no test coverage detected