|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 14592 (0x3900)
Types: TextFile
Names: »tcfexample «
└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code
└─⟦75ff9bef3⟧
└─⟦this⟧ »tcfexample «
CF-SYSTEM Programming example.
begin
comment
This an example of an algol 6 program which creates 2
master files: master_1 and master_2, and one listfile:
list.
2 chain groups: chain_1 and chain_2, are associated to
master_1 and list, and to master_2 and list respective-
ly.
A rudimentary description file: descrfile, sufficient
for the check of version numbers performed by the cf
protection system is also created.
Various functions are performed on the file configura-
tion.
;
procedure check_one;
comment gives a case alarm if result_cf <> 1;
case result_cf of begin end;
procedure printtime(text);
string text;
comment
prints the time consumed since last call;
begin
own boolean later_call;
own real cpubase, timebase;
real cpu, time;
if later_call then
begin
cpu:= systime(1, timebase, time) - cpubase;
write(out, <:<10>:>, text, <: in seconds, cpu::>,
<<dddd.dd>, cpu, <:, real::>, time);
end later_call
else later_call:= true;
cpubase:= systime(1, 0, timebase);
end printtime;
printtime(<::>); blocks_read:= 0;
begin
comment
block for creation of file heads;
integer
file_no,
fixed_rec_length,
i,
max_blocks,
max_bucks,
max_rec_length,
min_rec_length,
no_of_keys,
segs_per_block,
segs_per_buck;
integer array
chains(1:(2*4)),
rec_descr(1:4, 1:2),
size_l, size_m(1:4);
comment
initialize array chains:
chain group mother daughter chain type compr.key
1 1 100 headed see head_m
2 2 100 headed see head_m
;
for i:= 1 step 1 until 2*4 do
chains(i):= case i of(
1, 100, 1, 0,
2, 100, 1, 0);
comment
the fourth field in each line above, compressed keysize, is
initialized by head_m, and used by head_l.
(from the record description below it can be seen to be 8
bytes).
create the head of master_1;
file_no:= 1;
comment
initialize the record description:
keyfield type order address
1 long ascending 4
2 byte descending 11
3 word ascending 10
length fixed
;
no_of_keys:= 3;
for i:= 1 step 1 until (no_of_keys + 1) * 2 do
rec_descr((i+1)//2, 2-i mod 2):= case i of(
+3, 4,
-1, 11,
+2, 10,
0, 0);
comment
initialize size parameters;
size_m(1):= max_rec_length:= 120;
size_m(2):= max_bucks:= 100;
size_m(3):= segs_per_buck:= 40;
size_m(4):= segs_per_block:= 2;
comment
create the file head, the backing store area: master1,
must exist;
head_m(<:master1:>, file_no, chains, rec_descr, no_of_keys,
size_m);
comment
for simplicity, the same parameters are used for master_2;
file_no:= 2;
head_m(<:master2:>, file_no, chains, rec_descr, no_of_keys,
size_m);
comment
create the description file head;
file_no:= 1000;
comment
initialize the record description according to appendix E:
keyfield type order address
1 long ascending 12
2 long ascending 16
3 long ascending 20
length word - 2
;
no_of_keys:= 3;
for i:= 1 step 1 until (no_of_keys + 1) * 2 do
rec_descr((i+1)//2, 2 - i mod 2):= case i of(
+3, 12,
+3, 16,
+3, 20,
2, 2);
comment
initialize size_m, the description file is regarded as
being a small file;
size_m(1):= max_rec_length:= 100;
size_m(2):= max_bucks:= 50;
size_m(3):= segs_per_buck:= 10;
comment
never choose a smaller value for segs_per_buck;
size_m(4):= segs_per_block:= 1;
head_m(<:descrfile:>, file_no, chains, rec_descr, no_of_keys,
size_m);
comment
create the listfile head:
variable record length, minimum about 20 bytes;
file_no:= 100;
size_l(1):= fixed_rec_length:= 0;
size_l(2):= min_rec_length:= 20;
size_l(3):= segs_per_block:= 1;
size_l(4):= max_blocks:= 2000;
head_l(<:list:>, file_no, chains, size_l);
end block for the creation of file heads;
printtime(<:file heads created :>);
begin
comment
block for initialization of master files.
master_1, and master_2 are provided with a dummy record
having all fields equal to zero, because open_cf requires
that a master file contains at least one record.
the description file is initialized with 4 file description
records;
zone
zm1(buflength_cf(<:master1:>, 1), 3, stderror),
zm2(buflength_cf(<:master2:>, 1), 3, stderror),
zdescr(buflength_cf(<:descrfile:>, 1), 3, stderror);
integer
file_no;
integer field
descr_length;
long field
descr_key_1,
descr_key_2,
descr_key_3,
l_fld;
real array
rec(1:50);
comment
initialize the field variables for the description file;
descr_length:= 2;
descr_key_1:= 12;
descr_key_2:= 16;
descr_key_3:= 20;
comment
set all fields of array rec to zero;
for l_fld:= 4 step 4 until 200 do rec.l_fld:= 0;
comment
initialize master_1 with one record having all fields
equal to zero;
init_file_m(zm1, <:master1:>, 0, 1, 1);
init_rec_m(zm1, rec);
checkone;
comment
this procedure checks that result_cf was one, see the
procedure declaration at the beginning of the program;
close_cf(zm1, true);
comment
the same is done for master_2;
init_file_m(zm2, <:master2:>, 0, 1, 1);
init_rec_m(zm2, rec);
checkone;
close_cf(zm2, true);
comment
initialize the description file with 4 records, describing
the files including the description file itself;
init_file_m(zdescr, <:descrfile:>, 0, 1, 1);
for file_no:= 1, 2, 100, 1000 do
begin
comment
the file numbers of master_1, master_2, list, and
descr_file;
rec.descr_length:= 30;
rec.descr_key_1:= 2;
rec.descr_key_2:= file_no;
rec.descr_key_3:= 0;
init_rec_m(zdescr, rec);
checkone;
comment
the version numbers are zero in the description records as
well as in the catalog entries of the corresponding files,
if the files were created by set in this way:
master1= set 120, etc. just before the call of this
program;
end for file_no;
close_cf(zdescr, true);
comment
the list file needs no initialization;
end block for initialization;
printtime(<:files initialized :>);
begin
comment
block for processing of the file configuration:
200 records are inserted in both master files, at random
keys, and 1000 list records are connected to records
in both files via chain group 1 and chain group 2;
zone
zm1(buflength_cf(<:master1:>, 2) + 10*12//4, 3, stderror),
zm2(buflength_cf(<:master2:>, 2) + 10*12//4, 3, stderror),
zl(buflength_cf(<:list:>, 3) + 100//8, 4, stderror);
comment
the addition to buflength_cf provides for extra bufferlength
for extensions of the files during the processing: 10 extra
buckets for the master files, and 100 extra blocks for the
listfile.
the factor 12 in the expression for the master zone buffer
length is equal to compressed_keysize + 4, see appendix G;
integer
i,
ic_mode;
integer field
length,
m_key_3;
long field
l_fld;
real
chain_ref_1,
chain_ref_2;
real array
m_rec, l_rec(1:50);
procedure create_key;
comment
this procedure generates a pseudo random master key
in array m_rec;
begin
own integer ps_random;
random(ps_random);
m_rec.m_key_3:= ps_random mod 10000;
end create_key;
comment
initialize the field variables;
length:= 2; comment the length field of list records;
m_key_3:= 10; comment see the file head creation;
comment
this call provides the cf-system with the name of the
description file;
open_cf(zm1, <:master1:>, 0);
checkone;
open_cf(zm2, <:master2:>, 0);
checkone;
open_cf(zl, <:list:>, 0);
comment
the version numbers and the update marks have been checked,
and the zone states are read_only;
read_upd_cf(zm1);
read_upd_cf(zm2);
read_upd_cf(zl);
comment
now the zone states are read_update, insertions are allowed,
and the update marks are set in the catalog entries;
init_chain(zm1, zl, 1, chain_ref_1);
init_chain(zm2, zl, 2, chain_ref_2);
comment
the 2 chain groups are ready for processing, the chain_refs
are used to reference them;
for l_fld:= 4 step 4 until 200 do
m_rec.l_fld:= l_rec.l_fld:= 0;
for i:= 1 step 1 until 10 do
begin
comment
insert 200 master records in master_1, with random values
of keyfield 3, and the other fields equal to zero;
make_a_key:
create_key;
insert_m_rec:
insert_m(zm1, m_rec);
case result_cf of
begin
comment 1, ok, do nothing;
;
comment 2, record exists already, try another key;
goto make_a_key;
comment 3, not inserted, too expensive.
this is not possible when param_cf has not been used
to change the insertion parameters;
checkone;
comment 4, the file is full, extend the file with one
bucket = 40 segments;
begin
extend_cf(zm1, 40);
checkone;
goto insert_m_rec;
end 4;
comment 5, length error, not possible with fixed length;
checkone;
comment 6, no buffer, not possible because result_cf has
been checked after open_cf and extend_cf;
checkone
end case result_cf;
end insertion of 200 records in master_1;
comment
insert 200 records in master_2 in a more crude way;
for i:= 1 step 1 until 10 do
begin
create_key;
insert_m(zm2, m_rec);
case result_cf of
begin
comment 1, ok;
;
comment 2, exists already, repeat;
i:= i - 1
end case result_cf;
comment
other results will give a case alarm;
end insertion of 200 records in master_2;
printtime(<:master recs inserted:>);
for i:= 1 step 1 until 50 do
begin
comment
insert 1000 list records connected to random master
records.
the list records are clustered in chain group 1, i.e.,
insert_l works upon chain_ref_1;
create_key;
get_m(zm1, m_rec);
comment
the result is ignored, there will always be a current
record in a master file;
comment
insert a list record as the last in the chain_1 depar-
ting from the current master_1 record.
insertion as the first in chain is faster, but
it does not demonstrate the use of get_l;
get_l(zl, chain_ref_1, 1);
comment
read the first record in this chain, if any;
ic_mode:= if result_cf = 1 then 2 else 1;
comment
insert mode is next to last accessed, if there is any
record in the chain, else next to mother;
for i:= i while result_cf = 1 do get_l(zl, chain_ref_1, 2);
comment
read all records in the chain, last accessed in chain
group 1 is now the last in chain, if any;
l_rec.length:= 30;
insert_l_rec:
insert_l(zl, chain_ref_1, ic_mode, l_rec);
case result_cf of
begin
comment 1, ok, do nothing;
;
comment 2, fill limit exceeded, extend the file with
20 blocks = 20 segments;
begin
extend_the_file:
extend_cf(zl, 20);
checkone;
goto insert_l_rec;
end 2;
comment 3, length error;
checkone;
comment 4, no block can take this record;
goto extend_the_file
end case result_cf;
comment
connect the list record to a random master_2 record, as
first in chain;
create_key;
get_m(zm2, m_rec);
ic_mode:= 1; comment connect next to mother;
connect(zl, chain_ref_1, chain_ref_2, ic_mode);
checkone;
end insert 1000 list records;
comment
master_1 is not updated any more;
read_only_cf(zm1);
printtime(<:list recs inserted :>);
comment
go through all chains of chain group 2, at the same time
look up the master_1 record being the mother of the chain
1 passing through each list record, and at last delete the
list record.
the list records are counted, to check that all 1000 have
been deleted;
comment
master_2 is read by means of next_m, starting at the dummy
record created by init_rec_m;
m_rec.m_key_3:= 0;
get_m(zm2, m_rec);
checkone;
i:= 0;
for i:= i while result_cf = 1 do
begin
comment
read the first record in the chain_1 departing from the
current record of master_2;
get_l(zl, chain_ref_2, 1);
for i:= i while result_cf = 1 do
begin
get_head(zl, chain_ref_1, m_rec);
checkone;
comment
now m_rec contains the key of the record, which is the
mother of the chain_1 passing through the current list
record;
get_m(zm1, m_rec);
checkone;
comment
the calls of get_head and get_m above are performed
as a demonstration of how each list record acts as a
link between a record in master_2 and a record in mas-
ter_1;
delete_l(zl, chain_ref_2);
i:= i + 1;
comment
delete and count the list file record, delete will
access the next record in chain_2, if any;
end reading and deleting of one chain;
next_m(zm2);
comment
read the next master_2 record;
end reading of master_2;
if i <> 1000 then
write(out, <:<10>***error in count :>, i);
close_cf(zm1, true);
close_cf(zm2, true);
close_cf(zl, true);
end block for processing of file configuration;
printtime(<:list records deleted:>);
write(out, <:<10>blocks read: :>, blocks_read);
end program
▶EOF◀