this entity huffman tree stuff is crazy

master
Jordan Orelli 8 years ago
parent 8b4c666284
commit 857483bffa

@ -11,6 +11,10 @@ type Class struct {
Fields []*Field Fields []*Field
} }
func (c *Class) New() *Entity {
return &Entity{Class: c}
}
type classId struct { type classId struct {
name Symbol name Symbol
version int version int

@ -14,13 +14,21 @@ func NewContext() *Context {
} }
func (c *Context) CreateEntity(id int, r bit.Reader) { func (c *Context) CreateEntity(id int, r bit.Reader) {
classId := int(c.readClassId(r))
r.ReadBits(17) // ???
classV := int(bit.ReadVarInt(r))
className := c.classIds[classId]
class := c.Class(className, classV)
e := class.New()
e.Read(r)
} }
func (c *Context) GetEntity(id int) Entity { func (c *Context) UpdateEntity(id int, r bit.Reader) {
return Entity{}
} }
func (c *Context) DeleteEntity(id int) { func (c *Context) DeleteEntity(id int) {
} }
func (c *Context) LeaveEntity(id int) { func (c *Context) LeaveEntity(id int) {

@ -1,8 +1,12 @@
package ent package ent
import (
"github.com/jordanorelli/hyperstone/bit"
)
type Entity struct { type Entity struct {
*Class
} }
func (e *Entity) Update(raw []byte) { func (e *Entity) Read(br bit.Reader) {
} }

@ -0,0 +1,182 @@
package ent
import (
"fmt"
"io"
"sort"
"github.com/jordanorelli/hyperstone/bit"
)
type node interface {
weight() int
maxRank() int
}
// intermediate node
type iNode struct{ left, right node }
func (n iNode) String() string {
return fmt.Sprintf("{%d %d *}", n.left.weight()+n.right.weight(), n.maxRank())
}
func (n iNode) weight() int { return n.left.weight() + n.right.weight() }
func (n iNode) maxRank() int {
r := 0
switch v := n.left.(type) {
case iNode:
r2 := v.maxRank()
if r2 > r {
r = r2
}
case lNode:
if v.rank > r {
r = v.rank
}
}
switch v := n.right.(type) {
case iNode:
r2 := v.maxRank()
if r2 > r {
r = r2
}
case lNode:
if v.rank > r {
r = v.rank
}
}
return r
}
// leaf node
type lNode struct {
name string
rank int
freq int
fn func()
}
func (n lNode) String() string {
return fmt.Sprintf("{%d %d %s}", n.freq, n.rank, n.name)
}
func (n lNode) weight() int { return n.freq }
func (n lNode) maxRank() int { return n.rank }
// three-way comparison for nodes, used in sorting
func n_compare(n1, n2 node) int {
switch {
case n1.weight() < n2.weight():
return -1
case n1.weight() > n2.weight():
return 1
case n1.maxRank() < n2.maxRank():
return -1
case n1.maxRank() > n2.maxRank():
return 1
default:
return 0
}
}
// joins two nodes, creating and returning their parent node
func n_join(n1, n2 node) node {
switch n_compare(n1, n2) {
case -1:
return iNode{n1, n2}
case 0, 1:
return iNode{n2, n1}
default:
panic("not reached")
}
}
// a list of huffman nodes, for assembling a huffman tree
type nodeList []node
func (l nodeList) Len() int { return len(l) }
func (l nodeList) Less(i, j int) bool { return n_compare(l[i], l[j]) == -1 }
func (l nodeList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
func makeTree(l nodeList) node {
// at each step:
// sort the list of nodes in the tree.
// remove the last two nodes, joining them to create their parent node.
// append this parent node to the list of nodes.
// repeat until only one node remains, which is the root node.
for len(l) > 1 {
sort.Sort(sort.Reverse(l))
l = append(l[:len(l)-2], n_join(l[len(l)-2], l[len(l)-1]))
}
return l[0]
}
func walk(n node, br bit.Reader) func() {
switch v := n.(type) {
case lNode:
return v.fn
case iNode:
if bit.ReadBool(br) {
return walk(v.right, br)
} else {
return walk(v.left, br)
}
default:
panic("not reached")
}
}
func dump(n node, prefix string, w io.Writer) {
switch v := n.(type) {
case lNode:
fmt.Fprintf(w, "%s\t%v\n", prefix, v)
case iNode:
dump(v.left, prefix+"0", w)
dump(v.right, prefix+"1", w)
}
}
var hlist = nodeList{
lNode{"PlusOne", 0, 36271, func() {}},
lNode{"FieldPathEncodeFinish", 39, 25474, func() {}},
lNode{"PushOneLeftDeltaNRightNonZeroPack6Bits", 11, 10530, func() {}},
lNode{"PlusTwo", 1, 10334, func() {}},
lNode{"PlusN", 4, 4128, func() {}},
lNode{"PushOneLeftDeltaOneRightNonZero", 8, 2942, func() {}},
lNode{"PopAllButOnePlusOne", 29, 1837, func() {}},
lNode{"PlusThree", 2, 1375, func() {}},
lNode{"PlusFour", 3, 646, func() {}},
lNode{"PopAllButOnePlusNPack6Bits", 32, 634, func() {}},
lNode{"PushOneLeftDeltaNRightZero", 9, 560, func() {}},
lNode{"PushOneLeftDeltaOneRightZero", 7, 521, func() {}},
lNode{"PushOneLeftDeltaNRightNonZero", 10, 471, func() {}},
lNode{"PopAllButOnePlusNPack3Bits", 31, 300, func() {}},
lNode{"NonTopoPenultimatePlusOne", 37, 271, func() {}},
lNode{"PushOneLeftDeltaNRightNonZeroPack8Bits", 12, 251, func() {}},
lNode{"PopAllButOnePlusN", 30, 149, func() {}},
lNode{"NonTopoComplexPack4Bits", 38, 99, func() {}},
lNode{"NonTopoComplex", 36, 76, func() {}},
lNode{"PushOneLeftDeltaZeroRightZero", 5, 35, func() {}},
lNode{"PushOneLeftDeltaZeroRightNonZero", 6, 3, func() {}},
lNode{"PopNAndNonTopographical", 35, 1, func() {}},
lNode{"PopNPlusN", 34, 0, func() {}},
lNode{"PopNPlusOne", 33, 0, func() {}},
lNode{"PopOnePlusN", 28, 0, func() {}},
lNode{"PopOnePlusOne", 27, 2, func() {}},
lNode{"PushNAndNonTopological", 26, 310, func() {}},
lNode{"PushN", 25, 0, func() {}},
lNode{"PushThreePack5LeftDeltaN", 24, 0, func() {}},
lNode{"PushThreeLeftDeltaN", 23, 0, func() {}},
lNode{"PushTwoPack5LeftDeltaN", 22, 0, func() {}},
lNode{"PushTwoLeftDeltaN", 21, 0, func() {}},
lNode{"PushThreePack5LeftDeltaOne", 20, 0, func() {}},
lNode{"PushThreeLeftDeltaOne", 19, 0, func() {}},
lNode{"PushTwoPack5LeftDeltaOne", 18, 0, func() {}},
lNode{"PushTwoLeftDeltaOne", 17, 0, func() {}},
lNode{"PushThreePack5LeftDeltaZero", 16, 0, func() {}},
lNode{"PushThreeLeftDeltaZero", 15, 0, func() {}},
lNode{"PushTwoPack5LeftDeltaZero", 14, 0, func() {}},
lNode{"PushTwoLeftDeltaZero", 13, 0, func() {}},
}
var htree = makeTree(hlist)

@ -0,0 +1,14 @@
package ent
import (
"bytes"
"testing"
)
func TestDump(t *testing.T) {
t.Log(hlist)
var buf bytes.Buffer
dump(htree, "", &buf)
t.Logf("%s", buf.String())
}

@ -81,6 +81,10 @@ func (n *Namespace) MergeSendTables(st *dota.CDemoSendTables) {
} }
} }
func (n *Namespace) ReadClassId(r bit.Reader) int { func (n *Namespace) readClassId(r bit.Reader) int {
return int(r.ReadBits(uint(n.idBits))) return int(r.ReadBits(uint(n.idBits)))
} }
func (n *Namespace) Class(name string, version int) *Class {
return n.classesByName[name][version]
}

@ -49,13 +49,13 @@ func dumpEntities(m proto.Message) {
// next two bits encode one of four entity mutate operations // next two bits encode one of four entity mutate operations
switch br.ReadBits(2) { switch br.ReadBits(2) {
case 0: case 0:
// update ctx.UpdateEntity(id, br)
case 1: case 1:
// leave ctx.LeaveEntity(id)
case 2: case 2:
ctx.CreateEntity(id, br) ctx.CreateEntity(id, br)
case 3: case 3:
// delete ctx.DeleteEntity(id)
} }
} }
} }

Loading…
Cancel
Save