-
Notifications
You must be signed in to change notification settings - Fork 4
/
disk.jl
108 lines (92 loc) · 2.01 KB
/
disk.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
export DiskVector
type DiskVector{T} <: AVector{T}
length::Int
file::String
handle::IOStream
pos::Int
end
typealias DiskVectorT{T} Type{DiskVector{T}}
function (::DiskVectorT{T}){T}()
file = tempname()
v = DiskVector{T}(0, file, open(file, "a+"), 1)
finalizer(v, close)
return v
end
function (::DiskVectorT{T}){T}(xs)
v = DiskVector{T}()
for x in xs
push!(v, x)
end
return v
end
DiskVector() = DiskVector{Any}()
DiskVector(xs) = DiskVector{eltype(xs)}(xs)
function Base.close(v::DiskVector)
isopen(v.handle) && close(v.handle)
isfile(v.file) && rm(v.file)
end
Base.size(v::DiskVector) = (v.length,)
function Base.push!{T}(v::DiskVector{T}, x::T)
# warn("pushing single value")
seekto(v, :end)
if isbits(T)
write(v.handle, x)
else
serialize(v.handle, x)
end
v.length += 1
v.pos += 1
return v
end
function Base.append!{T}(v::DiskVector{T}, xs::AbstractVector{T})
seekto(v, :end)
@assert isbits(T)
write(v.handle, xs)
v.length += length(xs)
v.pos = v.length+1
return v
end
function seekto(v::DiskVector, i)
if i == :end
if v.pos ≤ v.length
seekend(v.handle)
v.pos = v.length+1
end
elseif v.pos ≠ i
@assert isbits(eltype(v))
v.pos = i
seek(v.handle, sizeof(eltype(v))*(i-1))
end
end
function Base.getindex(v::DiskVector, i::Integer)
# warn("reading single value")
seekto(v, i)
v.pos += 1
return read(v.handle, eltype(v))
end
function Base.setindex!{T}(v::DiskVector{T}, x::T, i::Integer)
@assert isbits(x)
# warn("writing single value")
seekto(v, i)
write(v.handle, x)
v.pos += 1
return x
end
function Base.copy!{T}(v::AbstractVector{T}, xs::DiskVector{T})
@assert isbits(T)
seekstart(xs.handle)
read!(xs.handle, v)
return v
end
function Base.collect(xs::DiskVector)
if isempty(xs)
Vector{eltype(xs)}()
else
copy!(Vector{eltype(xs)}(length(xs)), xs)
end
end
function Base.similar(v::DiskVector, n::Integer)
@assert n == 0
DiskVector{eltype(v)}()
end
# run(`open $(dirname(tempname()))`)