27 |
}; |
}; |
28 |
} |
} |
29 |
|
|
|
let (+) = Int64.add |
|
|
let (-) = Int64.sub |
|
|
|
|
30 |
let chunk_min_size = ref 65000 |
let chunk_min_size = ref 65000 |
31 |
|
|
32 |
let split_chunk c pos = |
let split_chunk c pos = |
33 |
let cc = { |
let cc = { |
34 |
created = None; |
created = None; |
35 |
pos = pos; |
pos = pos; |
36 |
len = c.len - pos; |
len = c.len -- pos; |
37 |
} in |
} in |
38 |
c.next <- Some cc; |
c.next <- Some cc; |
39 |
c.len <- (pos - c.pos) |
c.len <- pos -- c.pos |
40 |
|
|
41 |
let rec extend_chunk c size = |
let rec extend_chunk c size = |
42 |
match c.next with |
match c.next with |
49 |
append_chunk c cc; |
append_chunk c cc; |
50 |
remove_chunk cc; |
remove_chunk cc; |
51 |
c.next <- cc.next; |
c.next <- cc.next; |
52 |
c.len <- (cc.pos + cc.len) - c.pos; |
c.len <- (cc.pos ++ cc.len) -- c.pos; |
53 |
end |
end |
54 |
else |
else |
55 |
if cc.len >= size + !chunk_min_size then |
if cc.len >= size ++ !chunk_min_size then |
56 |
begin |
begin |
57 |
split_chunk cc (cc.pos + size); |
split_chunk cc (cc.pos ++ size); |
58 |
extend_chunk c size; |
extend_chunk c size; |
59 |
end |
end |
60 |
else |
else |
61 |
begin |
begin |
62 |
c.next <- cc.next; |
c.next <- cc.next; |
63 |
c.len <- (cc.pos + cc.len) - c.pos; |
c.len <- (cc.pos ++ cc.len) -- c.pos; |
64 |
ftruncate_chunk c (c.len + cc.len); |
ftruncate_chunk c (c.len ++ cc.len); |
65 |
end |
end |
66 |
|
|
67 |
let open_chunk c = () |
let open_chunk c = () |
71 |
let c = t.chunks in |
let c = t.chunks in |
72 |
let rec iter c = |
let rec iter c = |
73 |
|
|
74 |
if c.created <> None && c.pos <= pos && c.pos + c.len >= pos + len then |
if c.created <> None && c.pos <= pos && c.pos ++ c.len >= pos ++ len then |
75 |
(open_chunk c, pos - c.pos) |
(open_chunk c, pos -- c.pos) |
76 |
else |
else |
77 |
if c.created <> None && pos <= c.pos + c.len + !chunk_min_size then |
if c.created <> None && pos <= c.pos ++ c.len ++ !chunk_min_size then |
78 |
begin |
begin |
79 |
extend_chunk c (maxi !chunk_min_size (pos+len - c.pos -c.len + !chunk_min_size)); |
extend_chunk c (maxi !chunk_min_size (pos ++ len -- c.pos -- c.len ++ !chunk_min_size)); |
80 |
iter c |
iter c |
81 |
end |
end |
82 |
else |
else |
83 |
if c.pos + c.len <= pos then |
if c.pos ++ c.len <= pos then |
84 |
match c.next with |
match c.next with |
85 |
| None -> |
| None -> |
86 |
lprintf "Invalid access in file pos %Ld is after last chunk\n" pos; |
lprintf "Invalid access in file pos %Ld is after last chunk\n" pos; |
87 |
assert false |
assert false |
88 |
| Some c -> iter c |
| Some c -> iter c |
89 |
else |
else |
90 |
if c.pos + !chunk_min_size < pos then |
if c.pos ++ !chunk_min_size < pos then |
91 |
begin |
begin |
92 |
split_chunk c pos; |
split_chunk c pos; |
93 |
iter c |
iter c |
94 |
end |
end |
95 |
else |
else |
96 |
if c.pos + c.len > pos + (maxi len !chunk_min_size) + !chunk_min_size then |
if c.pos ++ c.len > pos ++ (maxi len !chunk_min_size) ++ !chunk_min_size then |
97 |
begin |
begin |
98 |
split_chunk c (pos+(maxi len !chunk_min_size)+!chunk_min_size); |
split_chunk c (pos ++ (maxi len !chunk_min_size) ++ !chunk_min_size); |
99 |
iter c |
iter c |
100 |
end |
end |
101 |
else |
else |
111 |
while t.chunks.next <> None do |
while t.chunks.next <> None do |
112 |
extend_chunk c t.size |
extend_chunk c t.size |
113 |
done; |
done; |
|
|
|
|
|
|
|
|
|