Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ba8e171
load timetable sortieren
CmdrTMir Apr 28, 2025
1a1a29e
changes to load timetable for permutating locations
CmdrTMir May 12, 2025
67b5367
Merge branch 'motis-project:master' into sort-loc
CmdrTMir May 12, 2025
0597829
permutate location in .h file
CmdrTMir May 19, 2025
1f6ec16
Merge branch 'motis-project:master' into sort-loc
CmdrTMir May 19, 2025
76f0871
Merge branch 'motis-project:master' into sort-loc
CmdrTMir May 21, 2025
13ab3a8
funktion ausgelagert und nicht gebrauchte funktion gelöscht
CmdrTMir May 23, 2025
5c07cb4
Merge branch 'motis-project:master' into sort-loc
CmdrTMir May 23, 2025
1f00aed
Merge branch 'sort-loc' of github.com:CmdrTMir/nigiri into sort-loc
CmdrTMir May 23, 2025
3b3b828
clang-format
CmdrTMir May 23, 2025
5fb4faf
ausgelagert in .cc Datei
CmdrTMir May 26, 2025
d300a8b
move to init finish
CmdrTMir May 30, 2025
d7b7242
timetable update
CmdrTMir May 30, 2025
cc859bf
timetable changes
CmdrTMir May 30, 2025
b406486
Merge branch 'master' of github.com:CmdrTMir/nigiri into sort-loc
CmdrTMir May 30, 2025
fb2b28c
format
CmdrTMir May 30, 2025
87053c6
implement suggested changes
CmdrTMir Jun 2, 2025
bc9a26a
Merge branch 'master' of github.com:CmdrTMir/nigiri into sort-loc
CmdrTMir Jun 2, 2025
02fded5
implement requested changes
CmdrTMir Jun 11, 2025
5f7e0aa
fix first index
CmdrTMir Jun 11, 2025
86a79b6
permutate locations optional (=true)
CmdrTMir Jun 13, 2025
0b32292
refactor, add fields, add disclaimer, make reorder default
felixguendling Jul 13, 2025
c84cfea
remove unused header, formatting
felixguendling Jul 13, 2025
b9ff4c2
Merge branch 'master' of github.com:motis-project/nigiri into sort-loc
felixguendling Jul 13, 2025
8135e26
update cista
felixguendling Jul 13, 2025
dec68d2
formatting
felixguendling Jul 13, 2025
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: 1 addition & 1 deletion .pkg
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[cista]
url=git@github.com:felixguendling/cista.git
branch=master
commit=1fb6f1d9bb8ac9fdb4ca648df69695dd819dc07e
commit=f51e3e9251ce9df6e8c2617e3c5ed21a0ba18221
[geo]
url=git@github.com:motis-project/geo.git
branch=master
Expand Down
4 changes: 2 additions & 2 deletions .pkg.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
11896755751842712608
cista 1fb6f1d9bb8ac9fdb4ca648df69695dd819dc07e
16540055415631783859
cista f51e3e9251ce9df6e8c2617e3c5ed21a0ba18221
PEGTL 0d37dcf8f02c12a84fdf521973801a5baab78e8f
res b759b93316afeb529b6cb5b2548b24c41e382fb0
date ce88cc33b5551f66655614eeebb7c5b7189025fb
Expand Down
9 changes: 9 additions & 0 deletions include/nigiri/loader/permutate_locations.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

