@@ -11,16 +11,18 @@ import (
11
11
12
12
"github.com/zephyrtronium/robot/brain"
13
13
"github.com/zephyrtronium/robot/brain/braintest"
14
- "github.com/zephyrtronium/robot/userhash"
15
14
)
16
15
17
16
// membrain is an implementation of braintest.Interface using in-memory maps
18
17
// to verify that the integration tests test the correct things.
19
18
type membrain struct {
20
- mu sync.Mutex
21
- tups map [string ]map [string ][][2 ]string // map of tags to map of prefixes to id and suffix
22
- users map [userhash.Hash ][][2 ]string // map of hashes to tag and id
23
- tms map [string ]map [int64 ][]string // map of tags to map of timestamps to ids
19
+ mu sync.Mutex
20
+ tups map [string ]* memtag
21
+ }
22
+
23
+ type memtag struct {
24
+ tups map [string ][][2 ]string // map of prefixes to id and suffix
25
+ forgort map [string ]bool // set of forgorten ids
24
26
}
25
27
26
28
var _ brain.Interface = (* membrain )(nil )
@@ -30,46 +32,25 @@ func (m *membrain) Learn(ctx context.Context, tag string, msg *brain.Message, tu
30
32
defer m .mu .Unlock ()
31
33
if m .tups [tag ] == nil {
32
34
if m .tups == nil {
33
- m .tups = make (map [string ]map [string ][][2 ]string )
34
- m .users = make (map [userhash.Hash ][][2 ]string )
35
- m .tms = make (map [string ]map [int64 ][]string )
35
+ m .tups = make (map [string ]* memtag )
36
36
}
37
- m .tups [tag ] = make (map [string ][][2 ]string )
38
- m .tms [tag ] = make (map [int64 ][]string )
37
+ m .tups [tag ] = & memtag {tups : make (map [string ][][2 ]string ), forgort : make (map [string ]bool )}
39
38
}
40
- m .users [msg .Sender ] = append (m .users [msg .Sender ], [2 ]string {tag , msg .ID })
41
- tms := m .tms [tag ]
42
- tms [msg .Timestamp ] = append (tms [msg .Timestamp ], msg .ID )
43
39
r := m .tups [tag ]
44
40
for _ , tup := range tuples {
45
41
p := strings .Join (tup .Prefix , "\xff " )
46
- r [p ] = append (r [p ], [2 ]string {msg .ID , tup .Suffix })
42
+ r . tups [p ] = append (r . tups [p ], [2 ]string {msg .ID , tup .Suffix })
47
43
}
48
44
return nil
49
45
}
50
46
51
- func (m * membrain ) forgetIDLocked (tag , id string ) {
52
- for p , u := range m .tups [tag ] {
53
- for len (u ) > 0 {
54
- k := slices .IndexFunc (u , func (v [2 ]string ) bool { return v [0 ] == id })
55
- if k < 0 {
56
- break
57
- }
58
- u [k ], u [len (u )- 1 ] = u [len (u )- 1 ], u [k ]
59
- u = u [:len (u )- 1 ]
60
- }
61
- if len (u ) != 0 {
62
- m.tups [tag ][p ] = u
63
- } else {
64
- delete (m .tups [tag ], p )
65
- }
66
- }
67
- }
68
-
69
47
func (m * membrain ) Forget (ctx context.Context , tag , id string ) error {
70
48
m .mu .Lock ()
71
49
defer m .mu .Unlock ()
72
- m .forgetIDLocked (tag , id )
50
+ if m .tups [tag ] == nil {
51
+ m .tups [tag ] = & memtag {tups : make (map [string ][][2 ]string ), forgort : make (map [string ]bool )}
52
+ }
53
+ m .tups [tag ].forgort [id ] = true
73
54
return nil
74
55
}
75
56
@@ -78,7 +59,9 @@ func (m *membrain) Recall(ctx context.Context, tag string, page string, out []br
78
59
}
79
60
80
61
// Think implements brain.Interface.
81
- func (m * membrain ) Think (ctx context.Context , tag string , prefix []string ) iter.Seq [func (id * []byte , suf * []byte ) error ] {
62
+ func (m * membrain ) Think (ctx context.Context , tag string , prompt []string ) iter.Seq [func (id * []byte , suf * []byte ) error ] {
63
+ m .mu .Lock ()
64
+ defer m .mu .Unlock ()
82
65
panic ("unimplemented" )
83
66
}
84
67
@@ -87,7 +70,15 @@ func (m *membrain) Speak(ctx context.Context, tag string, prompt []string, w *br
87
70
defer m .mu .Unlock ()
88
71
var s string
89
72
if len (prompt ) == 0 {
90
- u := m .tups [tag ]["" ]
73
+ u := slices .Clone (m .tups [tag ].tups ["" ])
74
+ d := 0
75
+ for k , v := range u {
76
+ if m .tups [tag ].forgort [v [0 ]] {
77
+ u [d ], u [k ] = u [k ], u [d ]
78
+ d ++
79
+ }
80
+ }
81
+ u = u [d :]
91
82
if len (u ) == 0 {
92
83
return nil
93
84
}
@@ -98,7 +89,15 @@ func (m *membrain) Speak(ctx context.Context, tag string, prompt []string, w *br
98
89
s = brain .ReduceEntropy (prompt [len (prompt )- 1 ])
99
90
}
100
91
for range 256 {
101
- u := m.tups [tag ][s ]
92
+ u := slices .Clone (m .tups [tag ].tups [s ])
93
+ d := 0
94
+ for k , v := range u {
95
+ if m .tups [tag ].forgort [v [0 ]] {
96
+ u [d ], u [k ] = u [k ], u [d ]
97
+ d ++
98
+ }
99
+ }
100
+ u = u [d :]
102
101
if len (u ) == 0 {
103
102
break
104
103
}
0 commit comments