Skip to content

Commit ff3d700

Browse files
committed
Store fromPos/toPos as 16-bit ints, and reorder fields for better packing
Hopefully, graphs will never get wider than 32768 characters. (They would get kind of hard to navigate if they did...) This reduces the size of the Pipe struct from 48 to 32 bytes, which makes a significant difference when there are many millions of instances.
1 parent f85a192 commit ff3d700

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

pkg/gui/presentation/graph/graph.go

+24-21
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ const (
2323
)
2424

2525
type Pipe struct {
26-
fromPos int
27-
toPos int
2826
fromHash *string
2927
toHash *string
30-
kind PipeKind
3128
style *style.TextStyle
29+
fromPos int16
30+
toPos int16
31+
kind PipeKind
3232
}
3333

3434
var (
@@ -37,11 +37,11 @@ var (
3737
StartCommitHash = "START"
3838
)
3939

40-
func (self Pipe) left() int {
40+
func (self Pipe) left() int16 {
4141
return min(self.fromPos, self.toPos)
4242
}
4343

44-
func (self Pipe) right() int {
44+
func (self Pipe) right() int16 {
4545
return max(self.fromPos, self.toPos)
4646
}
4747

@@ -107,7 +107,7 @@ func RenderAux(pipeSets [][]Pipe, commits []*models.Commit, selectedCommitHash *
107107
}
108108

109109
func getNextPipes(prevPipes []Pipe, commit *models.Commit, getStyle func(c *models.Commit) *style.TextStyle) []Pipe {
110-
maxPos := 0
110+
maxPos := int16(0)
111111
for _, pipe := range prevPipes {
112112
if pipe.toPos > maxPos {
113113
maxPos = pipe.toPos
@@ -133,6 +133,9 @@ func getNextPipes(prevPipes []Pipe, commit *models.Commit, getStyle func(c *mode
133133
}
134134

135135
// a taken spot is one where a current pipe is ending on
136+
// Note: this set and similar ones below use int instead of int16 because
137+
// that's much more efficient. We cast the int16 values we store in these
138+
// sets to int on every access.
136139
takenSpots := set.New[int]()
137140
// a traversed spot is one where a current pipe is starting on, ending on, or passing through
138141
traversedSpots := set.New[int]()
@@ -155,41 +158,41 @@ func getNextPipes(prevPipes []Pipe, commit *models.Commit, getStyle func(c *mode
155158
traversedSpotsForContinuingPipes := set.New[int]()
156159
for _, pipe := range currentPipes {
157160
if !equalHashes(pipe.toHash, commit.HashPtr()) {
158-
traversedSpotsForContinuingPipes.Add(pipe.toPos)
161+
traversedSpotsForContinuingPipes.Add(int(pipe.toPos))
159162
}
160163
}
161164

162-
getNextAvailablePosForContinuingPipe := func() int {
163-
i := 0
165+
getNextAvailablePosForContinuingPipe := func() int16 {
166+
i := int16(0)
164167
for {
165-
if !traversedSpots.Includes(i) {
168+
if !traversedSpots.Includes(int(i)) {
166169
return i
167170
}
168171
i++
169172
}
170173
}
171174

172-
getNextAvailablePosForNewPipe := func() int {
173-
i := 0
175+
getNextAvailablePosForNewPipe := func() int16 {
176+
i := int16(0)
174177
for {
175178
// a newly created pipe is not allowed to end on a spot that's already taken,
176179
// nor on a spot that's been traversed by a continuing pipe.
177-
if !takenSpots.Includes(i) && !traversedSpotsForContinuingPipes.Includes(i) {
180+
if !takenSpots.Includes(int(i)) && !traversedSpotsForContinuingPipes.Includes(int(i)) {
178181
return i
179182
}
180183
i++
181184
}
182185
}
183186

184-
traverse := func(from, to int) {
187+
traverse := func(from, to int16) {
185188
left, right := from, to
186189
if left > right {
187190
left, right = right, left
188191
}
189192
for i := left; i <= right; i++ {
190-
traversedSpots.Add(i)
193+
traversedSpots.Add(int(i))
191194
}
192-
takenSpots.Add(to)
195+
takenSpots.Add(int(to))
193196
}
194197

195198
for _, pipe := range currentPipes {
@@ -232,7 +235,7 @@ func getNextPipes(prevPipes []Pipe, commit *models.Commit, getStyle func(c *mode
232235
style: getStyle(commit),
233236
})
234237

235-
takenSpots.Add(availablePos)
238+
takenSpots.Add(int(availablePos))
236239
}
237240
}
238241

@@ -241,7 +244,7 @@ func getNextPipes(prevPipes []Pipe, commit *models.Commit, getStyle func(c *mode
241244
// continuing on, potentially moving left to fill in a blank spot
242245
last := pipe.toPos
243246
for i := pipe.toPos; i > pos; i-- {
244-
if takenSpots.Includes(i) || traversedSpots.Includes(i) {
247+
if takenSpots.Includes(int(i)) || traversedSpots.Includes(int(i)) {
245248
break
246249
} else {
247250
last = i
@@ -275,8 +278,8 @@ func renderPipeSet(
275278
selectedCommitHash *string,
276279
prevCommit *models.Commit,
277280
) string {
278-
maxPos := 0
279-
commitPos := 0
281+
maxPos := int16(0)
282+
commitPos := int16(0)
280283
startCount := 0
281284
for _, pipe := range pipes {
282285
if pipe.kind == STARTS {
@@ -292,7 +295,7 @@ func renderPipeSet(
292295
}
293296
isMerge := startCount > 1
294297

295-
cells := lo.Map(lo.Range(maxPos+1), func(i int, _ int) *Cell {
298+
cells := lo.Map(lo.Range(int(maxPos)+1), func(i int, _ int) *Cell {
296299
return &Cell{cellType: CONNECTION, style: &style.FgDefault}
297300
})
298301

0 commit comments

Comments
 (0)