namespace nigiri {

struct timetable;

void permutate_locations(timetable&);

} // namespace nigiri
2 changes: 1 addition & 1 deletion include/nigiri/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static log_lvl s_verbosity;
inline std::string now() {
using clock = std::chrono::system_clock;
auto const now = clock::to_time_t(clock::now());
struct tm tmp{};
struct tm tmp {};
#if _MSC_VER >= 1400
gmtime_s(&tmp, &now);
#else
Expand Down
13 changes: 6 additions & 7 deletions include/nigiri/special_stations.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ enum class special_station : location_idx_t::value_t {
kSpecialStationsSize
};

constexpr auto const kNSpecialStations =
static_cast<std::underlying_type_t<special_station>>(
special_station::kSpecialStationsSize);

constexpr bool is_special(location_idx_t const l) {
constexpr auto const max =
static_cast<std::underlying_type_t<special_station>>(
special_station::kSpecialStationsSize);
return to_idx(l) < max;
return to_idx(l) < kNSpecialStations;
}

constexpr auto const special_stations_names =
cista::array<std::string_view,
static_cast<std::underlying_type_t<special_station>>(
special_station::kSpecialStationsSize)>{
cista::array<std::string_view, kNSpecialStations>{
"START", "END", "VIA0", "VIA1", "VIA2", "VIA3", "VIA4", "VIA5", "VIA6"};

constexpr location_idx_t get_special_station(special_station const x) {
Expand Down
16 changes: 12 additions & 4 deletions include/nigiri/timetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@

namespace nigiri {

// Warning: for better data locality, locations will be reordered in a way that
// locations with no traffic (not served by any route) are at the end (high
// index) while locations with traffic will be at the start (low index).
// This means that every added data field that (directly or indirectly)
// references location_idx_t has to be handled in permutate_locations.cc
// Don't forget to add handling to permutate_locations.cc when adding new fields
// that either use location_idx_t as index (permutate) or as value
// (re-reference).
struct timetable {
struct locations {
timezone_idx_t register_timezone(timezone tz) {
Expand Down Expand Up @@ -121,10 +129,10 @@ struct timetable {
vector_map<location_idx_t, location_type> types_;
vector_map<location_idx_t, location_idx_t> parents_;
vector_map<location_idx_t, timezone_idx_t> location_timezones_;
mutable_fws_multimap<location_idx_t, location_idx_t> equivalences_;
mutable_fws_multimap<location_idx_t, location_idx_t> children_;
mutable_fws_multimap<location_idx_t, footpath> preprocessing_footpaths_out_;
mutable_fws_multimap<location_idx_t, footpath> preprocessing_footpaths_in_;
paged_vecvec<location_idx_t, location_idx_t> equivalences_;
paged_vecvec<location_idx_t, location_idx_t> children_;
paged_vecvec<location_idx_t, footpath> preprocessing_footpaths_out_;
paged_vecvec<location_idx_t, footpath> preprocessing_footpaths_in_;
array<vecvec<location_idx_t, footpath>, kNProfiles> footpaths_out_;
array<vecvec<location_idx_t, footpath>, kNProfiles> footpaths_in_;
vector_map<timezone_idx_t, timezone> timezones_;
Expand Down
6 changes: 2 additions & 4 deletions src/loader/build_footpaths.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,9 @@ void connect_components(timetable& tt,
utl::sort(assignments);

tt.locations_.preprocessing_footpaths_out_.clear();
tt.locations_.preprocessing_footpaths_out_[location_idx_t{
tt.locations_.src_.size() - 1}];
tt.locations_.preprocessing_footpaths_out_.resize(tt.n_locations());
tt.locations_.preprocessing_footpaths_in_.clear();
tt.locations_.preprocessing_footpaths_in_[location_idx_t{
tt.locations_.src_.size() - 1}];
tt.locations_.preprocessing_footpaths_in_.resize(tt.n_locations());

auto tmp_graph = cista::raw::mutable_fws_multimap<location_idx_t, footpath>{};
auto components = std::vector<component>{};
Expand Down
18 changes: 9 additions & 9 deletions src/loader/hrd/service/service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ void parse_range(std::vector<utl::cstr> const& spec_lines,
std::vector<service::stop> const& stops,
std::vector<service::section>& sections,
service::section& begin_to_end,
TargetInformationType service::section::* member,
TargetInformationType service::section::*member,
TargetInformationParserFun parse_target_info) {
compute_ranges(spec_lines, stops, parse_info, [&](auto const& r) {
TargetInformationType target_info = parse_target_info(r.first, r.second);
Expand All @@ -156,14 +156,14 @@ void parse_range(std::vector<utl::cstr> const& spec_lines,
}

template <typename TargetInformationType, typename TargetInformationParserFun>
void parse_range(std::vector<utl::cstr> const& spec_lines,
range_parse_information const& parse_info,
std::vector<service::stop> const& stops,
std::vector<service::section>& sections,
service::section& begin_to_end,
std::optional<std::vector<TargetInformationType>>
service::section::* member,
TargetInformationParserFun parse_target_info) {
void parse_range(
std::vector<utl::cstr> const& spec_lines,
range_parse_information const& parse_info,
std::vector<service::stop> const& stops,
std::vector<service::section>& sections,
service::section& begin_to_end,
std::optional<std::vector<TargetInformationType>> service::section::*member,
TargetInformationParserFun parse_target_info) {
compute_ranges(spec_lines, stops, parse_info, [&](auto const& r) {
TargetInformationType target_info = parse_target_info(r.first, r.second);

Expand Down
3 changes: 3 additions & 0 deletions src/loader/init_finish.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "nigiri/loader/build_footpaths.h"
#include "nigiri/loader/build_lb_graph.h"
#include "nigiri/loader/permutate_locations.h"
#include "nigiri/flex.h"
#include "nigiri/special_stations.h"
#include "nigiri/timetable.h"
Expand Down Expand Up @@ -129,6 +130,8 @@ void finalize(timetable& tt, finalize_options const opt) {
tt.strings_.get(tt.providers_[b].short_name_);
});
}

permutate_locations(tt);
build_footpaths(tt, opt);
build_lb_graph<direction::kForward>(tt, kDefaultProfile);
build_lb_graph<direction::kBackward>(tt, kDefaultProfile);
Expand Down
137 changes: 137 additions & 0 deletions src/loader/permutate_locations.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include "nigiri/loader/permutate_locations.h"

#include "nigiri/special_stations.h"
#include "nigiri/timetable.h"

namespace nigiri {

template <typename T>
concept Collection = requires(T& x) {
x.begin();
x.end();
};

using permutation_t = vector_map<location_idx_t, location_idx_t>;

void update_refs(permutation_t const& p, location_idx_t& l) {
l = l == location_idx_t::invalid() ? l : p[l];
}

void update_refs(permutation_t const& p,
vecvec<route_idx_t, stop::value_type>::bucket& seq) {
for (auto& s : seq) {
auto old = stop{s};
s = stop{p[old.location_idx()], old.in_allowed(), old.out_allowed(),
old.in_allowed_wheelchair(), old.out_allowed_wheelchair()}
.value();
}
}

void update_refs(permutation_t const& p, footpath& fp) {
fp = footpath{p[fp.target()], fp.duration()};
}

template <Collection T>
void update_refs(permutation_t const& p, T& c) {
if (c.empty()) {
return;
}

for (auto it = begin(c); it != end(c); ++it) {
if constexpr (std::is_reference_v<decltype(*it)>) {
update_refs(p, *it);
} else {
update_refs(p, it);
}
}
}

void update_refs(permutation_t const& p,
hash_map<location_id, location_idx_t>& map) {
for (auto& it : map) {
update_refs(p, it.second);
}
}

template <typename Vec>
void permutate(permutation_t const& p, Vec& vec) {
auto copy = Vec{};
for (auto i = location_idx_t{0U}; i != vec.size(); ++i) {
copy.emplace_back(vec[p[i]]);
}
vec = copy;
}

std::pair<permutation_t, permutation_t> get_permutation(timetable const& tt) {
if (tt.n_locations() == 0U) {
return {};
}

auto ret = std::pair<permutation_t, permutation_t>{};
auto& [p, r] = ret;

p.resize(tt.n_locations());
std::generate(begin(p), end(p),
[l = location_idx_t{0U}]() mutable { return l++; });
auto const first_idx =
tt.n_locations() >= kNSpecialStations &&
tt.locations_.names_.at(location_idx_t{0U}).view() ==
special_stations_names[0]
? kNSpecialStations
: 0U;
std::stable_sort(begin(p) + first_idx, end(p),
[&](location_idx_t const a, location_idx_t const b) {
return !tt.location_routes_[a].empty() &&
tt.location_routes_[b].empty();
});

r.resize(tt.n_locations());
for (auto i = location_idx_t{0U}; i != tt.n_locations(); ++i) {
r[p[i]] = i;
}

return ret;
}

void permutate_locations(timetable& tt) {
for (auto i = 0U; i != kNProfiles; ++i) {
assert(tt.locations_.footpaths_out_[i].empty());
assert(tt.locations_.footpaths_in_[i].empty());
assert(tt.fwd_search_lb_graph_[i].empty());
assert(tt.bwd_search_lb_graph_[i].empty());
}
assert(tt.locations_.rtree_.nodes_.empty());

auto const [p, r] = get_permutation(tt);

auto& locations = tt.locations_;
permutate(p, tt.location_areas_);
permutate(p, tt.location_routes_);
permutate(p, tt.location_location_groups_);
permutate(p, locations.names_);
permutate(p, locations.descriptions_);
permutate(p, locations.ids_);
permutate(p, locations.coordinates_);
permutate(p, locations.src_);
permutate(p, locations.transfer_time_);
permutate(p, locations.types_);
permutate(p, locations.parents_);
permutate(p, locations.location_timezones_);
permutate(p, locations.equivalences_);
permutate(p, locations.children_);
permutate(p, locations.preprocessing_footpaths_out_);
permutate(p, locations.preprocessing_footpaths_in_);
permutate(p, locations.location_importance_);

update_refs(r, tt.route_location_seq_);
update_refs(r, tt.location_group_locations_);
update_refs(r, tt.flex_area_locations_);
update_refs(r, locations.preprocessing_footpaths_out_);
update_refs(r, locations.preprocessing_footpaths_in_);
update_refs(r, locations.equivalences_);
update_refs(r, locations.parents_);
update_refs(r, locations.children_);
update_refs(r, locations.location_id_to_idx_);
}

} // namespace nigiri
1 change: 1 addition & 0 deletions test/routing/dijkstra_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ TEST(routing, dijkstra) {
finalize(tt);

auto const d1_l = tt.locations_.location_id_to_idx_.at({"D1", src});
EXPECT_EQ("D1", (location{tt, d1_l}.name_));
auto const q_d1_c2 = query{
.start_time_ = unixtime_t{sys_days{2024_y / June / 8} + 7_hours},
.start_match_mode_ = location_match_mode::kExact,
Expand Down
Loading