diff --git a/db.go b/db.go index a03e306..27271fb 100644 --- a/db.go +++ b/db.go @@ -2,15 +2,12 @@ package main import ( "database/sql" - "fmt" _ "github.com/mattn/go-sqlite3" - "math" - "math/rand" "os" ) var ( - planetIndex map[int]exoSystem + planetIndex map[int]Planet db *sql.DB ) @@ -47,7 +44,7 @@ func planetsData() { if err != nil { bail(E_No_Data, "unable to open data path: %v", err) } - c := make(chan exoSystem) + c := make(chan Planet) go speckStream(fi, c) for planet := range c { planet.Store(db) @@ -75,53 +72,10 @@ func setupDb() { // fillEdges(db, idx) } -func sq(x float64) float64 { - return x * x -} - -func dist3d(x1, y1, z1, x2, y2, z2 float64) float64 { - return math.Sqrt(sq(x1-x2) + sq(y1-y2) + sq(z1-z2)) -} - -func planetDistance(p1, p2 exoSystem) float64 { - return dist3d(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z) -} - -func indexPlanets(db *sql.DB) map[int]exoSystem { - rows, err := db.Query(`select * from planets`) - if err != nil { - log_error("unable to select all planets: %v", err) - return nil - } - defer rows.Close() - planetIndex = make(map[int]exoSystem, 551) - for rows.Next() { - var id int - p := exoSystem{} - if err := rows.Scan(&id, &p.name, &p.x, &p.y, &p.z, &p.planets); err != nil { - log_info("unable to scan planet row: %v", err) - continue - } - planetIndex[id] = p - } - return planetIndex -} - -func fillEdges(db *sql.DB, planets map[int]exoSystem) { +func fillEdges(db *sql.DB, planets map[int]Planet) { 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 randomPlanet() (*exoSystem, error) { - n := len(planetIndex) - if n == 0 { - return nil, fmt.Errorf("no planets are known to exist") - } - - pick := rand.Intn(n) - planet := planetIndex[pick] - return &planet, nil -} diff --git a/main.go b/main.go index de0485a..a8c3a2a 100644 --- a/main.go +++ b/main.go @@ -64,7 +64,7 @@ func handleConnection(conn *Connection) { if otherPlanet.name == planet.name { continue } - go func(p exoSystem) { + go func(p Planet) { dist := planetDistance(*planet, p) delay := time.Duration(int64(dist * 100000000)) time.Sleep(delay) diff --git a/planet.go b/planet.go new file mode 100644 index 0000000..5bcc909 --- /dev/null +++ b/planet.go @@ -0,0 +1,81 @@ +package main + +import ( + "database/sql" + "fmt" + "math" + "math/rand" +) + +type Planet struct { + x, y, z float64 + planets int + name string +} + +func (e Planet) Store(db *sql.DB) { + _, err := db.Exec(` + insert into planets + (name, x, y, z, planets) + values + (?, ?, ?, ?, ?) + ;`, e.name, e.x, e.y, e.z, e.planets) + if err != nil { + log_error("%v", err) + } +} + +func (e Planet) String() string { + return fmt.Sprintf("", e.name, e.x, e.y, e.z, e.planets) +} + +func countPlanets() (int, error) { + row := db.QueryRow(`select count(*) from planets`) + + var n int + err := row.Scan(&n) + return n, err +} + +func sq(x float64) float64 { + return x * x +} + +func dist3d(x1, y1, z1, x2, y2, z2 float64) float64 { + return math.Sqrt(sq(x1-x2) + sq(y1-y2) + sq(z1-z2)) +} + +func planetDistance(p1, p2 Planet) float64 { + return dist3d(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z) +} + +func indexPlanets(db *sql.DB) map[int]Planet { + rows, err := db.Query(`select * from planets`) + if err != nil { + log_error("unable to select all planets: %v", err) + return nil + } + defer rows.Close() + planetIndex = make(map[int]Planet, 551) + for rows.Next() { + var id int + p := Planet{} + if err := rows.Scan(&id, &p.name, &p.x, &p.y, &p.z, &p.planets); err != nil { + log_info("unable to scan planet row: %v", err) + continue + } + planetIndex[id] = p + } + return planetIndex +} + +func randomPlanet() (*Planet, error) { + n := len(planetIndex) + if n == 0 { + return nil, fmt.Errorf("no planets are known to exist") + } + + pick := rand.Intn(n) + planet := planetIndex[pick] + return &planet, nil +} diff --git a/speck.go b/speck.go index d936e98..aeb336e 100644 --- a/speck.go +++ b/speck.go @@ -2,15 +2,13 @@ package main import ( "bufio" - "database/sql" - "fmt" "io" "regexp" "strconv" "strings" ) -func speckStream(r io.ReadCloser, c chan exoSystem) { +func speckStream(r io.ReadCloser, c chan Planet) { defer close(c) defer r.Close() keep := regexp.MustCompile(`^\s*[\d-]`) @@ -36,41 +34,11 @@ func speckStream(r io.ReadCloser, c chan exoSystem) { } } -type exoSystem struct { - x, y, z float64 - planets int - name string -} - -func (e exoSystem) Store(db *sql.DB) { - _, err := db.Exec(` - insert into planets - (name, x, y, z, planets) - values - (?, ?, ?, ?, ?) - ;`, e.name, e.x, e.y, e.z, e.planets) - if err != nil { - log_error("%v", err) - } -} - -func countPlanets() (int, error) { - row := db.QueryRow(`select count(*) from planets`) - - var n int - err := row.Scan(&n) - return n, err -} - -func (e exoSystem) String() string { - return fmt.Sprintf("", e.name, e.x, e.y, e.z, e.planets) -} - -func parseSpeckLine(line []byte) *exoSystem { +func parseSpeckLine(line []byte) *Planet { parts := strings.Split(string(line), " ") var err error var g errorGroup - s := new(exoSystem) + s := new(Planet) s.x, err = strconv.ParseFloat(parts[0], 64) g.AddError(err)