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 ^L
81
82
83 cm_compact:
84 proc (p_file_opening_id, p_number_of_slots, p_element_id, p_basic_control_interval_header_ptr, p_code);
85
86
87
88
89 dcl p_ci_buffer_ptr ptr;
90 dcl p_file_opening_id bit (36) aligned;
91 dcl p_number_of_slots fixed bin;
92 dcl p_element_id bit (36) aligned;
93 dcl p_basic_control_interval_header_ptr
94 ptr;
95 dcl p_code fixed bin (35);
96
97
98
99 dcl code fixed bin (35);
100 dcl ci_length_in_bytes fixed bin (21);
101 dcl datum_length_in_bytes fixed bin (17);
102 dcl old_datum_offset fixed bin;
103 dcl new_datum_offset fixed bin;
104 dcl old_slot_idx fixed bin init (-1);
105 dcl new_slot_idx fixed bin init (-1);
106 dcl new_ci_ptr ptr;
107 dcl old_ci_ptr ptr;
108 dcl (is_buffered, is_replacement)
109 bit (1) aligned;
110
111 dcl new_ci (CONTROL_INTERVAL_ADDRESSABLE_LENGTH_IN_BYTES / BYTES_PER_DOUBLE_WORD) fixed
112 bin (71);
113 dcl old_ci (CONTROL_INTERVAL_ADDRESSABLE_LENGTH_IN_BYTES / BYTES_PER_DOUBLE_WORD) fixed
114 bin (71);
115
116
117
118 dcl based_ci char (ci_length_in_bytes) based;
119
120
121
122 dcl (addr, ceil, divide, hbound, null, string, substr, unspec)
123 builtin;
124
125
126
127
128 dcl myname init ("cm_compact") char (32) varying internal static options (constant);
129 dcl BITS_PER_BYTE fixed bin init (9) int static options (constant);
130 dcl BYTES_PER_DOUBLE_WORD fixed bin init (8) int static options (constant);
131 dcl START_OF_CI_OFFSET fixed bin (21) init (0) int static options (constant);
132
133
134
135 dcl file_manager_$simple_get
136 entry (bit (36) aligned, fixed bin (27), fixed bin (21), ptr, fixed bin (21),
137 fixed bin (35));
138 dcl file_manager_$simple_put
139 entry (bit (36) aligned, fixed bin (27), fixed bin (21), ptr, fixed bin (21),
140 fixed bin (35));
141 dcl sub_err_ entry () options (variable);
142
143
144
145 dcl dm_error_$unimplemented_ci_version
146 ext fixed bin (35);
147
148
149 ^L
150 is_buffered = "0"b;
151 is_replacement = "0"b;
152 go to JOIN;
153
154
155 replacement:
156 entry (p_file_opening_id, p_number_of_slots, p_element_id, p_basic_control_interval_header_ptr, p_code);
157
158 is_buffered = "0"b;
159 is_replacement = "1"b;
160 go to JOIN;
161
162 buffered:
163 entry (p_ci_buffer_ptr, p_number_of_slots, p_element_id, p_code);
164
165 is_buffered = "1"b;
166 is_replacement = "0"b;
167 new_ci_ptr = p_ci_buffer_ptr;
168 go to JOIN;
169
170
171 buffered_replacement:
172 entry (p_ci_buffer_ptr, p_number_of_slots, p_element_id, p_code);
173
174 is_buffered = "1"b;
175 is_replacement = "1"b;
176 new_ci_ptr = p_ci_buffer_ptr;
177 go to JOIN;
178 ^L
179 JOIN:
180 p_code, code = 0;
181 element_id_string = p_element_id;
182
183 if element_id.control_interval_id = 0
184 then ci_length_in_bytes = CONTROL_INTERVAL_ZERO_ADDRESSABLE_LENGTH_IN_BYTES;
185 else ci_length_in_bytes = CONTROL_INTERVAL_ADDRESSABLE_LENGTH_IN_BYTES;
186
187 old_ci_ptr = addr (old_ci);
188
189 if is_buffered
190 then
191 do;
192 call CHECK_CI_VERSION (new_ci_ptr -> basic_control_interval.header.layout_type);
193 unspec (old_ci_ptr -> based_ci) = unspec (new_ci_ptr -> based_ci);
194 unspec (new_ci_ptr -> based_ci) = ""b;
195 end;
196 else
197 do;
198 call file_manager_$simple_get (p_file_opening_id, (element_id.control_interval_id), START_OF_CI_OFFSET,
199 old_ci_ptr, ci_length_in_bytes, code);
200 if code ^= 0
201 then call ERROR_RETURN (code);
202 call CHECK_CI_VERSION (old_ci_ptr -> basic_control_interval.header.layout_type);
203 new_ci_ptr = addr (new_ci);
204 unspec (new_ci_ptr -> based_ci) = "0"b;
205 end;
206
207 basic_control_interval_ptr = null;
208
209 new_datum_offset = ci_length_in_bytes;
210
211 new_ci_ptr -> basic_control_interval.header = old_ci_ptr -> basic_control_interval.header;
212 new_ci_ptr -> basic_control_interval.header.scattered_free_space = 0;
213 new_ci_ptr -> basic_control_interval.header.number_of_datums = p_number_of_slots;
214
215 new_slot_idx = 1;
216 PUT_EACH_DATUM_IN_NEW_CI_LOOP:
217 do old_slot_idx = 1 to hbound (old_ci_ptr -> basic_control_interval.datum_position_table, 1)
218 while (new_slot_idx <= hbound (new_ci_ptr -> basic_control_interval.datum_position_table, 1));
219 if new_slot_idx = element_id.index
220 then
221 do;
222 string (new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).flags) = "0"b;
223 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).offset_in_bytes = FREE_SLOT;
224 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).length_in_bits = 0;
225
226 new_slot_idx = new_slot_idx + 1;
227 if ^is_replacement
228 then if old_ci_ptr -> basic_control_interval.datum_position_table (old_slot_idx).offset_in_bytes
229 ^= FREE_SLOT
230 then old_slot_idx = old_slot_idx - 1;
231
232
233 end;
234 else if old_ci_ptr -> basic_control_interval.datum_position_table (old_slot_idx).offset_in_bytes = FREE_SLOT
235 then
236 COPY_FREE_SLOT:
237 do;
238 string (new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).flags) = "0"b;
239 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).offset_in_bytes = FREE_SLOT;
240 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).length_in_bits = 0;
241
242 new_slot_idx = new_slot_idx + 1;
243 end COPY_FREE_SLOT;
244 else
245 COPY_OLD_DATUM:
246 do;
247 datum_length_in_bytes =
248 ceil (
249 divide (old_ci_ptr -> basic_control_interval.datum_position_table (old_slot_idx).length_in_bits,
250 BITS_PER_BYTE, 35, 18));
251
252 new_datum_offset = new_datum_offset - datum_length_in_bytes;
253
254 old_datum_offset =
255 old_ci_ptr -> basic_control_interval.datum_position_table (old_slot_idx).offset_in_bytes;
256 substr (new_ci_ptr -> based_ci, new_datum_offset + 1, datum_length_in_bytes) =
257 substr (old_ci_ptr -> based_ci, old_datum_offset + 1, datum_length_in_bytes);
258
259 string (new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).flags) =
260 string (old_ci_ptr -> basic_control_interval.datum_position_table (old_slot_idx).flags);
261 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).offset_in_bytes =
262 new_datum_offset;
263 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).length_in_bits =
264 old_ci_ptr -> basic_control_interval.datum_position_table (old_slot_idx).length_in_bits;
265
266 new_slot_idx = new_slot_idx + 1;
267
268 end COPY_OLD_DATUM;
269 end PUT_EACH_DATUM_IN_NEW_CI_LOOP;
270
271 INIT_NEW_FREE_SLOTS:
272 do new_slot_idx = new_slot_idx to element_id.index - 1;
273
274 string (new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).flags) = "0"b;
275 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).offset_in_bytes = FREE_SLOT;
276 new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).length_in_bits = 0;
277
278 end INIT_NEW_FREE_SLOTS;
279
280 if element_id.index = new_slot_idx
281 then new_ci_ptr -> basic_control_interval.datum_position_table (new_slot_idx).offset_in_bytes = FREE_SLOT;
282
283 new_ci_ptr -> basic_control_interval.header.start_of_used_space = new_datum_offset;
284
285 if ^is_buffered
286 then
287 do;
288 call file_manager_$simple_put (p_file_opening_id, (element_id.control_interval_id), START_OF_CI_OFFSET,
289 new_ci_ptr, ci_length_in_bytes, code);
290 if code ^= 0
291 then call ERROR_RETURN (code);
292 p_basic_control_interval_header_ptr -> basic_control_interval.header =
293 new_ci_ptr -> basic_control_interval.header;
294 end;
295
296 MAIN_RETURN:
297 return;
298
299
300 ERROR_RETURN:
301 proc (er_p_code);
302
303 dcl er_p_code fixed bin (35);
304
305 p_code = er_p_code;
306 go to MAIN_RETURN;
307
308 end ERROR_RETURN;
309 %page;
310 CHECK_CI_VERSION:
311 proc (ccv_p_given_version);
312
313 dcl ccv_p_given_version char (4) aligned;
314
315 if ccv_p_given_version ^= BASIC_CI_LAYOUT_1
316 then call sub_err_ (dm_error_$unimplemented_ci_version, myname, ACTION_CANT_RESTART, null, 0,
317 "^/Expected version ""^4a"" control interval; received ""^4a"".", BASIC_CI_LAYOUT_1, ccv_p_given_version);
318
319 return;
320
321
322 end CHECK_CI_VERSION;
323 %page;
324 %include dm_cm_basic_ci;
325 %page;
326 %include dm_cm_basic_ci_const;
327 %page;
328 %include dm_element_id;
329 %page;
330 %include dm_ci_lengths;
331 %page;
332 %include sub_err_flags;
333
334 end cm_compact;