extend readme
[Mitarbeiter/Tim-Zeitz/stud-rust-base.git] / README.md
1 # Getting started with Rust
2
3 ## Installieren über Rustup
4
5 [`rustup`](https://rustup.rs/) ist ein Installer der einem das Management unterschiedlicher Compilerversionen (aktuell halten, mehrere Versionen parallel, Extra-Komponenten verwalten, etc.) abnimmt.
6 Rustup kann entweder über das Packetmanagement eurer Distribution oder die Anweisungen auf der Website installiert werden.
7 Die Website-Methode sollte auch verwendet werden, wenn Rust auf den Poolrechnern/Computes verwendet werden soll.
8 Diese installiert Rustup im Homeverzeichnis des aktuellen Nutzers.
9 Dokumentation gibt es [hier](https://github.com/rust-lang-nursery/rustup.rs/blob/master/README.md);
10
11 Den aktuellen stable Compiler könnt ihr dann mit `rustup install stable` installieren.
12 Seine Toolchains kann man mit `rustup update` gesammelt auf den aktuellen Stand bringen.
13
14 ## Rust lernen
15
16 Die Rust-Community legt Wert auf gute Dokumentation.
17 Dementsprechend sind Libraries (insbesondere die Standardlibrary) in der Regel gut dokumentiert.
18 Außerdem gibt es umfangreiche [Einstiegsressourcen](https://www.rust-lang.org/en-US/documentation.html).
19 Insbesondere mit ["Dem Buch"](https://doc.rust-lang.org/book/second-edition/index.html) kriegt man kompakt und gut sortiert einmal alle Sprachkonzepte erklärt.
20
21 ## Cargo: Buildsystem & Dependency Management
22
23 Rust hat ein Build- und Dependency Managementsystem. Yay.
24 Heißt `cargo`.
25 Mit `cargo build` kann man Programme bauen.
26 Im Falle dieses Repos baut das nur die Basislib und noch keine Executable, dazu dann z.B. `cargo build --bin example` oder statt example ein anderes Programm wie `decode_vector`.
27 Mit `cargo run` kann man bauen und direkt ausführen.
28 Argumente an das Programm kommen nach einem `--`.
29 Sobald die Performance interessant ist unbedingt `cargo run --release` nutzen - das ist ungefähr was `-O3` bei C++ ist.
30 Alles zusammen `cargo run --release --bin example -- /path/to/graph/files/dir/`.
31
32 Mit `cargo check` kann man das Programm checken ohne zu bauen, das kann einem einiges an Zeit sparen.
33
34 ## Clippy
35
36 Rust hat einen exzellenten Linter, der einem sehr hilft idiomatischen und performanten Code zu schreiben.
37 Das ist insbesondere wenn man noch nicht viel Erfahrung mit der Sprache hat extrem sinnvoll!
38 Installieren kann man Clippy mit `rustup component add clippy-preview`.
39 Anstatt `cargo check` ruft man dann `cargo clippy` auf und kann sich auf viel hilfreiches Feedback freuen.
40
41 # Rust Routenplanungs-Basis-Framework
42
43 In diesem GIT-Repository finden Sie eine kleine Codebasis die Sie zur Bearbeitung des Übungsblatts verwenden sollen.
44 Sie haben Zugriff auf vier Module und 3 Hilfsprogramme.
45
46 In `types` werden Gewichts und ID Typen definiert sowie eine wichtige Gewichtskonstante: `INFINITY`.
47 `INFINITY` repräsentiert die unendliche Distanz und ist so gewählt, dass die Konstante verdoppelt werden kann, ohne einen Überlauf zu verursachen, d.h., der Ausdruck `INFINITY < INFINITY + INFINITY` ist unproblematisch.
48 Im Modul `time` gibt es zwei Funktionen die verwendet werden können um die Laufzeit von Code zu messen.
49 Das Modul `index_heap` enthält eine Prioritätswarteschlange (`std::collections::BinaryHeap` ist problematisch für unseren Anwendungsfall, da keine `decrease_key` Operation vorhanden).
50 Das `io` Modul dienen dem Einlesen und der Ausgabe von Daten.
51 Jede Datendatei ist das binäre Abbild eines `std::vector`s im Speicher, d.h., ein Vektor von 100 `u32`s wird in einer Datei gespeichert die genau 400 Byte lang (Wir gehen stets davon aus, dass ein int 32 Bit hat.) ist.
52 Die entsprechenden Funktionen sind über Traits definiert und können so direkt auf den entsprechenden Objekten aufgerufen werden.
53 Das kann z.B. so aussehen:
54
55 ```Rust
56 extern crate stud_rust_base;
57 use stud_rust_base::io::*;
58
59 let head = Vec::<u32>::load_from("head_file_name").expect("could not read head");
60 let lat = Vec::<f32>::load_from("node_latitude_file_name").expect("could not read lat");
61 head.write_to("output_file").expect("could not write head");
62 ```
63
64 Die Dateien in `src/bin/` sind einmal ein Beispielprogramm sowieso Hilfsprogramme.
65 `encode_vector` und `decode_vector` konvertieren Vektoren von und zu textuellen Darstellungen.
66 Das Programm `compare_vector` vergleicht ob zwei Vektoren identisch sind und wenn sie es nicht sind gibt es eine Übersicht über die Unterschiede.
67 Fügen sie Ihre Programme in `src/bin/` hinzu, diese werden dann von `cargo` automatisch gefunden.
68
69 ## Docs
70
71 `cargo doc --open` öffnet die Dokumentation zu dem bereitgestelltem Code.
72
73 ## Graphen
74
75 Knoten und Kanten werden durch numerische IDs identifiziert, die von `0` bis `n-1` bzw. `m-1` gehen, wobei `n` die Anzahl an Knoten und `m` die Anzahl an gerichteten Kanten ist.
76 Wir speichern gewichtete und gerichtete Graphen in einer Ajdazenzarraydarstellung.
77 Ein gerichteter und gewichteter Graph besteht aus 3 Vektoren.
78 Diese heißen `first_out`, `head` und `weight`.
79 Um über die ausgehenden Kanten eines Knoten zu iterieren können Sie den folgenden Code verwenden:
80
81 ```Rust
82 extern crate stud_rust_base;
83 use stud_rust_base::{types::*, io::*};
84
85 let first_out = Vec::<EdgeId>::load_from("first_out_file_name").expect("could not read first_out");
86 let head = Vec::<NodeId>::load_from("head_file_name").expect("could not read head");
87 let travel_time = Vec::<Weight>::load_from("weight_file_name").expect("could not read travel_time");
88
89 let node_id = 42;
90 for edge_id in first_out[node_id] .. first_out[node_id + 1] {
91     println!("There is an arc from {} to {} with weight {}", node_id, head[edge_id as usize], travel_time[edge_id as usize]);
92 }
93 ```
94
95 **Hinweis**: `head` und `weight` haben so viel Elemente wie es Kanten gibt.
96 `first_out` hat ein Element mehr als es Knoten gibt.
97 Das erste Element von `first_out` ist immer 0 und das letzte ist die Anzahl an Kanten.
98 Für alle Graphen gibt es zwei unterschiedliche Kantengewichte: Reisezeit und Reiselänge.
99 Des Weiteren gibt es für manche Graphen zusätzliche für jeden Knoten die geographische Position.
100 Diese wird als zwei `float` Vektoren abgespeichert die für jeden Knoten den Längen- und Breitengrad angeben.
101
102 Im Verzeichnis `/algoDaten/praktikum/graph` liegen die Daten von mehreren Graphen in diesem Format.
103 Manche dienen nur zu Testzwecken während andere zur Aufgabenbewertung verwendet werden.
104 Die Testgraphen entsprechen ganz grob Stupferich, Karlsruhe\&Umgebung, Deutschland\&Umgebung und (West-)Europa.
105 Die Aufgabengraphen haben die Größe des Deutschlandgraphen.
106
107 **Achtung**: Der Europagraph könnte zu groß sein für den Hauptspeicher von manchen Poolraumrechnern.
108
109 ## Hinweise zur Nutzung im Routenplanungspraktikum
110
111 Der Quellcode soll durch das Ausführen von `cargo build --all` mit dem aktuellen stabilen Compiler (1.29.2) übersetzt werden können.
112 Auf den Poolraumrechner ist kein Rust Compiler vorinstalliert.
113 Sie können aber für ihren Nutzer lokal `rustup` und damit dann einen aktuellen Compiler installieren.
114 Die Nutzung von nicht stabilen nightly Features ist nicht erlaubt.
115 Das verwenden externer crates ist nicht erlaubt.
116 Die Rust-Standardbibliothek ist nicht extern.