added table pooling and some micro-ops
This commit is contained in:
parent
4dc266201f
commit
865ac8859f
44
table.go
44
table.go
|
@ -12,9 +12,16 @@ static int get_table_length(lua_State *L, int index) {
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"strconv"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var tablePool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return make(map[string]interface{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// TableValue represents any value that can be stored in a Lua table
|
// TableValue represents any value that can be stored in a Lua table
|
||||||
type TableValue interface {
|
type TableValue interface {
|
||||||
~string | ~float64 | ~bool | ~int | ~map[string]interface{} | ~[]float64 | ~[]interface{}
|
~string | ~float64 | ~bool | ~int | ~map[string]interface{} | ~[]float64 | ~[]interface{}
|
||||||
|
@ -22,22 +29,41 @@ type TableValue interface {
|
||||||
|
|
||||||
func (s *State) GetTableLength(index int) int { return int(C.get_table_length(s.L, C.int(index))) }
|
func (s *State) GetTableLength(index int) int { return int(C.get_table_length(s.L, C.int(index))) }
|
||||||
|
|
||||||
|
// getTableFromPool gets a map from the pool and ensures it's empty
|
||||||
|
func getTableFromPool() map[string]interface{} {
|
||||||
|
table := tablePool.Get().(map[string]interface{})
|
||||||
|
// Clear any existing entries
|
||||||
|
for k := range table {
|
||||||
|
delete(table, k)
|
||||||
|
}
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
||||||
|
// putTableToPool returns a map to the pool
|
||||||
|
func putTableToPool(table map[string]interface{}) {
|
||||||
|
tablePool.Put(table)
|
||||||
|
}
|
||||||
|
|
||||||
// PushTable pushes a Go map onto the Lua stack as a table
|
// PushTable pushes a Go map onto the Lua stack as a table
|
||||||
func (s *State) PushTable(table map[string]interface{}) error {
|
func (s *State) PushTable(table map[string]interface{}) error {
|
||||||
s.NewTable()
|
s.CreateTable(0, len(table))
|
||||||
for k, v := range table {
|
for k, v := range table {
|
||||||
if err := s.PushValue(v); err != nil {
|
if err := s.PushValue(v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.SetField(-2, k)
|
s.SetField(-2, k)
|
||||||
}
|
}
|
||||||
|
// If this is a pooled table, return it
|
||||||
|
if _, hasEmptyKey := table[""]; len(table) == 1 && hasEmptyKey {
|
||||||
|
putTableToPool(table)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTable converts a Lua table to a Go map
|
// ToTable converts a Lua table to a Go map
|
||||||
func (s *State) ToTable(index int) (map[string]interface{}, error) {
|
func (s *State) ToTable(index int) (map[string]interface{}, error) {
|
||||||
absIdx := s.absIndex(index)
|
absIdx := s.absIndex(index)
|
||||||
table := make(map[string]interface{})
|
table := getTableFromPool()
|
||||||
|
|
||||||
// Check if it's an array-like table
|
// Check if it's an array-like table
|
||||||
length := s.GetTableLength(absIdx)
|
length := s.GetTableLength(absIdx)
|
||||||
|
@ -59,7 +85,10 @@ func (s *State) ToTable(index int) (map[string]interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if isArray {
|
if isArray {
|
||||||
return map[string]interface{}{"": array}, nil
|
putTableToPool(table) // Return unused table to pool
|
||||||
|
result := getTableFromPool()
|
||||||
|
result[""] = array
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,12 +100,13 @@ func (s *State) ToTable(index int) (map[string]interface{}, error) {
|
||||||
if valueType == C.LUA_TSTRING {
|
if valueType == C.LUA_TSTRING {
|
||||||
key = s.ToString(-2)
|
key = s.ToString(-2)
|
||||||
} else if valueType == C.LUA_TNUMBER {
|
} else if valueType == C.LUA_TNUMBER {
|
||||||
key = fmt.Sprintf("%g", s.ToNumber(-2))
|
key = strconv.FormatFloat(s.ToNumber(-2), 'g', -1, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
value, err := s.ToValue(-1)
|
value, err := s.ToValue(-1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Pop(1)
|
s.Pop(1)
|
||||||
|
putTableToPool(table) // Return table to pool on error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,3 +138,7 @@ func (s *State) SetTable(index int) {
|
||||||
func (s *State) GetTable(index int) {
|
func (s *State) GetTable(index int) {
|
||||||
C.lua_gettable(s.L, C.int(index))
|
C.lua_gettable(s.L, C.int(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *State) CreateTable(narr, nrec int) {
|
||||||
|
C.lua_createtable(s.L, C.int(narr), C.int(nrec))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user