-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbuckets.go
More file actions
100 lines (87 loc) · 2.61 KB
/
buckets.go
File metadata and controls
100 lines (87 loc) · 2.61 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package master
import (
"fmt"
"math"
"strconv"
"strings"
"github.com/codeuniversity/al-proto"
)
//BucketKey is of the form "<x>/<y>/<z>"-index of a cell pos
type BucketKey string
//NewBucketKey generates a BucketKey in the form of "<x>/<y>/<z>"
func NewBucketKey(x, y, z int) BucketKey {
return BucketKey(fmt.Sprintf("%d/%d/%d", x, y, z))
}
//Buckets is a map from "x/y/z"-bucket-index of the cells
type Buckets map[BucketKey][]*proto.Cell
//CreateBuckets from the cells
func CreateBuckets(cells []*proto.Cell, batchSize uint) Buckets {
dict := make(map[BucketKey][]*proto.Cell)
for _, cell := range cells {
key := bucketKeyFor(cell.Pos, batchSize)
if val, ok := dict[key]; ok {
dict[key] = append(val, cell)
} else {
dict[key] = []*proto.Cell{cell}
}
}
return dict
}
//Merge otherBuckets into the Buckets Merge is called on
func (b Buckets) Merge(otherBuckets Buckets) {
for key, cells := range otherBuckets {
b[key] = append(b[key], cells...)
}
}
//AllCells stored in the different Buckets
func (b Buckets) AllCells() []*proto.Cell {
allCells := []*proto.Cell{}
for _, cells := range b {
allCells = append(allCells, cells...)
}
return allCells
}
func bucketKeyFor(pos *proto.Vector, batchSize uint) BucketKey {
batchXPosition := axisBatchPositionFor(pos.X, batchSize)
batchYPosition := axisBatchPositionFor(pos.Y, batchSize)
batchZPosition := axisBatchPositionFor(pos.Z, batchSize)
return NewBucketKey(batchXPosition, batchYPosition, batchZPosition)
}
//SurroundingKeys of the key, including diagonals
func (k BucketKey) SurroundingKeys(width int) []BucketKey {
width64 := int64(width)
components := strings.Split(string(k), "/")
if len(components) != 3 {
return nil
}
x, err := strconv.ParseInt(components[0], 10, 32)
if err != nil {
return nil
}
y, err := strconv.ParseInt(components[1], 10, 32)
if err != nil {
return nil
}
z, err := strconv.ParseInt(components[2], 10, 32)
if err != nil {
return nil
}
keys := []BucketKey{}
for otherX := x - width64; otherX <= x+width64; otherX += width64 {
for otherY := y - width64; otherY <= y+width64; otherY += width64 {
for otherZ := z - width64; otherZ <= z+width64; otherZ += width64 {
if otherX == x && otherY == y && otherZ == z {
continue
}
keys = append(keys, NewBucketKey(int(otherX), int(otherY), int(otherZ)))
}
}
}
return keys
}
func axisBatchPositionFor(cellAxisPosition float32, batchSize uint) int {
if cellAxisPosition >= 0 {
return int(math.Ceil(float64(cellAxisPosition/float32(batchSize))) * float64(batchSize))
}
return int(math.Floor(float64(cellAxisPosition/float32(batchSize))) * float64(batchSize))
}