This repository has been archived by the owner on Feb 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
RLEFiniteString32Column.go
executable file
·93 lines (77 loc) · 2.38 KB
/
RLEFiniteString32Column.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
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
package main
// A run length encoded String32 column supporting all features
// supported by the RLEFiniteString32Column
//
// The majority of the implementation is hidden in RLEUInt32Column
type RLEFiniteString32Column struct {
// Underlying storage exploits all properties of ints
contents RLEUInt32Column
// Translation and inversion structure
// for compressing strings into flat ints
translator map[string]uint32
inverter map[uint32]string
translatorCounter uint32
}
func NewRLEFiniteString32Column() RLEFiniteString32Column {
return RLEFiniteString32Column{
contents: NewRLEUInt32Column(1000000),
translator: make(map[string]uint32),
inverter: make(map[uint32]string),
translatorCounter: 0,
}
}
func (c *RLEFiniteString32Column) Push(values []string) {
translated := make([]uint32, len(values))
for i, v := range values {
key, ok := c.translator[v]
if !ok {
// Increment translator counter
c.translatorCounter += 1
key = c.translatorCounter
// Add key to translator and inverter
c.translator[v] = key
c.inverter[key] = v
}
translated[i] = key
}
// Push to underlying storage
c.contents.Push(translated)
}
// Access the value stored at the named index
//
// Provides some guarantees as Access method for the
// columns underlying storage regarding panicking
func (c *RLEFiniteString32Column) Access(index int) string {
// Fetch compact representation
raw := c.contents.Access(index)
// Return the readable string
return c.inverter[raw]
}
// Determine all values equal a provided value
// and return them positionally as a BoolColumn
func (c *RLEFiniteString32Column) Equal(value string) BoolColumn {
// Translate the string into something
// our underlying storage can handle
translated := c.translator[value]
return c.contents.Equal(translated)
}
// Determine all values equal to a member of the provided values
// and return them positionally as a BoolColumn
//
// Cannot handle empty slices, for single values call Equal instead
func (c *RLEFiniteString32Column) Within(values []string) BoolColumn {
var query *BoolColumn
for _, v := range values {
// Translate the string into something
// our underlying storage can handle
translated := c.translator[v]
result := c.contents.Equal(translated)
if query == nil {
query = &result
} else {
result = query.OR(result)
query = &result
}
}
return *query
}