pull/5/head
Jordan Orelli 10 years ago
parent 4bcbadf92f
commit 50461b87b3

52
db.go

@ -2,15 +2,12 @@ package main
import ( import (
"database/sql" "database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"math"
"math/rand"
"os" "os"
) )
var ( var (
planetIndex map[int]exoSystem planetIndex map[int]Planet
db *sql.DB db *sql.DB
) )
@ -47,7 +44,7 @@ func planetsData() {
if err != nil { if err != nil {
bail(E_No_Data, "unable to open data path: %v", err) bail(E_No_Data, "unable to open data path: %v", err)
} }
c := make(chan exoSystem) c := make(chan Planet)
go speckStream(fi, c) go speckStream(fi, c)
for planet := range c { for planet := range c {
planet.Store(db) planet.Store(db)
@ -75,53 +72,10 @@ func setupDb() {
// fillEdges(db, idx) // fillEdges(db, idx)
} }
func sq(x float64) float64 { func fillEdges(db *sql.DB, planets map[int]Planet) {
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) {
for i := 0; i < len(planets); i++ { for i := 0; i < len(planets); i++ {
for j := i + 1; j < len(planets); j++ { 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])) 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
}

@ -64,7 +64,7 @@ func handleConnection(conn *Connection) {
if otherPlanet.name == planet.name { if otherPlanet.name == planet.name {
continue continue
} }
go func(p exoSystem) { go func(p Planet) {
dist := planetDistance(*planet, p) dist := planetDistance(*planet, p)
delay := time.Duration(int64(dist * 100000000)) delay := time.Duration(int64(dist * 100000000))
time.Sleep(delay) time.Sleep(delay)

@ -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("<name: %s x: %v y: %v z: %v planets: %v>", 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
}

@ -2,15 +2,13 @@ package main
import ( import (
"bufio" "bufio"
"database/sql"
"fmt"
"io" "io"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
) )
func speckStream(r io.ReadCloser, c chan exoSystem) { func speckStream(r io.ReadCloser, c chan Planet) {
defer close(c) defer close(c)
defer r.Close() defer r.Close()
keep := regexp.MustCompile(`^\s*[\d-]`) keep := regexp.MustCompile(`^\s*[\d-]`)
@ -36,41 +34,11 @@ func speckStream(r io.ReadCloser, c chan exoSystem) {
} }
} }
type exoSystem struct { func parseSpeckLine(line []byte) *Planet {
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("<name: %s x: %v y: %v z: %v planets: %v>", e.name, e.x, e.y, e.z, e.planets)
}
func parseSpeckLine(line []byte) *exoSystem {
parts := strings.Split(string(line), " ") parts := strings.Split(string(line), " ")
var err error var err error
var g errorGroup var g errorGroup
s := new(exoSystem) s := new(Planet)
s.x, err = strconv.ParseFloat(parts[0], 64) s.x, err = strconv.ParseFloat(parts[0], 64)
g.AddError(err) g.AddError(err)

Loading…
Cancel
Save