...
1go build main.go
2! stdout .
3! stderr .
4
5-- main.go --
6
7package main
8
9import (
10 "p/b"
11)
12
13func main() {
14 f()
15}
16
17func f() {
18 typ := indexedPageType{newIndexedType(nil)}
19 page := newPage(typ.indexedType)
20 page.Data()
21}
22
23func newPage(typ *indexedType) Page {
24 values := typ.NewValues(nil, nil)
25 return &indexedPage{
26 typ: typ,
27 values: values.Int32(),
28 columnIndex: ^0,
29 }
30}
31
32type Type interface {
33 NewPage(columnIndex, numValues int, data b.Values) Page
34 NewValues(values []byte, offsets []uint32) b.Values
35}
36
37type Page interface {
38 Type() Type
39 Data() b.Values
40}
41
42type indexedPage struct {
43 typ *indexedType
44 values []int32
45 columnIndex int16
46}
47
48func (page *indexedPage) Type() Type { return indexedPageType{page.typ} }
49
50func (page *indexedPage) Data() b.Values { return b.Int32Values(page.values) }
51
52type indexedType struct {
53 Type
54}
55
56func newIndexedType(typ Type) *indexedType {
57 return &indexedType{Type: typ}
58}
59
60type indexedPageType struct{ *indexedType }
61
62func (t indexedPageType) NewValues(values []byte, _ []uint32) b.Values {
63 return b.Int32ValuesFromBytes(values)
64}
65
66-- go.mod --
67module p
68
69go 1.24
70
71-- internal/a/a.go --
72package a
73
74import "unsafe"
75
76type slice struct {
77 ptr unsafe.Pointer
78 len int
79 cap int
80}
81
82func Slice[To, From any](data []From) []To {
83 // This function could use unsafe.Slice but it would drop the capacity
84 // information, so instead we implement the type conversion.
85 var zf From
86 var zt To
87 var s = slice{
88 ptr: unsafe.Pointer(unsafe.SliceData(data)),
89 len: int((uintptr(len(data)) * unsafe.Sizeof(zf)) / unsafe.Sizeof(zt)),
90 cap: int((uintptr(cap(data)) * unsafe.Sizeof(zf)) / unsafe.Sizeof(zt)),
91 }
92 return *(*[]To)(unsafe.Pointer(&s))
93}
94
95-- b/b.go --
96package b
97
98import "p/internal/a"
99
100type Kind int32
101
102const Int32 Kind = iota + 2
103
104type Values struct {
105 kind Kind
106 size int32
107 data []byte
108 offsets []uint32
109}
110
111func (v *Values) Int32() []int32 {
112 return a.Slice[int32](v.data)
113}
114
115func makeValues[T any](kind Kind, values []T) Values {
116 return Values{kind: kind, data: a.Slice[byte](values)}
117}
118
119func Int32Values(values []int32) Values {
120 return makeValues(Int32, values)
121}
122
123func Int32ValuesFromBytes(values []byte) Values {
124 return Values{kind: Int32, data: values}
125}
View as plain text