-
Notifications
You must be signed in to change notification settings - Fork 8
/
compat-tests.jl
179 lines (147 loc) · 4.2 KB
/
compat-tests.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
@testitem "compat-tests" begin
module TestBlobsCompat
using Blobs
using Test
# basic sanity checks
struct Foo
x::Int64
y::Float32 # tests conversion and alignment
end
foo = Blobs.malloc_and_init(Foo)
@v foo.x = 1
@test @v(foo.x) == 1
@v foo.y = 2.5
@test (@v foo.y) == 2.5
@test (@v foo) == Foo(1,2.5)
# tests interior pointers
@test (@a foo) == foo
@test pointer(@a foo.y) == pointer(foo) + sizeof(Int64)
# tests ambiguous syntax
@test_throws LoadError eval(:(@v foo.y == 2.5))
@test_throws LoadError eval(:(@a foo.y == 2.5))
mpv = Blobs.malloc_and_init(BlobVector{Foo}, 3)
pv = @v mpv
pv[2] = Foo(2, 2.2)
@test pv[2] == Foo(2, 2.2)
@test length(pv) == 3
pv[1] = Foo(1, 1.1)
pv[3] = Foo(3, 3.3)
# tests iteration
@test collect(pv) == [Foo(1,1.1), Foo(2,2.2), Foo(3,3.3)]
# tests interior pointers
@test pointer(@a mpv[2]) - pointer(pv.data) == Blobs.self_size(Foo)
bbv = Blobs.malloc_and_init(BlobBitVector, 3)
pbv = @v bbv
pbv[2] = true
@test pbv[2] == true
@test pv[2] == Foo(2, 2.2)
pbv[1] = false
pbv[3] = false
# tests iteration
@test collect(pbv) == [false, true, false]
fill!(pbv, false)
@test collect(pbv) == [false, false, false]
# strings and unicode
s = "普通话/普通話"
mp = Blobs.malloc_and_init(BlobString, s)
p = @v mp
@test p == s
@test repr(p) == repr(s)
@test collect(p) == collect(s)
@test findfirst(p, "通") == findfirst(s, "通")
# test right-to-left
s = "سلام"
mp = Blobs.malloc_and_init(BlobString, s)
p = @v mp
@test p == s
@test repr(p) == repr(s)
@test collect(p) == collect(s)
@test findfirst(p, "ا") == findfirst(s, "ا")
# test string conversions
@test isbits(p)
@test String(p) isa String
@test String(p) == s
# test string slices
s = "aye bee sea"
mp = Blobs.malloc_and_init(BlobString, s)
p = @v mp
@test p[5:7] isa BlobString
@test p[5:7] == "bee"
# sketch of paged pmas
struct PackedMemoryArray{K,V}
keys::BlobVector{K}
values::BlobVector{V}
mask::BlobBitVector
count::Int
#...other stuff
end
function Blobs.child_size(::Type{PackedMemoryArray{K,V}}, length::Int64) where {K,V}
T = PackedMemoryArray{K,V}
+(Blobs.child_size(fieldtype(T, :keys), length),
Blobs.child_size(fieldtype(T, :values), length),
Blobs.child_size(fieldtype(T, :mask), length))
end
function Blobs.init(pma::Blob{PackedMemoryArray{K,V}}, free::Blob{Nothing}, length::Int64) where {K,V}
free = Blobs.init(pma.keys, free, length)
free = Blobs.init(pma.values, free, length)
free = Blobs.init(pma.mask, free, length)
fill!(pma.mask[], false)
pma.count[] = 0
free
end
pma = Blobs.malloc_and_init(PackedMemoryArray{Int64, Float32}, 3)
@test (@v pma.count) == 0
@test (@v pma.keys.length) == 3
# tests fill!
@test !any(@v pma.mask)
# tests pointer <-> offset conversion
@test unsafe_load(convert(Ptr{UInt64}, pointer(pma)), 1) == Blobs.self_size(PackedMemoryArray{Int64, Float32})
# tests nested interior pointers
pma2 = pma.mask[2]
@test pma2[] == false
pma2[] = true
@test pma2[] == true
@test pma.mask[2][] == true
# test api works ok with varying sizes
struct Quux
x::BlobVector{Int}
y::Float64
end
struct Bar
a::Int
b::BlobBitVector
c::Bool
d::BlobVector{Float64}
e::Blob{Quux}
end
function Blobs.child_size(::Type{Quux}, x_len::Int64, y::Float64)
T = Quux
+(Blobs.child_size(fieldtype(T, :x), x_len))
end
function Blobs.child_size(::Type{Bar}, b_len::Int64, c::Bool, d_len::Int64, x_len::Int64, y::Float64)
T = Bar
+(Blobs.child_size(fieldtype(T, :b), b_len),
Blobs.child_size(fieldtype(T, :d), d_len),
Blobs.child_size(fieldtype(T, :e), x_len, y))
end
function Blobs.init(quux::Blob{Quux}, free::Blob{Nothing}, x_len::Int64, y::Float64)
free = Blobs.init(quux.x, free, x_len)
quux.y[] = y
free
end
function Blobs.init(bar::Blob{Bar}, free::Blob{Nothing}, b_len::Int64, c::Bool, d_len::Int64, x_len::Int64, y::Float64)
free = Blobs.init(bar.b, free, b_len)
free = Blobs.init(bar.d, free, d_len)
free = Blobs.init(bar.e, free, x_len, y)
bar.c[] = c
free
end
bar = Blobs.malloc_and_init(Bar, 10, false, 20, 15, 1.5)
quux = @v bar.e
@test length(@v bar.b) == 10
@test (@v bar.c) == false
@test length(@v bar.d) == 20
@test length(@v quux.x) == 15
@test (@v quux.y) == 1.5
end
end # testitem