• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / ark / 13686913763

05 Mar 2025 10:35PM CUT coverage: 99.319%. Remained the same
13686913763

Pull #141

github

web-flow
Merge fb410149c into 2db7135fb
Pull Request #141: Add benchmark tables to user guide

5838 of 5878 relevant lines covered (99.32%)

34358.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/ecs/column.go
1
package ecs
2

3
import (
4
        "reflect"
5
        "unsafe"
6
)
7

8
// column storage for components in an archetype.
9
type column struct {
10
        data       reflect.Value  // data buffer
11
        pointer    unsafe.Pointer // pointer to the first element
12
        isRelation bool           // whether this column is for a relation component
13
        target     Entity         // target entity if for a relation component
14
        itemSize   uintptr        // memory size of items
15
        len        uint32         // number of items
16
        cap        uint32         // capacity
17
}
18

19
// newColumn creates a new column for a given type and capacity.
20
func newColumn(tp reflect.Type, isRelation bool, target Entity, capacity uint32) column {
2,392✔
21
        // TODO: should be use a slice instead of an array here?
2,392✔
22
        data := reflect.New(reflect.ArrayOf(int(capacity), tp)).Elem()
2,392✔
23
        pointer := data.Addr().UnsafePointer()
2,392✔
24

2,392✔
25
        return column{
2,392✔
26
                data:       data,
2,392✔
27
                pointer:    pointer,
2,392✔
28
                itemSize:   sizeOf(tp),
2,392✔
29
                isRelation: isRelation,
2,392✔
30
                target:     target,
2,392✔
31
                len:        0,
2,392✔
32
                cap:        capacity,
2,392✔
33
        }
2,392✔
34
}
2,392✔
35

36
// Len returns the number of components in the column.
37
func (c *column) Len() uint32 {
1,038,486✔
38
        return c.len
1,038,486✔
39
}
1,038,486✔
40

41
// Cap returns the current capacity of the column.
42
func (c *column) Cap() uint32 {
6✔
43
        return c.cap
6✔
44
}
6✔
45

46
// Get returns a pointer to the component at the given index.
47
func (c *column) Get(index uintptr) unsafe.Pointer {
5,063,834✔
48
        return unsafe.Add(c.pointer, index*c.itemSize)
5,063,834✔
49
}
5,063,834✔
50

51
// Add adds a component to the column.
52
func (c *column) Add(comp unsafe.Pointer) (unsafe.Pointer, uint32) {
514,722✔
53
        c.Extend(1)
514,722✔
54
        c.len++
514,722✔
55
        return c.Set(c.len-1, comp), c.len - 1
514,722✔
56
}
514,722✔
57

58
// Alloc allocates memory for the given number of components.
59
func (c *column) Alloc(n uint32) {
520,267✔
60
        c.Extend(n)
520,267✔
61
        c.len += n
520,267✔
62
}
520,267✔
63

64
func (c *column) AddAll(other *column, count uint32) {
211✔
65
        oldLen := c.len
211✔
66
        c.Alloc(count)
211✔
67
        src := other.Get(0)
211✔
68
        dst := c.Get(uintptr(oldLen))
211✔
69
        copyPtr(src, dst, c.itemSize*uintptr(count))
211✔
70
}
211✔
71

72
func (c *column) SetLast(other *column, count uint32) {
320✔
73
        start := c.len - count
320✔
74
        src := other.Get(0)
320✔
75
        dst := c.Get(uintptr(start))
320✔
76
        copyPtr(src, dst, c.itemSize*uintptr(count))
320✔
77
}
320✔
78

79
// Set overwrites the component at the given index.
80
func (c *column) Set(index uint32, comp unsafe.Pointer) unsafe.Pointer {
1,040,910✔
81
        dst := c.Get(uintptr(index))
1,040,910✔
82
        if c.itemSize == 0 {
1,042,183✔
83
                return dst
1,273✔
84
        }
1,273✔
85

86
        copyPtr(comp, dst, uintptr(c.itemSize))
1,039,637✔
87
        return dst
1,039,637✔
88
}
89

90
// Remove swap-removes the component at the given index.
91
// Returns whether a swap was necessary.
92
func (c *column) Remove(index uint32, zero unsafe.Pointer) bool {
1,027,776✔
93
        lastIndex := uintptr(c.len - 1)
1,027,776✔
94
        swapped := index != uint32(lastIndex)
1,027,776✔
95

1,027,776✔
96
        if swapped && c.itemSize != 0 {
2,050,381✔
97
                src := unsafe.Add(c.pointer, lastIndex*c.itemSize)
1,022,605✔
98
                dst := unsafe.Add(c.pointer, uintptr(index)*c.itemSize)
1,022,605✔
99
                copyPtr(src, dst, uintptr(c.itemSize))
1,022,605✔
100
        }
1,022,605✔
101
        c.len--
1,027,776✔
102
        if zero != nil {
1,542,552✔
103
                c.Zero(lastIndex, zero)
514,776✔
104
        }
514,776✔
105
        return swapped
1,027,776✔
106
}
107

108
// Extend the column to be able to store the given number of additional components.
109
// Has no effect of the column's capacity is already sufficient.
110
// If the capacity needs to be increased, it will be doubled until it is sufficient.
111
func (c *column) Extend(by uint32) {
1,034,989✔
112
        required := c.Len() + by
1,034,989✔
113
        if c.cap >= required {
2,067,690✔
114
                return
1,032,701✔
115
        }
1,032,701✔
116
        for c.cap < required {
4,666✔
117
                c.cap *= 2
2,378✔
118
        }
2,378✔
119
        old := c.data
2,288✔
120
        c.data = reflect.New(reflect.ArrayOf(int(c.cap), old.Type().Elem())).Elem()
2,288✔
121
        c.pointer = c.data.Addr().UnsafePointer()
2,288✔
122
        reflect.Copy(c.data, old)
2,288✔
123
}
124

125
// Zero resets the memory at the given index.
126
func (c *column) Zero(index uintptr, zero unsafe.Pointer) {
514,776✔
127
        if c.itemSize == 0 {
514,997✔
128
                return
221✔
129
        }
221✔
130
        dst := unsafe.Add(c.pointer, index*c.itemSize)
514,555✔
131
        copyPtr(zero, dst, uintptr(c.itemSize))
514,555✔
132
}
133

134
// Zero resets a block of storage in one buffer.
135
func (c *column) ZeroRange(start, len uint32, zero unsafe.Pointer) {
588✔
136
        size := uint32(c.itemSize)
588✔
137
        if size == 0 {
605✔
138
                return
17✔
139
        }
17✔
140
        var i uint32
571✔
141
        for i = 0; i < len; i++ {
7,726✔
142
                dst := unsafe.Add(c.pointer, (i+start)*size)
7,155✔
143
                copyPtr(zero, dst, c.itemSize)
7,155✔
144
        }
7,155✔
145
}
146

147
func (c *column) Reset(zero unsafe.Pointer) {
777✔
148
        len := c.len
777✔
149
        if c.len == 0 {
779✔
150
                return
2✔
151
        }
2✔
152
        c.len = 0
775✔
153
        if zero == nil {
961✔
154
                return
186✔
155
        }
186✔
156
        if len <= 64 { // A coarse estimate where manually zeroing is faster
1,177✔
157
                c.ZeroRange(0, len, zero)
588✔
158
        } else {
589✔
159
                c.data.SetZero()
1✔
160
        }
1✔
161
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc