Skip to content

Commit

Permalink
Remove temporary set instance var used only during scan
Browse files Browse the repository at this point in the history
  • Loading branch information
chriso committed Nov 18, 2023
1 parent 59de070 commit b11980f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
24 changes: 14 additions & 10 deletions types/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ func (c *containers) insert(x container) int {
// It uses s.scanptrs to track which pointers it has already visited to avoid
// infinite loops. It does not clean it up after. I'm sure there is something
// more useful we could do with that.
func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
func (s *Serializer) scan(t reflect.Type, p unsafe.Pointer) {
s.scan1(t, p, map[reflect.Value]struct{}{})
}

func (s *Serializer) scan1(t reflect.Type, p unsafe.Pointer, seen map[reflect.Value]struct{}) {
if p == nil {
return
}
Expand All @@ -250,10 +254,10 @@ func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
}

r := reflect.NewAt(t, p)
if _, ok := s.scanptrs[r]; ok {
if _, ok := seen[r]; ok {
return
}
s.scanptrs[r] = struct{}{}
seen[r] = struct{}{}

if r.IsNil() {
return
Expand All @@ -268,7 +272,7 @@ func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
es := int(et.Size())
for i := 0; i < t.Len(); i++ {
ep := unsafe.Add(p, es*i)
scan(s, et, ep)
s.scan1(et, ep, seen)
}
case reflect.Slice:
sr := r.Elem()
Expand All @@ -288,7 +292,7 @@ func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
s.containers.add(xt, ep)
for i := 0; i < sr.Len(); i++ {
ep := unsafe.Add(ep, es*i)
scan(s, et, ep)
s.scan1(et, ep, seen)
}
case reflect.Interface:
if r.Elem().IsNil() {
Expand All @@ -308,22 +312,22 @@ func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
eptr = unsafe.Pointer(&xp)
}

scan(s, et, eptr)
s.scan1(et, eptr, seen)
case reflect.Struct:
s.containers.add(t, p)
n := t.NumField()
for i := 0; i < n; i++ {
f := t.Field(i)
ft := f.Type
fp := unsafe.Add(p, f.Offset)
scan(s, ft, fp)
s.scan1(ft, fp, seen)
}
case reflect.Pointer:
if r.Elem().IsNil() {
return
}
ep := r.Elem().UnsafePointer()
scan(s, t.Elem(), ep)
s.scan1(t.Elem(), ep, seen)
case reflect.String:
str := *(*string)(p)
sp := unsafe.StringData(str)
Expand All @@ -344,7 +348,7 @@ func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
for iter.Next() {
k := iter.Key()
kp := (*iface)(unsafe.Pointer(&k)).ptr
scan(s, kt, kp)
s.scan1(kt, kp, seen)

v := iter.Value()
vp := (*iface)(unsafe.Pointer(&v)).ptr
Expand All @@ -353,7 +357,7 @@ func scan(s *Serializer, t reflect.Type, p unsafe.Pointer) {
vp = unsafe.Pointer(&xp)
}

scan(s, vt, vp)
s.scan1(vt, vp, seen)
}
case reflect.Bool,
reflect.Int,
Expand Down
19 changes: 7 additions & 12 deletions types/serde.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ func Serialize(x any) ([]byte, error) {
p := wr.UnsafePointer() // *interface{}
t := wr.Elem().Type() // what x contains

scan(s, t, p)
// scan dirties s.scanptrs, so clean it up.
clear(s.scanptrs)
// Scan pointers to collect memory regions.
s.scan(t, p)

serializeAny(s, t, p)

Expand Down Expand Up @@ -164,9 +163,6 @@ type Serializer struct {
ptrs map[unsafe.Pointer]sID
containers containers

// TODO: move out. just used temporarily by scan
scanptrs map[reflect.Value]struct{}

// Output
b []byte
}
Expand All @@ -175,12 +171,11 @@ func newSerializer() *Serializer {
types := newTypeMap(serdes, nil)

return &Serializer{
serdes: serdes,
types: types,
funcs: newFuncMap(types, nil),
ptrs: make(map[unsafe.Pointer]sID),
scanptrs: make(map[reflect.Value]struct{}),
b: make([]byte, 0, 128),
serdes: serdes,
types: types,
funcs: newFuncMap(types, nil),
ptrs: make(map[unsafe.Pointer]sID),
b: make([]byte, 0, 128),
}
}

Expand Down

0 comments on commit b11980f

Please sign in to comment.