Skip to content

Commit f110767

Browse files
committed
Added fretboard layout hash consing
1 parent ec703fd commit f110767

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

Diff for: fretboard_layout.go

+35-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package musicgo
22

33
import (
44
"bytes"
5+
"sync"
56
)
67

78
type StringIndex int
@@ -10,8 +11,41 @@ type FretboardLayout struct {
1011
strings []FretboardString
1112
}
1213

14+
type fretboardLayoutHashConsCacheType struct {
15+
cache []*FretboardLayout
16+
mutex sync.Mutex
17+
}
18+
19+
func (flc *fretboardLayoutHashConsCacheType) HashCons(fl *FretboardLayout) *FretboardLayout {
20+
flc.mutex.Lock()
21+
for _, existingLayout := range flc.cache {
22+
existingStrings := existingLayout.strings
23+
if len(existingStrings) != len(fl.strings) {
24+
continue
25+
}
26+
foundDifference := false
27+
for i, existingString := range existingLayout.strings {
28+
if fl.strings[i] != existingString {
29+
foundDifference = true
30+
break
31+
}
32+
}
33+
34+
if !foundDifference {
35+
flc.mutex.Unlock()
36+
return existingLayout
37+
}
38+
}
39+
flc.cache = append(flc.cache, fl)
40+
41+
flc.mutex.Unlock()
42+
return fl
43+
}
44+
45+
var fretboardLayoutCache fretboardLayoutHashConsCacheType = fretboardLayoutHashConsCacheType{}
46+
1347
func NewFretboardLayout(strings ...FretboardString) *FretboardLayout {
14-
return &FretboardLayout{strings: strings}
48+
return fretboardLayoutCache.HashCons(&FretboardLayout{strings: strings})
1549
}
1650

1751
func (fl *FretboardLayout) String() string {

Diff for: test/fretboard_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,30 @@ import (
88
"github.com/bprosnitz/musicgo/notes"
99
)
1010

11+
func TestFretboardLayoutHashConsing(t *testing.T) {
12+
if guitar.StandardTuning != NewFretboardLayout(
13+
FretboardString(notes.E.Octave(4)),
14+
FretboardString(notes.B.Octave(3)),
15+
FretboardString(notes.G.Octave(3)),
16+
FretboardString(notes.D.Octave(3)),
17+
FretboardString(notes.A.Octave(2)),
18+
FretboardString(notes.E.Octave(2))) {
19+
t.Errorf("Expected copy of standard tuning to be equal to it")
20+
}
21+
22+
if NewFretboardLayout(FretboardString(notes.A.Octave(2))) != NewFretboardLayout(FretboardString(notes.A.Octave(2))) {
23+
t.Errorf("Expected equivilent note fretboards to be equal")
24+
}
25+
26+
if NewFretboardLayout(FretboardString(notes.B.Octave(2))) == NewFretboardLayout(FretboardString(notes.A.Octave(2))) {
27+
t.Errorf("Expected different single note fretboards to not be equal")
28+
}
29+
30+
if NewFretboardLayout() != NewFretboardLayout() {
31+
t.Errorf("Expected empty fretboards to be equivilent")
32+
}
33+
}
34+
1135
func TestFretboardStringFret(t *testing.T) {
1236
type expectedResult struct {
1337
in FretboardString

0 commit comments

Comments
 (0)