diff --git a/ent/class.go b/ent/class.go index 7f8357e..50b2a98 100644 --- a/ent/class.go +++ b/ent/class.go @@ -14,11 +14,15 @@ type Class struct { // all other entities for this class use this instance as a prototype baseline *Entity + // maps field names back to their indexes. Entities use this to access + // their own fields by name instead of by slot. + fieldNames map[string]int + fp *fieldPath } func (c *Class) New() *Entity { - return &Entity{Class: c, fields: make(map[string]interface{}, len(c.Fields))} + return &Entity{Class: c} } func (c Class) String() string { diff --git a/ent/entity.go b/ent/entity.go index 220c227..e05f558 100644 --- a/ent/entity.go +++ b/ent/entity.go @@ -8,7 +8,6 @@ import ( type Entity struct { *Class - fields map[string]interface{} } func (e *Entity) Read(br bit.Reader) error { diff --git a/ent/fieldpath.go b/ent/fieldpath.go index 4e5e412..57978d2 100644 --- a/ent/fieldpath.go +++ b/ent/fieldpath.go @@ -7,16 +7,26 @@ import ( type fieldPath struct { // slice of values, to be reused over and over - vals []int + vals [6]int + // index of the last valid value. e.g., the head of the stack. last int - history [][]int + // history of fieldpath values. that is, all selections thus far. + // Everything is fixed width to avoid allocations as much as possible + // inside of the fieldpath stuff. history lengths are known to go over 500, + // but I honestly have no idea if there is or isn't a limit. this is a + // hazard. + history [1024][7]int + + // last valid index of a history entry + hlast int } func newFieldPath() *fieldPath { - f := &fieldPath{vals: make([]int, 32)} + f := new(fieldPath) f.vals[f.last] = -1 + f.hlast = -1 return f } @@ -50,11 +60,29 @@ func (f *fieldPath) read(br bit.Reader, n node, class *Class) error { } fn(f, br) Debug.Printf("fieldpath: %v", f.path()) - // Debug.Printf("fieldpath: %v", f.getField(class)) + f.keep() } return nil } +// adds our current vals to the history list. +// a history list entry is an array of ints, 7 ints wide. a fieldPath value is +// 6 ints wide. a history value encodes the number of valid entries in its +// first position. e.g., this: +// [0 0 0 0 0 0 0] +// would indicate the selection [0] +// [0 4 0 0 0 0 0] +// would indicate the selection [4] +// [1 4 2 0 0 0 0] +// would indicate the selection [4 2] +func (f *fieldPath) keep() { + f.hlast++ + f.history[f.hlast][0] = f.last + for i := 0; i <= f.last; i++ { + f.history[f.hlast][i+1] = f.vals[i] + } +} + func (f *fieldPath) getField(class *Class) *Field { if f.last > 0 { for i := 0; i < f.last; i++ {