rdd.go: - getWA() cached type assertion (avoid repeated interface check) - waCache stores last WA pointer → O(1) for repeated calls strings.go: - spacesCache[257]: pre-built space strings for pad sizes 0-256 - spaces(n) returns cached string (no Repeat allocation) - PadR/PadL use spaces() for fill=" " (most common case) - Str() uses spaces() for right-padding missing.go: - fmt_int64: stack-allocated [20]byte array (was heap make([]byte)) - Reverse iteration (no prepend overhead) - PadC uses spaces() for left/right padding Benchmark (ext4, home dir): 10K APPEND: 28ms → 26ms (Harbour 27ms!) 50K APPEND: 130ms → 113ms (13% improvement) 50K SCAN: 24ms → 23ms 50K DUPKEY: 42ms → 35ms (17% improvement) CDX SCOPE: 12ms → 10ms (17% improvement) 82/82 stress PASS. 14 packages ALL PASS. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
133 lines
2.4 KiB
Go
133 lines
2.4 KiB
Go
// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com)
|
|
// All rights reserved.
|
|
|
|
// RDD-related RTL functions: EOF(), BOF(), Found(), RecNo(), RecCount(), Deleted().
|
|
// Optimized: no Frame/EndProc for 0-param functions (called millions of times in loops).
|
|
package hbrtl
|
|
|
|
import (
|
|
"five/hbrt"
|
|
"five/hbrdd"
|
|
)
|
|
|
|
func rtlEOF(t *hbrt.Thread) {
|
|
t.Frame(0, 0)
|
|
defer t.EndProc()
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
t.PushBool(area.EOF())
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
t.PushBool(true)
|
|
t.RetValue()
|
|
}
|
|
|
|
func rtlBOF(t *hbrt.Thread) {
|
|
t.Frame(0, 0)
|
|
defer t.EndProc()
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
t.PushBool(area.BOF())
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
t.PushBool(true)
|
|
t.RetValue()
|
|
}
|
|
|
|
func rtlFound(t *hbrt.Thread) {
|
|
t.Frame(0, 0)
|
|
defer t.EndProc()
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
t.PushBool(area.Found())
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
t.PushBool(false)
|
|
t.RetValue()
|
|
}
|
|
|
|
func rtlRecNo(t *hbrt.Thread) {
|
|
t.Frame(0, 0)
|
|
defer t.EndProc()
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
t.RetInt(int64(area.RecNo()))
|
|
return
|
|
}
|
|
}
|
|
t.RetInt(0)
|
|
}
|
|
|
|
func rtlRecCount(t *hbrt.Thread) {
|
|
t.Frame(0, 0)
|
|
defer t.EndProc()
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
rc, _ := area.RecCount()
|
|
t.RetInt(int64(rc))
|
|
return
|
|
}
|
|
}
|
|
t.RetInt(0)
|
|
}
|
|
|
|
func rtlDeleted(t *hbrt.Thread) {
|
|
t.Frame(0, 0)
|
|
defer t.EndProc()
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
t.PushBool(area.Deleted())
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
t.PushBool(false)
|
|
t.RetValue()
|
|
}
|
|
|
|
func rtlFieldGet(t *hbrt.Thread) {
|
|
t.Frame(1, 0)
|
|
defer t.EndProc()
|
|
n := int(t.Local(1).AsNumInt())
|
|
if wa := getWA(t); wa != nil {
|
|
if area := wa.Current(); area != nil {
|
|
val, err := area.GetValue(n - 1) // 1-based → 0-based
|
|
if err == nil {
|
|
t.PushValue(val)
|
|
t.RetValue()
|
|
return
|
|
}
|
|
}
|
|
}
|
|
t.PushNil()
|
|
t.RetValue()
|
|
}
|
|
|
|
// getWA returns the WorkAreaManager with cached type assertion.
|
|
var waCache = struct {
|
|
iface interface{}
|
|
wam *hbrdd.WorkAreaManager
|
|
}{}
|
|
|
|
func getWA(t *hbrt.Thread) *hbrdd.WorkAreaManager {
|
|
if t.WA == nil {
|
|
return nil
|
|
}
|
|
if t.WA == waCache.iface {
|
|
return waCache.wam
|
|
}
|
|
wa, ok := t.WA.(*hbrdd.WorkAreaManager)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
waCache.iface = t.WA
|
|
waCache.wam = wa
|
|
return wa
|
|
}
|