Skip to content

Commit 3c2ed1e

Browse files
committed
chore+feat: refactor triplestore and cardinality types
1 parent f1e40a5 commit 3c2ed1e

12 files changed

Lines changed: 153 additions & 220 deletions

File tree

algo/reach.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ func (s *ReachabilityCache) OrReach(node uint64, direction graph.Direction, dupl
278278
// from the result before the XOR operation.
279279
func (s *ReachabilityCache) XorReach(node uint64, direction graph.Direction, duplex cardinality.Duplex[uint64]) {
280280
// Reach bitmap will contain the member due to resolution of component reach
281-
reachBitmap := s.ReachOfComponentContainingMember(node, direction).Clone()
281+
reachBitmap := s.ReachOfComponentContainingMember(node, direction).Clone().(cardinality.Duplex[uint64])
282282
reachBitmap.Remove(node)
283283

284284
duplex.Xor(reachBitmap)

cardinality/cardinality.go

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,30 @@
11
package cardinality
22

3-
type ProviderConstructor[T uint32 | uint64] func() Provider[T]
3+
type ProviderConstructor[T uint32 | uint64] func() MutableProvider[T]
44
type SimplexConstructor[T uint32 | uint64] func() Simplex[T]
55
type DuplexConstructor[T uint32 | uint64] func() Duplex[T]
66

7-
// Provider describes the most basic functionality of a cardinality provider algorithm: adding elements to the provider
8-
// and producing the cardinality of those elements.
97
type Provider[T uint32 | uint64] interface {
10-
Add(value ...T)
11-
Or(other Provider[T])
12-
Clear()
138
Cardinality() uint64
9+
Clone() Provider[T]
1410
}
1511

16-
func CloneProvider[T uint32 | uint64](provider Provider[T]) Provider[T] {
17-
switch typedProvider := provider.(type) {
18-
case Simplex[T]:
19-
return typedProvider.Clone()
20-
21-
case Duplex[T]:
22-
return typedProvider.Clone()
12+
// MutableProvider describes the most basic functionality of a cardinality provider algorithm: adding elements to the provider
13+
// and producing the cardinality of those elements.
14+
type MutableProvider[T uint32 | uint64] interface {
15+
Provider[T]
2316

24-
default:
25-
return provider
26-
}
17+
Add(value ...T)
18+
Clear()
2719
}
2820

2921
// Simplex is a one-way cardinality provider that does not allow a user to retrieve encoded values back out of the
3022
// provider. This interface is suitable for algorithms such as HyperLogLog which utilizes a hash function to merge
3123
// identifiers into the cardinality provider.
3224
type Simplex[T uint32 | uint64] interface {
33-
Provider[T]
25+
MutableProvider[T]
3426

35-
Clone() Simplex[T]
27+
Or(other Provider[T])
3628
}
3729

3830
// Iterator allows enumeration of a duplex cardinality provider without requiring the allocation of the provider's set.
@@ -44,15 +36,24 @@ type Iterator[T uint32 | uint64] interface {
4436
// Duplex is a two-way cardinality provider that allows a user to retrieve encoded values back out of the provider. This
4537
// interface is suitable for algorithms that behave similar to bitvectors.
4638
type Duplex[T uint32 | uint64] interface {
47-
Provider[T]
39+
MutableProvider[T]
4840

41+
Or(other Provider[T])
4942
Xor(other Provider[T])
5043
And(other Provider[T])
5144
AndNot(other Provider[T])
45+
46+
CheckedAdd(value T) bool
5247
Remove(value T)
48+
Contains(value T) bool
49+
Slice() []T
50+
Each(delegate func(value T) bool)
51+
}
52+
53+
type ImmutableDuplex[T uint32 | uint64] interface {
54+
Provider[T]
55+
5356
Slice() []T
5457
Contains(value T) bool
5558
Each(delegate func(value T) bool)
56-
CheckedAdd(value T) bool
57-
Clone() Duplex[T]
5859
}

cardinality/hyperloglog32.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ func NewHyperLogLog32() Simplex[uint32] {
2626
}
2727
}
2828

29-
func NewHyperLogLog32Provider() Provider[uint32] {
29+
func NewHyperLogLog32Provider() MutableProvider[uint32] {
3030
return NewHyperLogLog32()
3131
}
3232

33-
func (s *hyperLogLog32) Clone() Simplex[uint32] {
33+
func (s *hyperLogLog32) Clone() Provider[uint32] {
3434
return &hyperLogLog32{
3535
sketch: s.sketch.Clone(),
3636
}

cardinality/hyperloglog64.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ func NewHyperLogLog64() Simplex[uint64] {
2626
}
2727
}
2828

29-
func NewHyperLogLog64Provider() Provider[uint64] {
29+
func NewHyperLogLog64Provider() MutableProvider[uint64] {
3030
return NewHyperLogLog64()
3131
}
3232

33-
func (s *hyperLogLog64) Clone() Simplex[uint64] {
33+
func (s *hyperLogLog64) Clone() Provider[uint64] {
3434
return &hyperLogLog64{
3535
sketch: s.sketch.Clone(),
3636
}

cardinality/lock.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ func (s threadSafeDuplex[T]) CheckedAdd(value T) bool {
100100
return s.provider.CheckedAdd(value)
101101
}
102102

103-
func (s threadSafeDuplex[T]) Clone() Duplex[T] {
103+
func (s threadSafeDuplex[T]) Clone() Provider[T] {
104104
s.lock.Lock()
105105
defer s.lock.Unlock()
106106

107-
return ThreadSafeDuplex(s.provider.Clone())
107+
return ThreadSafeDuplex(s.provider.Clone().(Duplex[T]))
108108
}
109109

110110
type threadSafeSimplex[T uint32 | uint64] struct {
@@ -147,9 +147,9 @@ func (s threadSafeSimplex[T]) Cardinality() uint64 {
147147
return s.provider.Cardinality()
148148
}
149149

150-
func (s threadSafeSimplex[T]) Clone() Simplex[T] {
150+
func (s threadSafeSimplex[T]) Clone() Provider[T] {
151151
s.lock.Lock()
152152
defer s.lock.Unlock()
153153

154-
return ThreadSafeSimplex(s.provider.Clone())
154+
return ThreadSafeSimplex(s.provider.Clone().(Simplex[T]))
155155
}

cardinality/roaring32.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func NewBitmap32() Duplex[uint32] {
2626
}
2727
}
2828

29-
func NewBitmap32Provider() Provider[uint32] {
29+
func NewBitmap32Provider() MutableProvider[uint32] {
3030
return NewBitmap32()
3131
}
3232

@@ -125,7 +125,7 @@ func (s bitmap32) Cardinality() uint64 {
125125
return s.bitmap.GetCardinality()
126126
}
127127

128-
func (s bitmap32) Clone() Duplex[uint32] {
128+
func (s bitmap32) Clone() Provider[uint32] {
129129
return bitmap32{
130130
bitmap: s.bitmap.Clone(),
131131
}

cardinality/roaring64.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func NewBitmap64() Duplex[uint64] {
2626
}
2727
}
2828

29-
func NewBitmap64Provider() Provider[uint64] {
29+
func NewBitmap64Provider() MutableProvider[uint64] {
3030
return NewBitmap64()
3131
}
3232

@@ -68,7 +68,13 @@ func (s bitmap64) CheckedAdd(value uint64) bool {
6868
}
6969

7070
func (s bitmap64) Add(values ...uint64) {
71-
s.bitmap.AddMany(values)
71+
switch len(values) {
72+
case 0:
73+
case 1:
74+
s.bitmap.Add(values[0])
75+
default:
76+
s.bitmap.AddMany(values)
77+
}
7278
}
7379

7480
func (s bitmap64) Remove(value uint64) {
@@ -123,7 +129,7 @@ func (s bitmap64) Cardinality() uint64 {
123129
return s.bitmap.GetCardinality()
124130
}
125131

126-
func (s bitmap64) Clone() Duplex[uint64] {
132+
func (s bitmap64) Clone() Provider[uint64] {
127133
return bitmap64{
128134
bitmap: s.bitmap.Clone(),
129135
}

container/adjacencymap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func (s *adjacencyMapDigraph) getAdjacent(node uint64, direction graph.Direction
119119

120120
if hasOutbound {
121121
if hasInbound {
122-
combinedAdjacent := outboundAdjacent.Clone()
122+
combinedAdjacent := outboundAdjacent.Clone().(cardinality.Duplex[uint64])
123123
combinedAdjacent.Or(inboundAdjacent)
124124

125125
return combinedAdjacent

0 commit comments

Comments
 (0)