Skip to content

Instantly share code, notes, and snippets.

@gnsx
Last active February 19, 2017 20:20
Show Gist options
  • Save gnsx/8552aa63d139e14e7150e3939f6b3b39 to your computer and use it in GitHub Desktop.
Save gnsx/8552aa63d139e14e7150e3939f6b3b39 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"gocsv"
"os"
"math"
"time"
"strconv"
"encoding/json"
"runtime"
"sync"
)
func check(e error) {
if e != nil {
panic(e)
}
}
type Location struct {
// Our example struct, you can use "-" to ignore a field fk_asset_id,lat,lon,spd,sig,hbk,tis
Id uint32 `csv:"fk_asset_id"`
Lat float64 `csv:"lat"`
Lon float64 `csv:"lon"`
Spd uint16 `csv:"spd"`
Sig uint16 `csv:"sig"`
Hbk uint16 `csv:"hbk"`
Tis uint32 `csv:"tis"`
}
type asset_inside_radius struct {
Id uint32
Tis []uint32
}
type Route_collection struct {
Lat float64
Lon float64
Air []asset_inside_radius
}
// haversin(θ) function
func hsin(theta float64) float64 {
return math.Pow(math.Sin(theta / 2), 2)
}
// Distance function returns the distance (in meters) between two points of
// a given longitude and latitude relatively accurately (using a spherical
// approximation of the Earth) through the Haversin Distance Formula for
// great arc distance on a sphere with accuracy for small distances
//
// point coordinates are supplied in degrees and converted into rad. in the func
//
// distance returned is METERS!!!!!!
// http://en.wikipedia.org/wiki/Haversine_formula
func Distance(lat1, lon1, lat2, lon2 float64) float64 {
// convert to radians
// must cast radius as float to multiply later
var la1, lo1, la2, lo2, r float64
la1 = lat1 * 0.01745329251
lo1 = lon1 * 0.01745329251
la2 = lat2 * 0.01745329251
lo2 = lon2 * 0.01745329251
r = 6378137 // Earth radius in METERS
// calculate
h := hsin(la2 - la1) + math.Cos(la1) * math.Cos(la2) * hsin(lo2 - lo1)
return 2 * r * math.Asin(math.Sqrt(h))
}
var ri = 0
var ni = 0
func parse_locations(i int, Location_in []*Location) {
var skip_lock = false
internal_rc := ri
lock = false
temp_route_collector := new(Route_collection)
temp_route_collector.Lat = Location_in[i].Lat
temp_route_collector.Lon = Location_in[i].Lon
route_collector = append(route_collector, temp_route_collector)
count_good := 0
for _, second_Location := range Location_in {
distance := Distance(Location_in[i].Lat, Location_in[i].Lon, second_Location.Lat, second_Location.Lon)
if ( distance < 5 && second_Location.Spd > 0) {
count_good++
//log.Printf("Iteration: %d Tis: %d",second_Location.Id,second_Location.Tis)
is_not_unique := false
tis_iterator := 0
if internal_rc < len(route_collector) {
for _, t_air := range route_collector[internal_rc].Air {
if (t_air.Id == second_Location.Id) {
is_not_unique = true
//t_air.Tis = append (t_air.Tis, second_Location.Tis)
route_collector[internal_rc].Air[tis_iterator].Tis = append(route_collector[internal_rc].Air[tis_iterator].Tis, second_Location.Tis)
//log.Printf("Appended TIS since new ID was found")
}
//log.Printf("Tis Iterator Count %d,",tis_iterator)
tis_iterator++
}
if (is_not_unique == false) {
ta_air := asset_inside_radius{}
ta_air.Id = second_Location.Id
ta_air.Tis = append(ta_air.Tis, second_Location.Tis)
route_collector[internal_rc].Air = append(route_collector[internal_rc].Air, ta_air)
//log.Printf("Appended New Route")
}
skip_lock = false
} else {
fmt.Printf("\nIndex Out for %d", internal_rc)
skip_lock = true
}
}
}
//FIle Dumopp code here
//log.Printf("%d i:%d", count_good, i)
if skip_lock == false {
for lock == true {
fmt.Printf("\nWaiting to get unlocked from %d", internal_rc)
}
lock = true
ri++
ni++
}
}
var lock = false
func lock_ri() {
ri++
ni++
}
var route_collector = []*Route_collection{}
func main() {
//var mutex = &sync.Mutex{}
now := time.Now()
secs := now.Unix()
s := strconv.Itoa(int(secs))
f, err := os.Create(s + ".raw")
check(err)
defer f.Close()
LocationsFile, err := os.OpenFile("psf.data", os.O_RDONLY | os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}
defer LocationsFile.Close()
Loc := []*Location{}
if err := gocsv.UnmarshalFile(LocationsFile, &Loc); err != nil {
// Load Locations from file
panic(err)
}
fmt.Printf("Done Marshalling\n")
runtime.GOMAXPROCS(4)
var wg sync.WaitGroup
wg.Add(6)
total_no_locations := len(Loc)
fmt.Printf("Length of Location %d", total_no_locations)
//file_is_busy := false
//1st loop
go func() {
defer wg.Done()
//Loop A Iterate
for ni < total_no_locations {
//mutex.Lock()
parse_locations(ni, Loc)
//lock_ri()
//mutex.Unlock()
}
lock = false
fmt.Printf("Out0")
}()
go func() {
defer wg.Done()
//Loop A Iterate
for ni < total_no_locations {
//mutex.Lock()
parse_locations(ni, Loc)
//lock_ri()
//mutex.Unlock()
}
lock = false
fmt.Printf("Out1")
}()
go func() {
defer wg.Done()
//Loop A Iterate
for ni < total_no_locations {
//mutex.Lock()
parse_locations(ni, Loc)
//lock_ri()
//mutex.Unlock()
}
lock = false
fmt.Printf("Out2")
}()
go func() {
defer wg.Done()
//Loop A Iterate
for ni < total_no_locations {
//mutex.Lock()
parse_locations(ni, Loc)
//lock_ri()
//mutex.Unlock()
}
lock = false
fmt.Printf("Out3")
}()
go func() {
defer wg.Done()
//Loop A Iterate
for ni < total_no_locations {
//mutex.Lock()
parse_locations(ni, Loc)
//lock_ri()
//mutex.Unlock()
}
lock = false
fmt.Printf("Out4")
}()
go func() {
defer wg.Done()
//Loop A Iterate
for ni < total_no_locations {
fmt.Printf("\nLocation :%d", ni)
time.Sleep(10 * time.Second)
}
fmt.Printf("\nThat's all folks")
}()
wg.Wait()
fmt.Println("\nCompute Finished going to write into file")
//File Dump Code Final
b, err := json.Marshal(route_collector)
if err != nil {
fmt.Println(err)
return
}
str := fmt.Sprint("\n", string(b))
f.WriteString(str)
f.Sync()
f.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment