diff --git a/db.go b/db.go index cdbc8ff..c245411 100644 --- a/db.go +++ b/db.go @@ -68,13 +68,43 @@ func setupDb() { planetsData() edgesTable() playersTable() - // fillEdges(db, idx) + fillEdges() } -func fillEdges(db *sql.DB, planets map[int]System) { - for i := 0; i < len(planets); i++ { - for j := i + 1; j < len(planets); j++ { - log_info("distance from %s to %s: %v", planets[i].name, planets[j].name, planetDistance(planets[i], planets[j])) +func fillEdges() { + row := db.QueryRow(`select count(*) from edges;`) + var n int + if err := row.Scan(&n); err != nil { + log_error("couldn't get number of edges: %v", err) + return + } + if n > 0 { + return + } + for i := 0; i < len(index); i++ { + for j := 0; j < len(index); j++ { + if i == j { + continue + } + if index[i] == nil { + log_error("wtf there's nil shit in here for id %d", i) + continue + } + if index[j] == nil { + log_error("wtf there's nil shit in here 2 for id %d", j) + continue + } + dist := index[i].DistanceTo(index[j]) + log_info("distance from %s to %s: %v", index[i].name, index[j].name, dist) + _, err := db.Exec(` + insert into edges + (id_1, id_2, distance) + values + (?, ?, ?) + ;`, i, j, dist) + if err != nil { + log_error("unable to write edge to db: %v", err) + } } } } diff --git a/main.go b/main.go index 1cef70a..25d24b2 100644 --- a/main.go +++ b/main.go @@ -96,6 +96,18 @@ func handleConnection(conn *Connection) { }) }(otherSystem) } + case "nearby": + neighbors, err := planet.Nearby(25) + fmt.Fprintf(conn, "fetching nearby star systems\n") + if err != nil { + log_error("%v", err) + break + } + fmt.Fprintf(conn, "found %d nearby systems\n", len(neighbors)) + for _, neighbor := range neighbors { + other := index[neighbor.id] + fmt.Fprintf(conn, "%s: %v\n", other.name, neighbor.distance) + } case "quit": return default: diff --git a/system.go b/system.go index 1d0e6a2..341ecb7 100644 --- a/system.go +++ b/system.go @@ -12,6 +12,7 @@ var ( ) type System struct { + id int x, y, z float64 planets int name string @@ -59,10 +60,44 @@ func (e System) Store(db *sql.DB) { } } +func (s *System) DistanceTo(other *System) float64 { + return dist3d(s.x, s.y, s.z, other.x, other.y, other.z) +} + func (e System) String() string { return fmt.Sprintf("", e.name, e.x, e.y, e.z, e.planets) } +type Neighbor struct { + id int + distance float64 +} + +func (e *System) Nearby(n int) ([]Neighbor, error) { + rows, err := db.Query(` + select planets.id, edges.distance + from edges + join planets on edges.id_2 = planets.id + where edges.id_1 = ? + order by distance + limit ? + ;`, e.id, n) + if err != nil { + log_error("unable to get nearby systems for %s: %v", e.name, err) + return nil, err + } + neighbors := make([]Neighbor, 0, n) + for rows.Next() { + var neighbor Neighbor + if err := rows.Scan(&neighbor.id, &neighbor.distance); err != nil { + log_error("error unpacking row from nearby neighbors query: %v", err) + continue + } + neighbors = append(neighbors, neighbor) + } + return neighbors, nil +} + func countPlanets() (int, error) { row := db.QueryRow(`select count(*) from planets`) @@ -92,13 +127,12 @@ func indexPlanets(db *sql.DB) map[int]*System { defer rows.Close() index = make(map[int]*System, 551) for rows.Next() { - var id int p := System{} - if err := rows.Scan(&id, &p.name, &p.x, &p.y, &p.z, &p.planets); err != nil { + if err := rows.Scan(&p.id, &p.name, &p.x, &p.y, &p.z, &p.planets); err != nil { log_info("unable to scan planet row: %v", err) continue } - index[id] = &p + index[p.id] = &p } return index }