-
Notifications
You must be signed in to change notification settings - Fork 6
/
cluster.go
62 lines (54 loc) · 1.64 KB
/
cluster.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package ais
import (
"bytes"
"fmt"
"strconv"
)
// Cluster is an abstraction for a []*Record. The intent is that a Cluster of
// Records are vessels that share the same geohash
type Cluster struct {
data []*Record
}
// Append adds a *Record to the underlying slice managed by the Cluster
func (c *Cluster) Append(rec *Record) {
c.data = append(c.data, rec)
}
// Size returns the length of the underlying slice managed by the Cluster.
func (c *Cluster) Size() int { return len(c.data) }
// String impelments the stringer interface for Cluster
func (c *Cluster) String() string {
buf := bytes.Buffer{}
for _, rec := range c.data {
buf.WriteString(fmt.Sprint(*rec))
buf.WriteString("\n")
}
return buf.String()
}
// Data returns the encapsulated data in the Cluster
func (c *Cluster) Data() []*Record { return c.data }
// ClusterMap is an abstraction for a map[geohash]*Cluster.
type ClusterMap map[uint64]*Cluster
// FindClusters returns a ClusterMap that groups Records in the window
// into common Clusters that share the same geohash. It requires that
// the RecordSet Window it is operating on has a 'Geohash' field stored as
// a Uint64 with the proper prefix for the hash (i.e. 0x for hex representation).
func (win *Window) FindClusters(geohashIndex int) ClusterMap {
cm := make(ClusterMap)
for _, rec := range win.Data {
geoString := (*rec)[geohashIndex]
geohash, err := strconv.ParseUint(geoString, 0, 64)
if err != nil {
panic(err)
}
if cluster, ok := cm[geohash]; ok {
cluster.Append(rec)
} else {
cm[geohash] = func(r *Record) *Cluster {
cl := new(Cluster)
cl.Append(r)
return cl
}(rec)
}
}
return cm
}