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 ^L
124
125
126 cm_delete:
127 proc (p_file_opening_id, p_collection_id, p_element_id, p_zero_on_free, p_code);
128
129
130
131
132
133 dcl p_cm_info_ptr ptr;
134 dcl p_file_opening_id bit (36) aligned;
135 dcl p_collection_id bit (36) aligned;
136 dcl p_element_id bit (36) aligned;
137 dcl p_zero_on_free bit (1) aligned;
138 dcl p_code fixed bin (35);
139
140
141
142 dcl code fixed bin (35);
143 dcl 1 automatic_bci_header aligned like bci_header;
144 dcl 1 automatic_datum_slot aligned like datum_slot;
145 dcl 1 my_ci_parts aligned,
146 2 number_of_ci_parts fixed bin init (0),
147 2 pad fixed bin init (0),
148 2 part (2) like ci_parts.part;
149
150 dcl continuation_datum_id_string
151 bit (36) aligned init ("0"b);
152 dcl next_element_id_string bit (36) aligned init ("0"b);
153
154 dcl is_ordered_esm bit (1) aligned init ("0"b);
155
156 dcl first_free_slot_idx fixed bin (17);
157 dcl slot_idx fixed bin (17);
158 dcl st_number_of_slots fixed bin (17);
159
160
161
162
163 dcl (addr, divide, null, size, unspec)
164 builtin;
165
166
167
168
169 dcl myname init ("cm_delete") char (32) varying int static options (constant);
170 dcl RELATIVE init ("0"b) bit (1) aligned int static options (constant);
171 dcl NEXT_ELEMENT init (1) fixed bin (17) int static options (constant);
172 dcl BITS_PER_BYTE init (9) fixed bin int static options (constant);
173 dcl BYTES_PER_WORD init (4) fixed bin int static options (constant);
174
175
176
177 dcl file_manager_$get entry (bit (36) aligned, fixed bin (27), ptr, fixed bin (35));
178 dcl file_manager_$put entry (bit (36) aligned, fixed bin (27), ptr, fixed bin (35));
179 dcl file_manager_$simple_get
180 entry (bit (36) aligned, fixed bin (27), fixed bin (21), ptr, fixed bin (21),
181 fixed bin (35));
182 dcl sub_err_ entry () options (variable);
183
184
185
186 dcl (
187 dm_error_$end_of_collection,
188 dm_error_$no_element,
189 dm_error_$ci_not_in_collection
190 ) ext fixed bin (35);
191 dcl error_table_$unimplemented_version
192 ext fixed bin (35);
193
194
195 ^L
196
197
198 code = 0;
199 call cm_opening_info$get (p_file_opening_id, p_collection_id, cm_info_ptr, code);
200 if code ^= 0
201 then call ERROR_RETURN (code);
202 else go to JOIN;
203
204
205 info:
206 entry (p_cm_info_ptr, p_element_id, p_zero_on_free, p_code);
207
208 code = 0;
209 cm_info_ptr = p_cm_info_ptr;
210 go to JOIN;
211 %page;
212 JOIN:
213 p_code = 0;
214
215 call CHECK_VERSION ("cm_info", cm_info.version, CM_INFO_VERSION_2);
216
217 collection_header_ptr = cm_info.header_ptr;
218 call CHECK_VERSION ("collection_header", collection_header.version, COLLECTION_HEADER_VERSION_2);
219
220 element_id_string = p_element_id;
221 if element_id.index = 0
222 then call ERROR_RETURN (dm_error_$no_element);
223
224 bci_header_ptr = addr (automatic_bci_header);
225 datum_slot_ptr = addr (automatic_datum_slot);
226
227 call cm_get_bci_header$slot (cm_info.file_oid, bci_header_ptr, datum_slot_ptr, element_id_string, code);
228 if code ^= 0
229 then call ERROR_RETURN (code);
230
231 if bci_header.collection_id ^= cm_info.collection_id
232 then call ERROR_RETURN (dm_error_$ci_not_in_collection);
233
234 if datum_slot.offset_in_bytes = FREE_SLOT | datum_slot.flags.is_continuation
235 then call ERROR_RETURN (dm_error_$no_element);
236
237
238 if collection_header.element_storage_method = ORDERED_ELEMENT_STORAGE_METHOD
239 then is_ordered_esm = "1"b;
240 else is_ordered_esm = "0"b;
241
242 if datum_slot.is_continued
243 then
244 do;
245
246
247
248
249
250
251 continuation_datum_id_string =
252 GET_CONTINUATION ((element_id.control_interval_id), (datum_slot.offset_in_bytes));
253
254 do while (continuation_datum_id_string ^= "0"b);
255
256 call cm_delete_cn_datum (cm_info_ptr, p_zero_on_free, continuation_datum_id_string, code);
257 if code ^= 0
258 then call ERROR_RETURN (code);
259 end;
260
261 end;
262
263 st_number_of_slots = bci_header.number_of_datums;
264
265 BEGIN_BLOCK:
266 begin;
267
268 dcl 1 slot_table aligned,
269 2 slot (st_number_of_slots) like datum_slot;
270
271 ci_parts_ptr = addr (my_ci_parts);
272 ci_parts.number_of_parts = 1;
273 call GET_SLOT_TABLE (cm_info.file_oid, (element_id.control_interval_id), addr (slot_table), st_number_of_slots,
274 ci_parts_ptr);
275
276 if ^is_ordered_esm
277 then
278 do;
279
280
281
282
283 call cm_get_id$id (cm_info.file_oid, cm_info.collection_id, element_id_string, NEXT_ELEMENT, RELATIVE,
284 next_element_id_string, code);
285 if code ^= 0
286 then if code = dm_error_$end_of_collection
287 then code = 0;
288 else call ERROR_RETURN (code);
289 end;
290
291 if is_ordered_esm
292 then
293 do;
294
295
296
297
298 do slot_idx = element_id.index to bci_header.number_of_datums - 1;
299 slot_table.slot (slot_idx) = slot_table.slot (slot_idx + 1);
300 end;
301 unspec (slot_table.slot (slot_idx)) = "0"b;
302 bci_header.number_of_datums = bci_header.number_of_datums - 1;
303
304 end;
305 else
306 unspec (slot_table.slot (element_id.index)) = "0"b;
307
308
309 do slot_idx = bci_header.number_of_datums to 1 by -1 while (unspec (slot_table.slot (slot_idx)) = "0"b);
310 end;
311
312
313 if ^is_ordered_esm & slot_idx <= 0
314 then
315 FREE_ENTIRE_CI:
316 do;
317
318
319
320 call cm_free_ci$info (cm_info_ptr, (element_id.control_interval_id), p_zero_on_free, code);
321 if code ^= 0
322 then call ERROR_RETURN (code);
323 end FREE_ENTIRE_CI;
324 else
325 UPDATE_CI:
326 do;
327
328
329
330
331
332
333
334 bci_header.number_of_datums = slot_idx;
335
336 do first_free_slot_idx = 1 to bci_header.number_of_datums
337 while (unspec (slot_table.slot (first_free_slot_idx)) ^= ""b);
338 end;
339 if first_free_slot_idx < bci_header.number_of_datums
340 then bci_header.flags.free_slot_is_present = "1"b;
341 else bci_header.flags.free_slot_is_present = "0"b;
342
343 call PUT_HEADER_AND_SLOTS (cm_info.file_oid, bci_header_ptr, datum_slot_ptr,
344 (element_id.control_interval_id), ci_parts_ptr);
345
346 end UPDATE_CI;
347 end BEGIN_BLOCK;
348
349 if ^is_ordered_esm
350 then p_element_id = next_element_id_string;
351
352 MAIN_RETURN:
353 return;
354 %page;
355 ERROR_RETURN:
356 proc (er_p_code);
357
358 dcl er_p_code fixed bin (35);
359
360 p_code = er_p_code;
361 go to MAIN_RETURN;
362
363 end ERROR_RETURN;
364 %page;
365 CHECK_VERSION:
366 proc (cv_p_structure_name, cv_p_given_version, cv_p_correct_version);
367
368 dcl cv_p_structure_name char (*);
369 dcl cv_p_given_version char (8) aligned;
370 dcl cv_p_correct_version char (8) aligned;
371
372 if cv_p_given_version ^= cv_p_correct_version
373 then call sub_err_ (error_table_$unimplemented_version, myname, ACTION_CANT_RESTART, null, 0,
374 "^/Expected version ^8a of ^a structure; received ^8a.", cv_p_correct_version, cv_p_structure_name,
375 cv_p_given_version);
376 else return;
377
378 end CHECK_VERSION;
379 %page;
380 PUT_HEADER_AND_SLOTS:
381 proc (phas_p_file_opening_id, phas_p_bci_header_ptr, phas_p_datum_slot_ptr, phas_p_control_interval_id,
382 phas_p_ci_parts_ptr);
383
384 dcl phas_p_file_opening_id bit (36) aligned;
385 dcl phas_p_bci_header_ptr ptr;
386 dcl phas_p_datum_slot_ptr ptr;
387 dcl phas_p_control_interval_id
388 fixed bin (27);
389 dcl phas_p_ci_parts_ptr ptr;
390 dcl phas_code fixed bin (35);
391
392 phas_code = 0;
393
394 if phas_p_datum_slot_ptr -> datum_slot.offset_in_bytes = phas_p_bci_header_ptr -> bci_header.start_of_used_space
395 then phas_p_bci_header_ptr -> bci_header.start_of_used_space =
396 phas_p_bci_header_ptr -> bci_header.start_of_used_space
397 + BITS_TO_BYTES ((phas_p_datum_slot_ptr -> datum_slot.length_in_bits));
398 else phas_p_bci_header_ptr -> bci_header.scattered_free_space =
399 phas_p_bci_header_ptr -> bci_header.scattered_free_space
400 + BITS_TO_BYTES ((phas_p_datum_slot_ptr -> datum_slot.length_in_bits));
401
402
403 phas_p_ci_parts_ptr -> ci_parts.number_of_parts = 2;
404 phas_p_ci_parts_ptr -> ci_parts.part (2).offset_in_bytes = 0;
405 phas_p_ci_parts_ptr -> ci_parts.part (2).length_in_bytes = size (bci_header) * BYTES_PER_WORD;
406 phas_p_ci_parts_ptr -> ci_parts.part (2).local_ptr = phas_p_bci_header_ptr;
407
408 call file_manager_$put (phas_p_file_opening_id, phas_p_control_interval_id, phas_p_ci_parts_ptr, phas_code);
409 if phas_code ^= 0
410 then call ERROR_RETURN (phas_code);
411 else return;
412
413 end PUT_HEADER_AND_SLOTS;
414 %page;
415 BITS_TO_BYTES:
416 proc (btb_p_bits) returns (fixed bin (17));
417
418 dcl btb_p_bits fixed bin (35);
419
420 return (divide (btb_p_bits + BITS_PER_BYTE - 1, BITS_PER_BYTE, 17, 0));
421
422 end BITS_TO_BYTES;
423 %page;
424 GET_CONTINUATION:
425 proc (gc_p_ci, gc_p_offset) returns (bit (36) aligned);
426
427
428
429
430
431
432 dcl gc_p_ci fixed bin (27);
433 dcl gc_p_offset fixed bin (21);
434 dcl 1 gc_continued_datum_header
435 aligned like continued_datum.header;
436 dcl gc_code fixed bin (35);
437
438 call file_manager_$simple_get (cm_info.file_oid, gc_p_ci, gc_p_offset, addr (gc_continued_datum_header),
439 (size (gc_continued_datum_header) * BYTES_PER_WORD), gc_code);
440 if gc_code ^= 0
441 then call ERROR_RETURN (gc_code);
442 else return (unspec (gc_continued_datum_header.continuation));
443
444
445 end GET_CONTINUATION;
446 %page;
447 GET_SLOT_TABLE:
448 proc (gst_p_file_oid, gst_p_control_interval_id, gst_p_slot_table_ptr, gst_p_slot_table_length_in_words,
449 gst_p_ci_parts_ptr);
450
451 dcl gst_p_file_oid bit (36) aligned;
452 dcl gst_p_control_interval_id
453 fixed bin (27);
454 dcl gst_p_slot_table_ptr ptr;
455 dcl gst_p_slot_table_length_in_words
456 fixed bin (17);
457 dcl gst_p_ci_parts_ptr ptr;
458
459 dcl gst_code fixed bin (35);
460
461 gst_p_ci_parts_ptr -> ci_parts.number_of_parts = 1;
462 gst_p_ci_parts_ptr -> ci_parts.part (1).offset_in_bytes = size (bci_header) * BYTES_PER_WORD;
463 gst_p_ci_parts_ptr -> ci_parts.part (1).length_in_bytes = gst_p_slot_table_length_in_words * BYTES_PER_WORD;
464 gst_p_ci_parts_ptr -> ci_parts.part (1).local_ptr = gst_p_slot_table_ptr;
465
466 call file_manager_$get (gst_p_file_oid, gst_p_control_interval_id, gst_p_ci_parts_ptr, gst_code);
467 if gst_code ^= 0
468 then call ERROR_RETURN (gst_code);
469 else return;
470
471
472 end GET_SLOT_TABLE;
473 %page;
474 %include dm_cm_datum;
475 %page;
476 %include dm_cm_info;
477 %page;
478 %include dm_cm_basic_ci;
479 %page;
480 %include dm_cm_basic_ci_const;
481 %page;
482 %include dm_cm_collection_header;
483 %page;
484 %include dm_element_id;
485 %page;
486 %include dm_esm_info;
487 %page;
488 %include dm_ci_parts;
489 %page;
490 %include dm_cm_entry_dcls;
491 %page;
492 %include sub_err_flags;
493
494 end cm_delete;