4 ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
\r
5 º m o d u l o b s l u g i º
\r
8 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
\r
10 zadaniem modulu jest zrealizowanie systemu wspolpracy z
\r
11 relacjami i krotkami: modul opisuje te pojecia i definiuje
\r
12 operacje na nich: insert, delete, make etc.*)
\r
15 (***************************************************)
\r
17 (* Assumptions on file system *)
\r
19 (* The module handling relations assumes a file *)
\r
20 (* system of random access files. The signature *)
\r
21 (* of file system consists of four sorts: *)
\r
24 (* S - file's names, *)
\r
25 (* N - nonnegative integers *)
\r
26 (* and several operations and predicates, *)
\r
27 (* makefile : S x N -> P *)
\r
28 (* openfile : S x N -> P *)
\r
29 (* closefile : P -> P *)
\r
30 (* isopen? : P -> B0 *)
\r
31 (* frewind : P -> P *)
\r
32 (* feof : P -> B0 *)
\r
33 (* fput : P x R -> P *)
\r
35 (* fseek : P x N -> P *)
\r
36 (* position : P -> N *)
\r
37 (* filelen : P -> N *)
\r
39 (* which satisfy the following properties *)
\r
41 (* isopen?(makefile(s,n)) *)
\r
42 (* position(makefile(s,n)) = 1 *)
\r
43 (* feof(p) <=> (position(p) = filelen(p)) *)
\r
44 (* ªisopen?(closefile(p)) *)
\r
45 (* position(frewind(p)) = 1 *)
\r
46 (* k<filelen(p) => position(fseek(p,k)) = k *)
\r
48 (* isopen?(p) => (p':=fput(p,r))(k:=position(p')) *)
\r
49 (* (p":=fseek(p',k-1)) (r':=fget(p")) (r =r') *)
\r
51 (* isopen?(p) => (p':=frewind(p)) *)
\r
52 (* (while ªfeof(p') do r:= fget(p') od) true *)
\r
54 (* position(p) ó filelen(p) *)
\r
56 (*** * * * * * * * * * * * * * * * * * * * * * * ***)
\r
58 unit FileSystem: class;
\r
59 (* system plikow bezposredniego dostepu *)
\r
62 (************************************************************)
\r
63 (* T Y P Y D A N Y C H *)
\r
64 (************************************************************)
\r
67 (* plik jest ciagiem ponumerowanych rekordow
\r
68 jednakowej dlugosci *)
\r
70 var name: arrayof char (* nazwa zewnetrzna *),
\r
71 opened: boolean (* czy otwarty *),
\r
72 reclen (* dlugosc rekordu - w slowach *),
\r
73 (* rozmiar slowa odpowiada rozmiarowi
\r
74 liczby typu integer *)
\r
75 position (* numer biezacego rekordu *),
\r
76 length: integer (* dlugosc pliku -
\r
77 numer pozycji nastepnej po
\r
78 ostatniej zajetej *),
\r
79 plik: file (* plik bezposredniego dostepu *),
\r
80 next, prev: Rfile (* wszystkie pliki w systemie
\r
81 sa powiazane w liste
\r
86 var system: Rfile; (* dowiazanie do straznika listy plikow *)
\r
92 (******************************************************************)
\r
93 (******************************************************************)
\r
97 (*****************************************************************)
\r
98 (* P R O C E D U R Y I F U N K C J E *)
\r
99 (* S Y S T E M U P L I K O W *)
\r
100 (*****************************************************************)
\r
104 (******************************)
\r
105 (* A U X I L I A R Y *)
\r
106 (******************************)
\r
110 unit FindInSystem: function
\r
111 ( name:arrayof char): Rfile ;
\r
113 unit equalstring: function
\r
114 (s1, s2: arrayof char): boolean;
\r
115 var i1, i2, len, i: integer;
\r
118 writeln(" 1st parameter in equalstring=none");
\r
121 writeln(" 2nd parameter in equalstring=none");
\r
123 i1 := lower(s1); i2 := lower(s2);
\r
124 len := upper(s1) - i1 + 1;
\r
125 if len =/= upper(s2) - i2 + 1
\r
128 do if s1(i1) =/= s2(i2)
\r
137 begin system.name := name;
\r
139 while not equalstring( name, p.name )
\r
141 if (p = system) then result := none
\r
142 else result := p fi;
\r
145 (*********************************)
\r
147 unit AddToSystem: function
\r
148 (name: arrayof char): Rfile;
\r
150 result := new Rfile;
\r
151 result.name := name;
\r
152 result.next := system.next;
\r
153 result.prev := system;
\r
154 system.next.prev := result;
\r
155 system.next := result;
\r
158 (*********************************)
\r
160 unit DeleteFromSystem: procedure
\r
163 if p = system then return fi;
\r
164 p.next.prev := p.prev;
\r
165 p.prev.next := p.next
\r
166 end DeleteFromSystem;
\r
168 (********************************)
\r
170 unit FindFileLength: function
\r
171 (p: file, recl:integer): integer;
\r
173 (* odtwarza dlugosc istniejacego pliku,
\r
174 recl - dlugosc rekord w slowach *)
\r
176 var record: arrayof integer, i:integer;
\r
179 write(" FS - FindFileLength - ");
\r
180 writeln("file object does not exist");
\r
185 array record dim (1:recl);
\r
188 getrec(p,record,i);
\r
189 if i =/= recl*intsize then exit fi;
\r
190 result := result + 1;
\r
192 end FindFileLength;
\r
199 (*****************************************************************)
\r
201 (* M A K E F I L E *)
\r
203 (* utworzenie i dolaczenie do systemu nowego pliku
\r
204 o zadanej nazwie i dlugosci rekordu *)
\r
208 unit makefile: function
\r
209 ( name: arrayof char (* nazwa zewnetrzna pliku *),
\r
210 reclen: integer (* dlugosc rekordu pliku *) ): Rfile;
\r
213 if FindInSystem(name) =/= none
\r
214 (* istnieje w systemie plik o tej nazwie *)
\r
216 writeln(" FS - makefile - file name duplicated");
\r
220 writeln(" FS - makefile - record length should be possitive");
\r
222 result := AddToSystem(name);
\r
223 result.opened := true;
\r
224 result .reclen := reclen;
\r
225 result.position := 1;
\r
226 result.length := 1;
\r
227 open (result.plik, direct, name);
\r
228 call rewrite(result.plik);
\r
232 (***************************************************************)
\r
234 (* O P E N F I L E *)
\r
236 (* otwarcie i ewentualne dolaczenie do systemu
\r
237 pliku o zadanej nazwie zewnetrznej i rozmiarze
\r
242 unit openfile: function
\r
243 (name: arrayof char (* nazwa zewnetrzna pliku *),
\r
244 reclen: integer (* dlugosc rekordu pliku *) ): Rfile;
\r
249 writeln(" FS - openfile - record length should be possitive");
\r
251 result := FindInSystem(name);
\r
252 if result = none then result := AddToSystem(name) fi;
\r
253 result.opened := true;
\r
254 result.reclen := reclen;
\r
255 result.position := 1;
\r
256 open(result.plik, direct, name);
\r
257 result.length := FindFileLength(result.plik,reclen);
\r
258 if result.length = 1 then call rewrite(result.plik)
\r
259 else call reset(result.plik) fi;
\r
263 (***************************************************************)
\r
265 (* C L O S E F I L E *)
\r
267 (* zamkniecie pliku z usunieciem obiektu pliku ;
\r
268 obiekt typu Rfile pozostaje w systemie z odpowiednia
\r
272 unit closefile: procedure (p:Rfile);
\r
276 writeln(" FS - closefile - closing nonexisting file");
\r
280 writeln(" FS - closefile - closing not opened file");
\r
282 p. opened := false;
\r
288 (****************************************************************)
\r
292 (* sprawdzenie, czy plik jest otwarty *)
\r
295 unit isopen: function( p:Rfile): boolean;
\r
299 writeln(" FS - isopen - testing nonexisting file");
\r
305 (****************************************************************)
\r
307 (* F R E W I N D *)
\r
309 (* przewiniecie pliku do poczatku *)
\r
312 unit frewind: procedure( p:Rfile);
\r
316 writeln(" FS - frewind - rewinding nonexisting file");
\r
320 writeln(" FS - frewind - rewinding net opened file");
\r
327 (**************************************************************)
\r
331 (* test, czy koniec pliku *)
\r
334 unit feof: function(p: Rfile): boolean;
\r
338 writeln(" FS - feof - testing nonexisting file");
\r
342 writeln(" FS - feof - testing not opened file");
\r
344 result := ( p.position >= p.length )
\r
348 (**************************************************************)
\r
352 (* wlozenie rekordu na plik w miejsce wskazane przez
\r
353 atrybut position *)
\r
357 unit fput: procedure( p: Rfile, Record: arrayof integer);
\r
359 var ile, i : integer;
\r
363 writeln(" FS - fput - file does not exist"); i:= inchar;
\r
367 writeln(" FS - fput - file not opened");
\r
369 if p.position > p.length
\r
371 writeln(" FS - fput - try to access after file length");
\r
375 writeln(" FS - fput - record does not exist");
\r
377 ile := upper(Record) - lower(Record) + 1;
\r
378 if ile =/= p.reclen
\r
380 writeln(" FS - fput - wrong record length");
\r
382 i := ile * intsize;
\r
383 putrec(p.plik, Record, i);
\r
384 if i =/= ile * intsize
\r
386 writeln(" FS - fput - error during writing ");
\r
388 p.position := p.position + 1;
\r
389 if p.position > p.length then p.length := p.position fi;
\r
393 (**************************************************************)
\r
397 (* odczytanie rekordu z pliku z miejsca wskazywanego
\r
398 przez atrybut position *)
\r
401 unit fget: function( p: Rfile): arrayof integer;
\r
402 var Record: arrayof integer,
\r
407 writeln(" FS - fget - file does not exist ");
\r
411 writeln(" FS - fget - file not opened");
\r
413 if p.position >= p.length
\r
415 writeln(" FS - fget - try to read past eof");
\r
418 array Record dim (1:ile);
\r
419 i := ile * intsize;
\r
420 getrec(p.plik, Record, i);
\r
421 if i =/= ile * intsize
\r
423 writeln(" FS - fget - error during reading");
\r
425 p.position := p.position + 1;
\r
431 (*************************************************************)
\r
435 (* wyszukanie w pliku rekordu o zadanym numerze -
\r
436 ustawienie atrybutu position *)
\r
440 unit fseek: procedure( p: Rfile, nrrec: integer);
\r
442 var offset: integer;
\r
446 writeln(" FS - fseek - file does not exist");
\r
450 writeln(" FS - fseek - file not opened");
\r
454 writeln(" FS - fseek - record number should be positive");
\r
456 if nrrec > p.length
\r
458 writeln(" FS - fseek - try to access after file length");
\r
460 p.position := nrrec;
\r
461 offset := (nrrec - 1) * p.reclen * intsize;
\r
462 call seek(p.plik, offset, 0)
\r
467 (************************************************************)
\r
469 (* P O S I T I O N *)
\r
471 (* answeres the current position of file pointer *)
\r
474 unit position: function( p: Rfile): integer;
\r
478 writeln(" FS - position - checking nonexisting file");
\r
482 writeln(" FS - position - checking not opened file");
\r
484 result := p.position
\r
488 (************************************************************)
\r
490 (* F I L E L E N *)
\r
492 (* gives the file length - the number of position
\r
493 immediately after the last one *)
\r
496 unit filelen: function( p: Rfile): integer;
\r
500 writeln(" FS - filelen - checking nonexisting file");
\r
504 writeln(" FS - filelen - checking not opened file");
\r
510 (**************************************************************)
\r
511 (**************************************************************)
\r
520 begin (* of FileSystem *)
\r
521 system := new Rfile;
\r
522 system.next, system.prev := system;
\r
525 (***************************************************************)
\r
526 (* Pakiet Grafiki Blokowej *)
\r
531 (***************************************************************)
\r
532 unit Bold : procedure;
\r
534 write( chr(27), "[1m")
\r
537 unit Blink : procedure;
\r
539 write( chr(27), "[5m")
\r
542 unit Reverse : procedure;
\r
544 write( chr(27), "[7m")
\r
547 unit Normal : procedure;
\r
549 write( chr(27), "[0m")
\r
552 unit Underscore : procedure;
\r
554 write( chr(27), "[4m")
\r
559 unit inchar : IIuwgraph function : integer;
\r
560 (*podaj nr znaku przeslanego z klawiatury *)
\r
565 if i <> 0 then exit fi;
\r
570 unit NewPage : procedure;
\r
572 write( chr(27), "[2J")
\r
575 unit SetCursor : procedure(row, column : integer);
\r
576 var c,d,e,f : char,
\r
583 i := column div 10;
\r
584 j := column mod 10;
\r
587 write( chr(27), "[", c, d, ";", e, f, "H")
\r
589 h(***************************************************************)
\r
590 (* koniec Grafiki *)
\r
591 (***************************************************************)
\r
593 unit HandlerOfRelations : FileSystem class(PageSize: integer,
\r
594 TreeHeight: integer,
\r
595 HalfPageSize : integer) ;
\r
596 signal signal8, (*przekroczono wysokosc TreeHeight *)
\r
597 signal14, (*dwa identyczne klucze o jednakowych ref*)
\r
598 Signal13; (*sygnal usuwania nieobecnego rekordu*)
\r
599 signal Signal11, (*nie ma poprzednika w PrevKey*)
\r
600 Signal12; (*nie ma nastepnika w NextKey*)
\r
604 (*klasa prefiksujaca wszystkie klasy wykorzystywane w
\r
610 (* unit ObjectToRec : function (n : Node) : arrayof integer;
\r
613 unit RecToObject : function(a: arrayof integer) : Node;
\r
616 (*struktura logiczna
\r
626 | _______________________ | *)
\r
630 (********************************************
\r
641 ********************************************)
\r
643 unit DataFile : Node class;
\r
644 (*typ DataFile jest wspolnym prefiksem dla Atrybut i
\r
645 Relation i IndexFile. Ten typ umo*liwia operacje
\r
646 Wstaw Rekord, UsunRekord etc. *)
\r
648 var FreePlace : integer; (* pozycja wolnego miejsca
\r
652 unit Reset : procedure ;
\r
654 call fseek(plik,1);
\r
657 unit AddRec : procedure (input Record:arrayof integer;
\r
658 output RefRec:integer);
\r
659 (*Procedura wstawia rekord Record do DataFile i zwraca
\r
660 jego pozycje w pliku wykorzystujac przy tym informacje o
\r
661 wolnych miejscach zapamietana na stosie FreePlace*)
\r
663 var AuxRec: arrayof integer;
\r
665 array AuxRec dim(lower(Record):upper(Record));
\r
668 RefRec:=FileLen(plik);
\r
669 (*jesli nie bylo usunietych rekordow, to Record
\r
670 zapiszemy na koncu pliku*)
\r
673 call fseek(plik,RefRec);
\r
674 AuxRec:=fget(plik);(*odczytanie pozycji poprzed
\r
675 niego wolnego miejsca, ktore
\r
676 bedzie teraz aktualnym wolnym miejscem*)
\r
677 FreePlace:=AuxRec(1);
\r
679 call fseek(plik,RefRec);
\r
680 call fput(plik,Record)
\r
683 unit DelRec: procedure(input DataRef: integer);
\r
684 (*Procedura usuwa rekord wskazany przez DataRef i wpisuje
\r
685 na jego miejsce referencje do ostatniego wolnego miejsca.
\r
686 Pozycja usunietego rekordu jest zapamietana na stosie
\r
689 var AuxRec: arrayof integer;
\r
691 call fseek(plik,DataRef);
\r
692 array AuxRec dim (1 : plik.reclen);
\r
693 AuxRec(1):=FreePlace;
\r
694 call fput(plik,AuxRec);
\r
695 FreePlace:=DataRef;
\r
698 unit FindRec:procedure(input Record:arrayof integer;
\r
699 output RefRec : integer);
\r
700 (*Procedura FindRec odszukuje rekord wskazany przez Record
\r
701 i zwraca jego pozycje w pliku*)
\r
702 var equal :boolean,
\r
704 AuxRec: arrayof integer;
\r
706 array AuxRec dim(lower(Record): upper(Record));
\r
709 while (not feof(plik) and not equal)
\r
711 RefRec := position(plik);
\r
712 AuxRec:= fget(plik);
\r
713 for i:=lower(AuxRec) to upper(AuxRec)
\r
715 equal:= AuxRec(i)=Record(i);
\r
716 if not equal then exit fi
\r
717 od (*koniec porownywania rekordow*);
\r
718 (* czy znaleziony jest usunietym wczesniej rekordem? *)
\r
719 if (equal and FreePlace <> 0)
\r
729 call fseek(plik,Place);
\r
730 AuxRec:=fget(plik);
\r
734 call fseek(plik,RefRec+plik.reclen);
\r
739 RefRec:=-1(*nie znalezlismy rekordu*)
\r
749 ********************************************
\r
761 ********************************************
\r
763 unit Relation : DataFile class ;
\r
764 var Index :arrayof IndexFile;
\r
766 unit Tuple : Node class;
\r
767 (*element relacji*)
\r
770 unit virtual TupleToRec : function (t : Tuple): arrayof
\r
774 unit virtual RecToTuple : function(a : arrayof integer):
\r
780 unit Insert: procedure (t: Tuple);
\r
781 var i,PageRef,DataRef:integer;
\r
782 var AuxRec : arrayof integer;
\r
784 AuxRec:=TupleToRec(t);
\r
785 call AddRec(AuxRec, DataRef);
\r
788 for i:=1 to upper(Index)
\r
792 call Index(i).AddKey(Index(i).KeyOf(t),DataRef)
\r
798 unit Delete : procedure (t: Tuple);
\r
799 var i,DataRef :integer,
\r
800 AuxRec : arrayof integer;
\r
803 then (*najpierw szukamy w indeksach i usuwamy tam*)
\r
804 for i:=1 to upper(Index)
\r
806 if none <> Index(i)
\r
808 DataRef := Index(i).FindKey(Index(i).KeyOf(t));
\r
809 call Index(i).DelKey(Index(i).KeyOf(t),DataRef);
\r
814 else (*brak indeksu*)
\r
815 AuxRec := TupleToRec(t);
\r
816 call FindRec(AuxRec, DataRef);
\r
820 raise Signal13 (*proba usuniecia rekordu ktorego nie ma*)
\r
822 call DelRec(DataRef) ; (*wstawic na liste usuniec*)
\r
827 (* ********************************************
\r
844 ********************************************
\r
847 unit IndexFile : DataFile coroutine;
\r
850 unit SearchStep: class;
\r
851 var PageRef,RefOnPage : integer,
\r
855 unit Item : class ;
\r
856 var ky: key, PageRef: integer, DataRef: integer;
\r
857 (* item jest jednostka ( rekordem) przechowywana w
\r
858 indeksie na stronie tzn.Page
\r
861 PageRef - informacje o stronie na ktorej znajduje sie
\r
862 korzen poddrzewa z kluczami wiekszymi od klucza kl,
\r
863 a mniejszymi od kluczy podporzadkowanych sasiadowi z
\r
865 DataRef - informacja w ktorym rekordzie zapisano
\r
866 krotke odpowiadajaca naszemu kluczowi ky*)
\r
870 var ItemsOnPage, (*ilu synow ma ta strona +1*)
\r
871 LessPageRef: integer; (*wskaznik do poddrzewa elementow
\r
872 mniejszych od pierwszego klucza na tej stronie*)
\r
873 var ItemsArray: arrayof Item;
\r
875 array ItemsArray dim (1:PageSize)
\r
878 var KeySize: integer;
\r
880 unit key : Node class ;
\r
881 (*definicja klucza zgodnie z zyczeniem uzytkownika*)
\r
885 var StackOfPages: arrayof Page;
\r
886 var Finger: integer; (*zmienne StackOfPages i Finger
\r
887 implementuja stos stron*)
\r
888 var Path: arrayof SearchStep; (*zmienne Path i Finger
\r
889 implementuja sciezke*)
\r
891 (* axiom: nr strony wskazanej przez Finger w StackOfPages jest
\r
892 identyczny z numerem strony wskazanym przez Finger w Path*)
\r
894 unit virtual KeyOf : function (t : Tuple) : key;
\r
895 (*KeyOf tworzy z dowolnej krotki klucz zaleznie od
\r
896 rozwazanego indeksu*)
\r
899 unit virtual Leq: function (k1,k2 : key):Boolean;
\r
900 (* Leq sprawdza czy krotki k1,k2 sa w relacji
\r
901 obowiazujacej w rozwazanym indeksie
\r
902 zakladamy, ze jest to relacja antysymetryczna*)
\r
906 unit AddKey : procedure (input ky:key,DataRef:integer);
\r
907 (*wstawienie klucza ky i referencji DataRef do indexu w odpowiednie
\r
908 miejsce w B-drzewie
\r
909 DataRef jest adresem rekordu ktory odpowiada kluczowi
\r
911 var depth, (*aktualna glebokosc stosu stron*)
\r
914 AddItem, AuxItem, itm2 : Item,
\r
915 IncreaseHeight : boolean,
\r
917 AuxRec : arrayof integer;
\r
919 unit Search : procedure (input itm1 : Item, PageRef :
\r
921 output include : boolean, itm2 :
\r
923 (*szukaj poczawszy od strony PageRef, miejsca dla itm1;
\r
924 jezeli nie znajdzie miejsca na tej stronie to
\r
925 rekurencyjnie szuka na nastepnej odpowiedniej az do
\r
927 jezeli include to WSTAWIA obiekt itm2*)
\r
935 unit Insert : procedure;
\r
936 (*wstawia obiekt itm2 na strone PageRef w miejscu ItemRef*)
\r
937 var OldPage, RightPage : Page,
\r
938 AuxRec : arrayof integer,
\r
940 AuxItmArr2 : arrayof Item,
\r
944 OldPage := StackOfPages(Finger);
\r
945 if OldPage.ItemsOnPage < PageSize
\r
946 then (*jest miejsce na tej stronie *)
\r
947 call UpdatePage (item2, ItemRef, OldPage);
\r
948 Path(Finger).RefOnPage := ItemRef + 1;
\r
950 else (*strona jest pelna dokonujemy podzialu *)
\r
952 OldPage.ItemsOnPage := HalfPageSize;
\r
953 Path(Finger).updated := true;
\r
954 RightPage := new Page;
\r
955 RightPage.ItemsOnPage := HalfPageSize;
\r
956 array RightPage.ItemsArray dim (1:PageSize);
\r
957 AuxItmArr := OldPage.ItemsArray;
\r
958 AuxItmArr2 := RightPage.ItemsArray;
\r
959 if ItemRef = HalfPageSize
\r
960 then (*obiekt itm2=item2 idzie do gory*)
\r
961 for i := 1 to HalfPageSize
\r
963 AuxItmArr2(i):=AuxItmArr(i+HalfPageSize)
\r
966 else (*to nie item2 idzie do gory *)
\r
967 if ItemRef < HalfPageSize
\r
968 then (*wstawiamy do lewej strony*)
\r
969 for i := 1 to HalfPageSize
\r
972 AuxItmArr(i+HalfPageSize)
\r
974 itm2 := AuxItmArr(HalfPageSize);
\r
975 for i := HalfPageSize-1 downto ItemRef+1
\r
980 AuxItmArr(ItemRef+1) := item2;
\r
981 else (*ItemRef>HalfPageSize *)
\r
982 itm2 := AuxItmArr(HalfPageSize+1);
\r
983 for i := HalfPageSize+2 to ItemRef
\r
985 AuxItmArr2(i-HalfPageSize-1) :=
\r
988 AuxItmArr2(ItemRef-HalfPageSize)
\r
991 for i := ItemRef+1 to PageSize
\r
993 AuxItmArr2(i-HalfPageSize) :=
\r
996 fi (*ItemRef < HalfPageSize *)
\r
997 fi (*ItemRef = HalfPagSize *);
\r
998 (*****) (* StackOfPages(finger) := OldPage; *)
\r
999 call fseek(plik,Path(Finger).PageRef);
\r
1000 call fput(plik,PageToRec(StackOfPages(Finger)));
\r
1001 RightPage.LessPageRef := itm2.PageRef;
\r
1002 AuxRec :=PageToRec(RightPage);
\r
1003 call AddRec(AuxRec,RightPageRef);
\r
1004 itm2.PageRef :=RightPageRef;
\r
1012 then (*poprzednia strona jest lisciem, nalezy do niej
\r
1013 wstawic itm1 ale z PageRef = -1*)
\r
1016 itm2.PageRef := -1;
\r
1017 else (*przeszukaj te strone*)
\r
1018 Finger, depth := Finger+1;
\r
1019 call GetPage (PageRef);
\r
1020 AuxPage := StackOfPages (Finger);
\r
1021 call SearchPage (AuxPage, itm1, NextPageRef, ItemRef);
\r
1022 call Search(itm1, NextPageRef, include, item2);
\r
1024 then (*wstawic obiekt item2 na strone PageRef w miejsce
\r
1025 ItemRef; jezeli na tej stronie wystarczy miejsca
\r
1026 na nowy obiekt to wstawic go i zgasic include;
\r
1027 jezeli brakuje miejsca to strone dzielimy i
\r
1028 include pozostawiamy zapalone, nowy item itm2 ma
\r
1029 byc wstawiony na wyzszej stronie *)
\r
1032 Finger := Finger -1;
\r
1033 fi (*PageRef=-1*);
\r
1038 (*szukaj w korzeniu i powtarzaj rekurencyjnie w odp.
\r
1039 poddrzewach, gdy znajdziesz to sygnal blad
\r
1040 w przeciwnym przypadku*)
\r
1041 Path(1).updated := true;
\r
1042 AuxItem := new Item;
\r
1044 AuxItem.DataRef := DataRef;
\r
1045 AuxItem.PageRef := -1;
\r
1047 call Search(AuxItem, Path(1).PageRef,
\r
1048 IncreaseHeight, AddItem);
\r
1050 then (*korzen podzielony, dodajemy nowy korzen*)
\r
1051 NewRoot := new Page;
\r
1052 NewRoot.ItemsOnPage := 1;
\r
1053 NewRoot.LessPageRef := Path(1).PageRef;
\r
1054 (*adres prawej czesci starego korzenia*)
\r
1055 array NewRoot.ItemsArray dim (1:PageSize);
\r
1056 NewRoot.ItemsArray(1) := AddItem;
\r
1057 if depth+1 > TreeHeight
\r
1058 then (*przekroczono dopuszczalna wysokosc drzewa*)
\r
1061 for i := 1 to depth
\r
1063 StackOfPages(i+1) := StackOfPages(i);
\r
1064 Path(i+1) := Path(i);
\r
1066 StackOfPages(1) := NewRoot;
\r
1067 Path(1) := new SearchStep;
\r
1068 Path(1).RefOnPage := 1;
\r
1069 Path(1).updated := true;
\r
1070 AuxRec :=PageToRec(NewRoot);
\r
1071 call AddRec(AuxRec, PageRef);
\r
1072 Path(1).PageRef := PageRef (*adres nowego korzenia*) ;
\r
1073 Finger := depth+1;
\r
1076 fi (*IncreaseHeight*);
\r
1083 (*AXIOM po wykonaniu dowolnej operacji zmieniajacej Finger
\r
1084 Finger i Path pokazuja na sciezce jakis item w ktorym jest
\r
1085 klucz tzn. item dla ktorego RefOnPage =/= 0*)
\r
1087 unit PrevKey : procedure (output ky:key, DataRef:integer);
\r
1088 (*ky jest bezposrednim poprzednikiem klucza biezacego
\r
1089 wskazanego przez Path. DataRef wskazuje referencje do
\r
1090 krotki odpowiadajacej ky w pliku danych*)
\r
1091 var AuxPage : Page,
\r
1092 AuxRec : arrayof integer,
\r
1093 PageRef, nextPageRef,
\r
1094 RefOnPage : integer;
\r
1095 begin (*Zakladamy, ze biezacy klucz jest wskazany przez
\r
1097 RefOnPage := Path(Finger).RefOnPage;
\r
1098 PageRef:=Path(Finger).PageRef;
\r
1099 AuxPage:=StackOfPages(Finger);
\r
1100 if AuxPage.LessPageRef = -1
\r
1101 then (*jestesmy w lisciu*)
\r
1103 then (*poprzednikiem jest sasiad z lewej*)
\r
1104 RefOnPage := RefOnPage -1;
\r
1105 Path(Finger).RefOnPage := RefOnPage
\r
1106 else (*RefOnPage = 1*)
\r
1108 then (*to jest korzen*)
\r
1109 ky:=AuxPage.ItemsArray(RefOnPage).ky;
\r
1110 DataRef:=AuxPage.ItemsArray(RefOnPage).DataRef;
\r
1111 raise signal11; (*nie ma poprzednika*)
\r
1115 while Finger <> 1 and RefOnPage = 0
\r
1117 Finger := Finger-1;
\r
1118 Auxpage := StackOfPages(Finger);
\r
1119 RefOnPage := Path(Finger).RefOnPage
\r
1121 if Finger = 1 and RefOnPage = 0
\r
1123 ky:=AuxPage.ItemsArray(1).ky;
\r
1124 DataRef:=AuxPage.ItemsArray(1).DataRef;
\r
1125 raise signal11; (*nie ma poprzednika*)
\r
1128 fi (* Finger = 1 *);
\r
1129 fi (* RefOnPage <> 1 *);
\r
1130 else (*to nie jest lisc*)
\r
1133 nextPageRef := AuxPage.LessPageRef;
\r
1134 Path(Finger).RefOnPage := 0
\r
1136 RefOnPage := RefOnPage -1;
\r
1137 nextPageRef := AuxPage.ItemsArray(RefOnPage).PageRef;
\r
1138 Path(Finger).RefOnPage := RefOnPage
\r
1140 while nextPageRef <> -1 (*szukamy najwiekszego syna*)
\r
1142 Finger := Finger +1;
\r
1143 PageRef := nextPageRef;
\r
1144 call GetPage(PageRef);
\r
1145 AuxPage := StackOfPages(Finger);
\r
1146 RefOnPage, Path(Finger).RefOnPage :=
\r
1147 Auxpage.ItemsOnPage;
\r
1148 nextPageRef := AuxPage.ItemsArray(RefOnPage).PageRef
\r
1151 ky:=AuxPage.ItemsArray(RefOnPage).ky;
\r
1152 DataRef:=AuxPage.ItemsArray(RefOnPage).DataRef
\r
1156 unit MinKey : procedure (output k:Key, DataRef : integer);
\r
1157 (*ustawia Pointer do indexu i Path tak by pokazywaly
\r
1158 najmniejszy klucz. k - jest najmniejszym kluczem w
\r
1159 rozwazanym indeksie, DataRef jest odpowiadajaca mu
\r
1160 referencja do rekordu w pliku glownym relacji*)
\r
1162 var PageRef : integer,
\r
1169 AuxPage := StackOfPages(Finger);
\r
1170 PageRef := AuxPage.LessPageRef;
\r
1171 Path(Finger).RefOnPage := 0;
\r
1172 if PageRef = -1 then exit fi;
\r
1173 Finger := Finger +1;
\r
1174 call GetPage(PageRef);
\r
1176 AuxItem := AuxPage.ItemsArray(1);
\r
1178 DataRef := AuxItem.DataRef;
\r
1179 Path(Finger).RefOnPage := 1;
\r
1183 unit MaxKey : procedure( output k:Key, DataRef: integer);
\r
1184 (*ustawia Pointer do indexu i Path tak by pokazywaly
\r
1185 najwiekszy klucz*)
\r
1186 var PageRef, n : integer,
\r
1192 AuxPage := StackOfPages(Finger);
\r
1193 Path(Finger).RefOnPage, n :=
\r
1194 AuxPage.ItemsOnPage ;
\r
1195 PageRef := AuxPage.ItemsArray(n).PageRef;
\r
1196 if PageRef = -1 then exit fi;
\r
1197 Finger := Finger+1;
\r
1198 call GetPage(PageRef);
\r
1200 k := AuxPage.ItemsArray(n).Ky;
\r
1201 DataRef := AuxPage.ItemsArray(n).DataRef;
\r
1207 (*************************************************************************)
\r
1210 unit NextKey: procedure (output ky:key,DataRef:integer);
\r
1211 (*referencja DataRef do bezposredniego nastepnika biezacej
\r
1213 ky jest bezposrednim nastepnikiem klucza biezacego
\r
1214 wskazanego przez Path. DataRef wskazuje referencje do
\r
1215 krotki odpowiadajacej ky w pliku danych*)
\r
1216 var AuxPage : Page,
\r
1218 PageRef,nextPageRef,
\r
1219 RefOnPage : integer;
\r
1220 begin (*Zakladamy, ze biezacy klucz jest wskazany przez
\r
1222 RefOnPage := Path(Finger).RefOnPage;
\r
1223 PageRef := Path(Finger).PageRef;
\r
1224 AuxPage:=StackOfPages(Finger);
\r
1226 if AuxPage.LessPageRef = -1
\r
1227 then (*jestesmy w lisciu*)
\r
1228 while Finger <> 1 and RefOnPage = AuxPage.ItemsOnPage
\r
1230 Finger := Finger - 1;
\r
1231 AuxPage := StackOfPages(Finger);
\r
1232 RefOnPage := Path(Finger).refOnPage
\r
1234 if RefOnPage = AuxPage.ItemsOnPage
\r
1236 AuxItem := AuxPage.ItemsArray(RefOnPage);
\r
1237 DataRef := AuxItem.DataRef;
\r
1239 raise signal12; (*nie ma nastepnika*)
\r
1242 RefOnPage := RefOnPage+1;
\r
1243 Path(Finger).RefOnPage := RefOnPage
\r
1245 else (*to nie jest lisc*)
\r
1246 nextPageRef := AuxPage.ItemsArray(RefOnPage).PageRef;
\r
1247 while nextPageRef <> -1
\r
1249 Finger := Finger+1;
\r
1250 PageRef := NextPageRef;
\r
1251 call GetPage(PageRef);
\r
1252 AuxPage := StackOfPages(Finger);
\r
1253 Path(Finger).refOnPage := 0;
\r
1254 NextPageRef := AuxPage.LesspageRef
\r
1257 Path(Finger).RefOnPage := 1
\r
1259 AuxItem := AuxPage.ItemsArray(RefOnPage);
\r
1260 DataRef := AuxItem.DataRef;
\r
1265 unit DelKey : procedure (input ky:key,DataRef:integer);
\r
1266 (*usuwanie klucza ky, o referencji do pliku glownego
\r
1267 dataref, z indeksu, jezeli takiego klucza nie ma to
\r
1269 var DataRef1: integer,
\r
1271 underflw:boolean; (*true if underflow occurred*)
\r
1273 unit remove : procedure(output underflw:boolean);
\r
1274 var AuxPage,AuxPage1 :Page,
\r
1275 i,ItemsOnPage,RefOnPage,nextPageRef :integer;
\r
1277 AuxPage:=StackOfPages(Finger);
\r
1279 Path(Finger).updated:=true;
\r
1280 RefOnPage := Path(Finger).RefOnPage;
\r
1282 if AuxPage.LessPageRef <> -1
\r
1283 then (*to nie jest lisc*)
\r
1285 AuxPage.ItemsArray(RefOnPage).PageRef;
\r
1286 while NextPageRef <> -1
\r
1288 Finger := Finger+1;
\r
1289 call GetPage(NextPageRef);
\r
1290 AuxPage1 := StackOfPages(Finger);
\r
1291 Path(Finger).RefOnPage := 0;
\r
1292 NextPageRef := AuxPage1.LessPageRef
\r
1294 Path(Finger).updated:=true;
\r
1295 Path(Finger).RefOnPage := 1;
\r
1296 AuxPage.ItemsArray(RefOnPage).ky:=
\r
1297 AuxPage1.ItemsArray(1).ky;
\r
1298 AuxPage.ItemsArray(RefOnPage).DataRef:=
\r
1299 AuxPage1.ItemsArray(1).DataRef;
\r
1300 StackOfPages(i):=AuxPage;(*wymienilam usuniety element*)
\r
1301 AuxPage:= AuxPage1;
\r
1303 fi;(*jestesmy w lisciu*)
\r
1305 ItemsOnPage:= AuxPage.ItemsOnPage -1;
\r
1307 for i:=RefOnPage to ItemsOnPage
\r
1309 AuxPage.ItemsArray(i):=AuxPage.ItemsArray(i+1)
\r
1311 AuxPage.ItemsOnPage:= ItemsOnPage;
\r
1312 StackOfPages(Finger):=AuxPage;
\r
1313 if ItemsOnPage<HalfPageSize
\r
1314 then (*trzeba wywolac underflow*)
\r
1319 unit underflow: procedure(inout underflw:boolean);
\r
1320 (* Finger wskazuje strone A na ktorej jest niedomiar *)
\r
1322 AuxPage,AuxPage1, AuxPage2:Page,
\r
1323 i,k,n,pb,lb,PageRef,RefOnPage: integer,
\r
1324 AuxRec: arrayof integer;
\r
1326 call SetCursor(7,1); (*****************************)
\r
1327 writeln("underflow",Finger);
\r
1330 AuxPage:=StackOfPages(Finger);(*strona z niedomiarem*)
\r
1332 Path(Finger).updated:=true ;
\r
1333 Path(Finger-1).updated:=true ;
\r
1334 AuxPage1:=StackOfPages(Finger-1); (*strona ojca*)
\r
1335 RefOnPage:=Path(Finger-1).RefOnPage;
\r
1336 if RefOnPage< AuxPage1.ItemsOnPage
\r
1337 then (*istnieje prawy stryj*)
\r
1339 Itm:=AuxPage1.ItemsArray(k);
\r
1340 PageRef:=Itm.PageRef;
\r
1341 (*wczytanie strony-brata prawego na AuxPage2*)
\r
1342 call fseek(plik,PageRef);
\r
1343 AuxRec:=fget(plik);
\r
1344 AuxPage2:=RecToPage(AuxRec);
\r
1346 Itm.PageRef:=AuxPage2.LessPageRef;
\r
1347 AuxPage.ItemsArray(AuxPage.ItemsOnPage+1):=Itm;
\r
1348 (*stryj schodzi do AuxPage*)
\r
1349 n:=AuxPage2.ItemsOnPage-HalfPageSize;
\r
1353 n:=entier((n-1)/2);(* przelewamy n elementow *)
\r
1354 Itm:=AuxPage2.ItemsArray(n+1);
\r
1355 Itm.PageRef:=PageRef;
\r
1356 AuxPage1.ItemsArray(k):=Itm;
\r
1359 AuxPage.ItemsArray(HalfPageSize+i):=
\r
1360 AuxPage2.ItemsArray(i)
\r
1362 AuxPage.ItemsOnPage:=HalfPageSize+n;
\r
1363 StackOfPages(Finger):=AuxPage;
\r
1364 StackOfPages(Finger-1):=AuxPage1;
\r
1365 k:=AuxPage2.ItemsOnPage-(n+1);
\r
1369 AuxPage2.ItemsArray(i):=
\r
1370 AuxPage2.ItemsArray(n+1+i)
\r
1372 AuxPage2.ItemsOnPage:=k;
\r
1373 AuxRec:=PageToRec(AuxPage2);(*zapamiet. AuxPage2*)
\r
1374 call fseek(plik,PageRef);
\r
1375 call fput(plik,AuxRec);
\r
1377 (*AuxPage2.ItemsOnPage=HalfPageSize tzn. n=0*)
\r
1378 for i:=1 to HalfPageSize
\r
1380 AuxPage.ItemsArray(HalfPageSize+i):=
\r
1381 AuxPage2.ItemsArray(i)
\r
1383 AuxPage.ItemsOnPage:=PageSize;
\r
1384 for i:=RefOnPage+2 to AuxPage1.ItemsOnPage
\r
1386 AuxPage1.ItemsArray(i-1):=
\r
1387 AuxPage1.ItemsArray(i)
\r
1390 AuxPage1.ItemsOnPage:=AuxPage1.ItemsOnPage-1;
\r
1391 StackOfPages(Finger-1):=AuxPage1;
\r
1392 StackOfPages(Finger):=AuxPage;
\r
1393 call DelRec(PageRef);
\r
1394 if AuxPage1.ItemsOnPage<HalfPageSize
\r
1398 (*niedomiar na stronie ojca*)
\r
1402 else (*nie ma prawego stryja, wez z lewej*)
\r
1405 Itm:=AuxPage1.ItemsArray(RefOnPage-1);
\r
1406 PageRef:=Itm.PageRef;
\r
1408 PageRef:=AuxPage1.LessPageRef;
\r
1410 (*wczytanie strony-brata lewego na AuxPage2*)
\r
1411 call fseek(plik,PageRef);
\r
1412 AuxRec:=fget(plik);
\r
1413 AuxPage2:=RecToPage(AuxRec); (*str-brat lewy*)
\r
1415 Itm:=AuxPage1.ItemsArray(RefOnPage);
\r
1416 Itm.PageRef:=AuxPage.LessPageRef;
\r
1417 n:=AuxPage2.ItemsOnPage-HalfPageSize;
\r
1420 n:=entier((n-1)/2);
\r
1421 (*przesun o n+1 w prawo elem na str.AuxPage*)
\r
1422 k:=AuxPage.ItemsOnPage;
\r
1425 AuxPage.ItemsArray(k+n+2-i):=
\r
1426 AuxPage.ItemsArray(k+1-i)
\r
1429 AuxPage.ItemsArray(n+1):=Itm;
\r
1430 (*ojciec do AuxPage*)
\r
1431 AuxPage.ItemsOnPage:=k+n+1;
\r
1432 Itm:=AuxPage2.ItemsArray(HalfPageSize+n+1);
\r
1433 Itm.PageRef:=PageRef; (*referencja do AuxPage*)
\r
1434 AuxPage1.ItemsArray(RefOnPage):=Itm;
\r
1437 AuxPage.ItemsArray(i):=
\r
1438 AuxPage2.ItemsArray(HalfPageSize+1+i+n)
\r
1440 AuxPage.ItemsOnPage:=HalfPageSize+n;
\r
1441 AuxPage2.ItemsOnPage:= HalfPageSize+n;
\r
1443 (*wyslac strony i zapisac sciezke i stos*)
\r
1444 StackOfPages(Finger-1):=AuxPage1;
\r
1445 StackOfPages(Finger):=AuxPage;
\r
1446 (*zapamietanie strony AuxPage2*)
\r
1447 AuxRec:=PageToRec(AuxPage2);
\r
1448 call fseek(plik,PageRef);
\r
1449 call fput(plik,AuxRec);
\r
1452 (*n=o tzn.AuxPage2.ItemsOnPage=HalfPageSize*)
\r
1454 AuxPage2.ItemsArray(HalfPageSize+1):=Itm;
\r
1455 for i:=1 to HalfPageSize-1
\r
1457 AuxPage2.ItemsArray(HalfPageSize+1+i):=
\r
1458 AuxPage.ItemsArray(i)
\r
1460 AuxPage1.ItemsOnPage:=AuxPage1.ItemsOnPage-1;
\r
1461 AuxPage2.ItemsOnPage:=PageSize;
\r
1462 StackOfPages(Finger-1):=AuxPage1;
\r
1463 StackOfPages(Finger):=AuxPage2;
\r
1464 Path(Finger-1).RefOnPage:=RefOnPage-1;
\r
1465 call DelRec(Path(Finger).PageRef);
\r
1466 (*wyrzucono str AuxPage*)
\r
1467 Path(Finger).PageRef:=PageRef;
\r
1469 if AuxPage1.ItemsOnPage<HalfPageSize
\r
1472 underflw:=true (*niedomiar na stronie ojca*)
\r
1476 fi(*lewy istnieje*)
\r
1479 else (*niedomiar jest w korzeniu*)
\r
1480 AuxPage:=StackOfPages(1);
\r
1481 if AuxPage.ItemsOnPage=0
\r
1483 call DelRec(Path(1).PageRef);
\r
1484 if AuxPage.LessPageRef<>-1
\r
1487 while Path(i)<>none
\r
1489 Path(i-1):=Path(i);
\r
1490 StackOfPages(i-1):=StackOfPages(i);
\r
1494 writeln("drzewo znika ");
\r
1502 DataRef1:=FindKey(k);
\r
1504 if k=ky and DataRef=DataRef1
\r
1506 (*znalezlismy wlasciwy klucz *)
\r
1507 call remove(underflw);
\r
1510 call underflow(underflw)
\r
1514 if k<>ky or DataRef1= -1
\r
1516 writeln("* nie ma takiego klucza *")
\r
1518 call NextKey(k,DataRef1)
\r
1525 unit FindKey:function (k : key): integer;
\r
1526 (*wynikiem poszukiwania klucza k jest referencja do
\r
1527 datafile wskazujaca na krotke o danym kluczu. Gdy
\r
1528 nie znaleziono, wartoscia funkcji jest -1 *)
\r
1532 Itms : arrayof Item,
\r
1536 PageRef := Path(Finger).PageRef;
\r
1538 call GetPage( PageRef );
\r
1539 (*przeszukujemy strone o adresie Pageref*)
\r
1540 AuxPage := StackOfPages(Finger);
\r
1541 Itms := AuxPage.ItemsArray;
\r
1542 for i := AuxPage.ItemsOnPage downto 1
\r
1547 Path(Finger).RefOnPage := i;
\r
1549 then (*znaleziony*)
\r
1550 result := Itms(i).DataRef;
\r
1553 PageRef := Itms(i).PageRef;
\r
1557 then (*klucz k jest mniejszy od wszystkich kluczy
\r
1558 na rozwazanej stronie*)
\r
1559 PageRef := AuxPage.LessPageRef;
\r
1560 Path(Finger).RefOnPage := 0;
\r
1566 then (*jestesmy w lisciu, nie ma poszukiwanego klucza*)
\r
1567 if Path(Finger).RefOnPage = 0
\r
1569 Path(Finger).RefOnPage :=1
\r
1574 Finger := Finger+1
\r
1579 unit SearchKey: procedure(input k:key;
\r
1580 output DataRef : integer);
\r
1581 (*referencja do klucza, ktory jest >=k *)
\r
1583 DataRef:=FindKey(k);
\r
1586 call NextKey(k,DataRef)
\r
1592 unit GetPage : procedure(PageRef : integer);
\r
1593 (* wczytanie do stosu stron strony o adresie PageRef,
\r
1594 chyba, ze strona o tej referencji jest juz w stosie.
\r
1595 Poprawienie sciezki i ew. przeslanie do pliku strony
\r
1596 wskazanej przez Path(Finger).PageRef o ile byla zmieniana jej tresc *)
\r
1598 var AuxRec : arrayof integer;
\r
1601 if Path(Finger) = none
\r
1603 Path(Finger) := new SearchStep;
\r
1604 Path(Finger).Updated := false;
\r
1605 Path(Finger).PageRef := PageRef-1; (*chce by byla roznica ponizej *)
\r
1607 (*! if Path(Finger).PageRef <> PageRef
\r
1608 then *) (*zmiana strony *)
\r
1609 if Path(Finger).Updated
\r
1610 then (*wyslanie strony na plik, poniewaz byla zmieniana *)
\r
1611 AuxRec := PageToRec(StackOfPages(Finger));
\r
1612 call fseek(plik, Path(Finger).PageRef);
\r
1613 call fput(plik,AuxRec);
\r
1615 (*wczytanie potrzebnej strony*)
\r
1616 call fseek(plik, PageRef);
\r
1617 AuxRec := fget(plik);
\r
1618 StackOfPages(Finger) := RecToPage(AuxRec);
\r
1619 Path(Finger) := new SearchStep;
\r
1620 Path(Finger).PageRef := PageRef;
\r
1621 Path(Finger).updated := false;
\r
1626 unit UpdatePage : procedure (input AuxItem : Item,
\r
1627 ItemRef : integer,
\r
1629 (* wstaw AuxItem na wskazanej stronie, w miejscu ItemRef +1 *)
\r
1630 var AuxItmArr : arrayof Item,
\r
1633 AuxPage.ItemsOnPage, n := AuxPage.ItemsOnPage +1;
\r
1634 for i := n downto ItemRef +2
\r
1636 AuxItmArr := AuxPage.ItemsArray;
\r
1637 AuxItmArr(i) := AuxItmArr(i-1)
\r
1639 AuxPage.ItemsArray(ItemRef+1) := AuxItem;
\r
1640 Path(Finger).Updated := true;
\r
1643 unit order : function (i1, i2 : Item) : boolean;
\r
1644 (*ropzszerzenie porzadku LessOrEqual Leq o badanie DataRef w
\r
1645 przypadku gdy klucze sa rowne *)
\r
1658 (* DORADZAMY zbadaj czy k1 = k2? *************************)
\r
1659 (* potrzebna inna funkcja EQ? booleowska *****************)
\r
1660 (* o odp. wlasnosciach: zwrotnsc,przechodniosc, symetria *)
\r
1662 n := i1.DataRef - i2.DataRef;
\r
1664 then (*dwa identyczne klucze o jednakowych referencjach*)
\r
1672 if not Leq(k1, k2)
\r
1674 (* 16.08.87 ********************************************)
\r
1675 (* raise RelacjaNieSpojna *)
\r
1682 unit SearchPage : procedure (input P : Page, it : Item;
\r
1683 output NextPageRef, ItemRef : integer);
\r
1684 (* szukamy miejsca dla obiektu it na stronie P, NextPageRef
\r
1685 jest adresem strony na ktorej mozemy kontynuowac
\r
1686 poszukiwania; ItemRef jest numerem obiektu mniejszego od it
\r
1687 lub jest rowne 0 gdy nasz obiekt it jest mniejszy
\r
1688 od wszystkich obiektow na stronie*)
\r
1690 var Itms : arrayof Item,
\r
1694 Itms :=P.ItemsArray;
\r
1695 for ItemRef := P.ItemsOnPage downto 1
\r
1697 it1 := Itms(ItemRef);
\r
1698 if order (it1, it)
\r
1700 NextPageRef := it1.PageRef;
\r
1704 (*obiekt it jest mniejszy od wszystkich obiektow na tej
\r
1707 NextPageRef := P.LessPageRef;
\r
1712 unit RecToPage : function(A: arrayof integer): Page;
\r
1713 (*Ta funkcja odczytuje tablice liczb calkowitych i zmienia
\r
1714 ja w strone Page. Wykorzystuje sie virtualna funkcje
\r
1721 P.ItemsOnPage,j := A(1);
\r
1722 P.LessPageRef := A(2);
\r
1723 array P.ItemsArray dim (1:PageSize);
\r
1724 for i := 1 to j (*P.ItemsOnPage*)
\r
1727 It.ky := RecToKey(A, 3+(i-1)*(KeySize+2) ) ;
\r
1728 It.PageRef := A(i*(KeySize+2)+1);
\r
1729 It.DataRef := A(i*(KeySize+2)+2);
\r
1730 P.ItemsArray(i) := It;
\r
1731 od(*itemsOnPage*);
\r
1735 unit PageToRec : function (P: Page): arrayof integer;
\r
1736 (*Funkcja odwrotna do poprzedniej*)
\r
1737 var A : arrayof integer,
\r
1741 array A dim(1:(2+PageSize*(KeySize+2)));
\r
1742 A(1) :=P.ItemsOnPage;
\r
1743 A(2) := P.LessPageRef;
\r
1744 for i := 1 to P.ItemsOnPage
\r
1746 It:=P.ItemsArray(i);
\r
1747 (* if It = none then writeln(" It w PageToRec jest none");
\r
1748 writeln("ItemsOnPage= ",P.ItemsOnPage,"i= ",i)
\r
1750 call KeyToRec(It.ky, A, 3+(i-1)*(KeySize+2) );
\r
1751 (*O KeyToRec zakladam, ze jest to procedura virtualna,
\r
1752 ktora przepisuje klucz ky do tablicy A poczynajac od
\r
1753 danego miejsca A(j) do kolejnych KeySize komorek tej
\r
1755 A(i*(KeySize+2)+1) := It.PageRef;
\r
1756 A(i*(KeySize+2)+2) := It.DataRef;
\r
1761 unit virtual KeyToRec : procedure(ky:Key, A: arrayof integer, j: integer);
\r
1762 (*procedura virtualna, ktora przepisuje klucz ky do tablicy
\r
1763 A poczynajac od danego miejsca A(j) do kolejnych KeySize
\r
1764 komorek tej tablicy. *)
\r
1770 unit virtual RecToKey : function(A: arrayof integer,
\r
1772 (*Funkcja odczytuje KeySize kolejnych komorek z tablicy A
\r
1773 poczynajac od A(j) i tworzy z nich klucz *)
\r
1779 var AuxRec : arrayof integer,
\r
1781 PageRef : integer;
\r
1783 begin (*IndexFile*)
\r
1784 (*ustawic wskazowke do IndexFile *)
\r
1785 (*zainicjowac Path i StackOfPages*)
\r
1787 array StackOfPages dim(1:TreeHeight);
\r
1788 array Path dim (1:TreeHeight);
\r
1789 StackOfPages(1) := new Page;
\r
1790 StackOfPages(1).ItemsOnPage := 0;
\r
1791 StackOfPages(1).LessPageRef := -1;
\r
1792 array StackOfPages(1).ItemsArray dim (1: PageSize);
\r
1793 Path(1):= new SearchStep;
\r
1794 Path(1).PageRef := 1;
\r
1795 Path(1).RefOnPage := 0;
\r
1803 begin (*Relation*)
\r
1810 begin (*obsluga relacji*)
\r
1812 end HandlerOfRelations;
\r
1815 begin (*to begin odpowiada zewnetrznym : program i end*)
\r
1817 pref HandlerOfRelations(4,8,2) block
\r
1819 unit Bibliografia : Relation class;
\r
1820 (*nasza przykladowa relacja *)
\r
1821 const autleng=25, tytleng=50, wydleng=15;
\r
1823 unit Krotka : Tuple class ;
\r
1826 wydawca : arrayof char,
\r
1828 pozycja : integer;
\r
1830 array autor dim(1 : autleng);
\r
1831 array tytul dim (1 : tytleng);
\r
1832 array wydawca dim (1 :wydleng);
\r
1835 var ak : Krotka; (*aktualna krotka*)
\r
1837 unit virtual TupleToRec : function (k : Krotka): arrayof
\r
1839 var Aux : arrayof integer,
\r
1840 AIC : arrayof char,
\r
1844 array Aux dim (1:95);
\r
1846 for i := 1 to autleng
\r
1848 Aux(i) := ord(AIC(i));
\r
1849 if ord(AIC(i)) = 13
\r
1854 for i := 1 to tytleng
\r
1856 Aux(autleng+i) := ord(k.tytul(i));
\r
1857 if ord(k.tytul(i)) = 13
\r
1862 for i := 1 to wydleng
\r
1864 Aux(75+i) := ord(k.wydawca(i));
\r
1865 if ord(k.wydawca(i)) = 13
\r
1871 Aux(92) := k.pozycja;
\r
1875 unit virtual RecToTuple : function (a: arrayof integer)
\r
1882 for i:=1 to autleng
\r
1884 k.autor(i):=chr(a(i));
\r
1886 then (*koniec tekstu *)
\r
1890 for i:=1 to tytleng
\r
1892 k.tytul(i):=chr(a(autleng+i));
\r
1893 if a(autleng+i) = 13
\r
1894 then (*koniec tekstu *)
\r
1898 for i := 1 to wydleng
\r
1900 k.wydawca(i):=chr(a(75+i));
\r
1902 then (*koniec tekstu *)
\r
1911 unit DrukujKrotke : procedure;
\r
1912 (*drukuj aktualna krotke *)
\r
1914 call SetCursor(4,1);
\r
1919 call SetCursor(10,1);
\r
1920 write(" autor: ");
\r
1921 call SetCursor(10,14);
\r
1922 call Drukuj(ak.autor); writeln;
\r
1923 write(" tytul: ");
\r
1924 call SetCursor(11,14);
\r
1925 call Drukuj(ak.tytul); writeln;
\r
1926 write(" wydawca: ");
\r
1927 call SetCursor(12,14);
\r
1928 call Drukuj(ak.wydawca); writeln;
\r
1929 writeln("rok wydania: ",ak.rok);
\r
1930 writeln(" pozycja nr: ",ak.pozycja);
\r
1931 end DrukujKrotke ;
\r
1933 unit WczytajKrotke : procedure;
\r
1934 (*Czytaj aktualna krotke *)
\r
1936 call SetCursor(25,1);
\r
1937 write("edit tuple, pressing PgDn finishes ");
\r
1940 call SetCursor(4,1);
\r
1941 writeln; call Reverse;
\r
1942 write(" autor: "); call Normal;
\r
1943 call Czytaj(ak.autor); call Reverse;
\r
1944 write(" tytul: "); call Normal;
\r
1945 call Czytaj(ak.tytul); call Reverse;
\r
1946 write(" wydawca: "); call Normal;
\r
1947 call Czytaj(ak.wydawca); call Reverse;
\r
1948 write("rok wydania: "); call Normal;
\r
1949 read(ak.rok); call Reverse;
\r
1950 write(" pozycja nr: "); call Normal;
\r
1951 readln(ak.pozycja);
\r
1952 if inchar = -81 then exit fi;
\r
1954 end WczytajKrotke ;
\r
1956 unit IndeksAutorow : IndexFile class ;
\r
1958 unit klucz : Key class ;
\r
1959 var autor : arrayof char;
\r
1961 array autor dim (1: autleng );
\r
1965 unit virtual KeyOf : function (k :Krotka) : klucz;
\r
1966 (*tworzenie klucza z krotki *)
\r
1968 result := new klucz;
\r
1969 result.autor := copy (k.autor)
\r
1972 unit virtual Leq : function (k1,k2 : klucz) : boolean;
\r
1973 (*porownanie dwu kluczy *)
\r
1980 for i := 1 to autleng
\r
1982 if ord(k1.autor(i)) =13
\r
1986 if ord(k2.autor(i)) = 13
\r
1994 if ord(k1.autor(i)) = ord(k2.autor(i))
\r
1997 if ord(k1.autor(i)) < ord(k2.autor(i))
\r
2008 unit virtual KeyToRec : procedure(ky:klucz, A: arrayof integer,
\r
2010 (*procedura virtualna, ktora przepisuje klucz ky do tablicy
\r
2011 A poczynajac od danego miejsca A(j) do kolejnych KeySize
\r
2012 komorek tej tablicy. *)
\r
2016 for i := 1 to autleng
\r
2018 A(j+i-1) := ord(ky.autor(i))
\r
2022 unit virtual RecToKey : function(A: arrayof integer,
\r
2023 j:integer): klucz;
\r
2024 (*Funkcja odczytuje KeySize kolejnych komorek z tablicy A
\r
2025 poczynajac od A(j) i tworzy z nich klucz *)
\r
2030 for i := 1 to autleng
\r
2032 k.autor(i) := chr(A(j+i-1))
\r
2037 unit DrukujStrone : procedure (PageRef: integer);
\r
2043 AuxRec : arrayof integer;
\r
2045 if PageRef = -1 then return fi;
\r
2046 for i := 1 to TreeHeight
\r
2048 if Path(i) = none then exit fi;
\r
2049 if Path(i).updated
\r
2051 call fseek(plik,Path(i).PageRef);
\r
2052 call fput(plik,PageToRec(StackOfPages(i)));
\r
2053 Path(i).updated := false;
\r
2056 (*wczytaj strone*)
\r
2057 call fseek(plik, PageRef);
\r
2058 AuxRec := fget(plik);
\r
2059 P := RecToPage(AuxRec);
\r
2062 writeln("stronaRefNr=",PageRef:4," itemow =", P.ItemsOnPage:3);
\r
2063 write(" klucze ");
\r
2064 for i := 1 to P.ItemsOnPage
\r
2066 l := P.ItemsArray(i).ky;
\r
2079 write(" PgRfs",P.LessPageRef:5);
\r
2080 for i := 1 to P.ItemsOnPage
\r
2082 write(P.ItemsArray(i).PageRef:12);
\r
2085 call DrukujStrone(P.LessPageRef);
\r
2086 for i := 1 to P.ItemsOnPage
\r
2088 call DrukujStrone(P.ItemsArray(i).PageRef);
\r
2095 begin (*indeksAutorow*)
\r
2096 KeySize := autleng;
\r
2097 akl, akey := new klucz;
\r
2098 (* dlugosc rekordu-klucza = 2+(PageSize * (KeySize + 2)); *)
\r
2101 plik := openfile(unpack("autor.idx"),2+(PageSize * (KeySize + 2)) );
\r
2102 (* odczytac strony do StackOfPages *)
\r
2103 Path(1).PageRef := INFO(1);
\r
2104 Path(1).RefOnPage := 1;
\r
2105 call fseek(plik,Path(1).PageRef);
\r
2106 AuxRec := fget(plik);
\r
2107 StackOfPages(1) := RecToPage(AuxRec);
\r
2110 plik := makefile(unpack("autor.idx"),2+(PageSize * (KeySize + 2)) );
\r
2113 (* ZAMYKANIE indeksu *)
\r
2114 (* strony zmienione ze sciezki sa zapisywane na pliku *)
\r
2115 for i := 1 to TreeHeight
\r
2117 if Path(i) = none then exit fi;
\r
2118 if Path(i).updated
\r
2120 call fseek(plik,Path(i).PageRef);
\r
2121 call fput(plik,PageToRec(StackOfPages(i)));
\r
2122 Path(i).updated := false;
\r
2125 (* ZAPISAC nr rekordu - korzenia *)
\r
2126 INFO(1) := Path(1).PageRef;
\r
2127 call closefile(plik);
\r
2128 end IndeksAutorow ;
\r
2130 var IA :IndeksAutorow ;
\r
2132 unit IndeksPoz : IndexFile class ;
\r
2134 unit klucz : Key class ;
\r
2135 var poz : integer;
\r
2140 unit virtual KeyOf : function (k :Krotka) : klucz;
\r
2141 (*tworzenie klucza z krotki *)
\r
2143 result := new klucz;
\r
2144 result.poz := k.pozycja
\r
2147 unit virtual Leq : function (k1,k2 : klucz) : boolean;
\r
2148 (*porownanie dwu kluczy *)
\r
2150 result := not (k1.poz > k2.poz)
\r
2153 unit virtual KeyToRec : procedure(ky:klucz, A: arrayof integer,
\r
2155 (*procedura virtualna, ktora przepisuje klucz ky do tablicy
\r
2156 A poczynajac od danego miejsca A(j) do kolejnych KeySize
\r
2157 komorek tej tablicy. *)
\r
2165 unit virtual RecToKey : function(A: arrayof integer,
\r
2166 j:integer): klucz;
\r
2167 (*Funkcja odczytuje KeySize kolejnych komorek z tablicy A
\r
2168 poczynajac od A(j) i tworzy z nich klucz *)
\r
2177 unit DrukujStrone : procedure (PageRef: integer);
\r
2180 AuxRec : arrayof integer;
\r
2182 if PageRef = -1 then return fi;
\r
2183 for i := 1 to TreeHeight
\r
2185 if Path(i) = none then exit fi;
\r
2186 if Path(i).updated
\r
2188 call fseek(plik,Path(i).PageRef);
\r
2189 call fput(plik,PageToRec(StackOfPages(i)));
\r
2190 Path(i).updated := false;
\r
2193 (*wczytaj strone*)
\r
2194 call fseek(plik, PageRef);
\r
2195 AuxRec := fget(plik);
\r
2196 P := RecToPage(AuxRec);
\r
2199 writeln("stronaRefNr=",PageRef:4," itemow =", P.ItemsOnPage:3);
\r
2200 write(" klucze ");
\r
2201 for i := 1 to P.ItemsOnPage
\r
2203 write(P.ItemsArray(i).ky qua klucz.poz:12);
\r
2205 (* 16.08.87 *******************************************************)
\r
2207 write(" PgRfs",P.LessPageRef:5);
\r
2208 for i := 1 to P.ItemsOnPage
\r
2210 write(P.ItemsArray(i).PageRef:12);
\r
2213 call DrukujStrone(P.LessPageRef);
\r
2214 for i := 1 to P.ItemsOnPage
\r
2216 call DrukujStrone(P.ItemsArray(i).PageRef);
\r
2224 begin (*indeksPozycji*)
\r
2226 akl, akey := new klucz;
\r
2227 (* plik.reclength := 2+(PageSize * (KeySize + 2)); *)
\r
2230 plik := openfile(unpack("nrpzycji.idx"),2+(PageSize * (KeySize + 2)));
\r
2231 (* odczytac strone-korzen do StackOfPages *)
\r
2233 Path(1).PageRef := INFO(2);
\r
2234 Path(1).RefOnPage := 1;
\r
2235 call fseek(plik,Path(1).PageRef);
\r
2236 AuxRec := fget(plik);
\r
2237 StackOfPages(1) := RecToPage(AuxRec);
\r
2240 plik := makefile(unpack("nrpzycji.idx"),2+(PageSize * (KeySize + 2)) );
\r
2243 (* ZAMYKANIE indexu *)
\r
2244 for i := 1 to TreeHeight
\r
2246 if Path(i) = none then exit fi;
\r
2247 if Path(i).updated
\r
2249 call fseek(plik,Path(i).PageRef);
\r
2250 call fput(plik,PageToRec(StackOfPages(i)));
\r
2251 Path(i).updated := false;
\r
2254 (* ZAPISAC nr rekordu - korzenia *)
\r
2255 INFO(2) := Path(1).PageRef;
\r
2256 call closefile(plik);
\r
2259 var IB :IndeksPoz ;
\r
2261 begin (*bibliografia*)
\r
2265 plik:= openfile(unpack("bibliog.dta"), 95);
\r
2267 plik:= makefile(unpack("bibliog.dta"), 95);
\r
2270 (* call IncreaseIndex( new IndeksAutorow); *)
\r
2271 array Index dim(1 : 2);
\r
2272 Index(1), IA := new IndeksAutorow;
\r
2273 Index(2), IB := new IndeksPoz;
\r
2274 end Bibliografia ;
\r
2277 (*deklaracje pomocnicze programu glownego*)
\r
2279 otworz, (* otwieramy *)
\r
2280 otwarta : boolean, (*czy baza bibliograficzna juz jest otwarta?*)
\r
2283 Rec : arrayof integer;
\r
2285 unit Czytaj : procedure(a: arrayof char);
\r
2286 (*czytaj tablice znakow *)
\r
2287 var i,j : integer,
\r
2290 for i := 1 to upper(a)
\r
2296 then (*wczytano Enter *)
\r
2305 a(upper(a)) := chr(13)
\r
2309 unit Drukuj : procedure (a : arrayof char);
\r
2310 (*drukuj tablice znakow jako linijke tekstu *)
\r
2313 for i := 1 to upper(a)
\r
2317 then (*wydrukowano Enter *)
\r
2323 var INFO : arrayof integer,
\r
2331 call SetCursor(5,1);
\r
2332 writeln("Trying to delete an already absent record");
\r
2336 call SetCursor(5,1);
\r
2337 writeln("osiagnieto element minimalny");
\r
2342 call SetCursor(5,1);
\r
2343 writeln("osiagnieto element maksymalny");
\r
2349 begin (*program glowny prefiksowany przez HandlerOfRelations*)
\r
2350 (*dane bibliograficzne*)
\r
2351 (*wyswietl powitanie*)
\r
2353 array INFO dim (1:3);
\r
2356 call SetCursor(13,10);
\r
2359 write("TOOLBOX dla baz danych");
\r
2360 call SetCursor(15,10);
\r
2361 write("test 19v.4");
\r
2362 call SetCursor(21,10);
\r
2364 write("G.Mirkowska, A.Salwicki - Lipiec 1988");
\r
2365 call SetCursor(22,10);
\r
2366 write("klase FileSystem napisala J.Warpechowska");
\r
2367 call SetCursor(23,68);
\r
2368 write("press a key");
\r
2372 writeln; writeln; writeln;
\r
2374 "Do you wish to use the previously prepared bibliography files?(y/n)?");
\r
2381 infoplik := openfile(unpack("bibliog.bas"),3);
\r
2382 INFO := fget(infoplik);
\r
2385 infoplik := makefile(unpack("bibliog.bas"),3);
\r
2388 R :=new Bibliografia;
\r
2389 R.FreePlace := Info(3);
\r
2393 "i-INSERT d-DELETE s-SEARCH m-MINMAX t-TYPE n-NEXT p-PREVIOUS q-QUIT");
\r
2396 "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ");
\r
2398 call SetCursor(23,1);
\r
2401 "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ");
\r
2406 " make a choice ");
\r
2409 call SetCursor(1,76);
\r
2410 cha := chr(inchar);
\r
2412 call SetCursor(25,1);
\r
2415 call SetCursor(5,1);
\r
2419 when 'q' : (* quit*)
\r
2421 call SetCursor(24,7);
\r
2422 writeln("end of program test19-4, CLOSING FILES");
\r
2424 call SetCursor(5,1);
\r
2425 call closefile(R.plik);
\r
2428 INFO(3) := R.FreePlace;
\r
2429 call frewind(infoplik);
\r
2430 call fput(infoplik,INFO);
\r
2431 call closefile(infoplik);
\r
2436 when 'i': (*read a tuple and INSERT*)
\r
2437 call R.WczytajKrotke;
\r
2438 call SetCursor(24,7);
\r
2441 write("inserting the tuple");
\r
2442 call R.Insert(R.ak);
\r
2445 call SetCursor(24,7);
\r
2448 when 't' : (*type*)
\r
2451 call SetCursor(3,38);
\r
2452 write("print: r-RELATION or b-BTREE ");
\r
2453 cha := chr(inchar);
\r
2457 then (*printing relation*)
\r
2458 call SetCursor(24,4);
\r
2459 write(" press SPACEBAR for next record");
\r
2460 call SetCursor(5,1);
\r
2461 call fseek(R.plik,1);
\r
2462 while not feof(R.plik)
\r
2464 Rec := fget(R.plik);
\r
2465 R.ak := R.RecToTuple(Rec);
\r
2466 call R.DrukujKrotke;
\r
2467 call SetCursor(24,19);
\r
2470 else (*printing Btree*)
\r
2471 call SetCursor(4,30);
\r
2473 write("select index: a-AUTHORS or p-POSITIONS ");
\r
2475 cha := chr(inchar);
\r
2477 call SetCursor(5,1);
\r
2480 call R.IB.DrukujStrone(R.IB.Path(1).PageRef);
\r
2482 call R.IA.DrukujStrone(R.IA.Path(1).PageRef);
\r
2485 fi (*koniec drukuj*);
\r
2487 when 's': (*search for a tuple*)
\r
2488 call SetCursor(3,19);
\r
2490 write(" searching tuple (t)? or key (k)? ");
\r
2491 cha := chr(inchar);
\r
2495 then (*give a tuple *)
\r
2496 call SetCursor(5,1);
\r
2497 call R.WczytajKrotke;
\r
2498 Rec := R.TupleToRec(R.ak);
\r
2499 call SetCursor(24,7);
\r
2502 write("searching the tuple");
\r
2504 call R.FindRec(Rec, i);
\r
2507 call SetCursor(24,7);
\r
2511 writeln(" the tuple not found");
\r
2513 writeln(" position of the tuple in the datafile = ",i);
\r
2514 (* call fseek(R.plik, i);
\r
2515 Rec := fget(R.plik);
\r
2516 R.ak := R.RecToTuple(rec);
\r
2517 call R.DrukujKrotke; *)
\r
2521 then (*searching in the authors or position index*)
\r
2522 call SetCursor(4,19);
\r
2524 write("which index: authors(a)? or positions(p)? ");
\r
2525 cha := chr(inchar);
\r
2531 call SetCursor(5,1);
\r
2532 write(" autor: ");
\r
2533 call Czytaj(R.IA.akl.autor);
\r
2535 j1 := R.IA.Findkey(R.IA.akl);
\r
2537 then (*znaleziono *)
\r
2538 call SetCursor(24,7);
\r
2539 writeln("tuple found on position = ",j1);
\r
2540 call fseek(R.plik, j1);
\r
2541 Rec := fget(R.plik);
\r
2542 R.ak := R.RecToTuple(Rec);
\r
2543 call R.DrukujKrotke;
\r
2544 else (*nie znaleziono *)
\r
2545 call SetCursor(24,7);
\r
2546 writeln(" tuple not found");
\r
2548 else (*zakladamy cha ='p'*)
\r
2550 call SetCursor(5,1);
\r
2551 write(" position nr: ");
\r
2552 read(R.IB.akl.poz);
\r
2553 j2 := R.Index(i).Findkey(R.IB.akl);
\r
2555 then (*znaleziono *)
\r
2556 call SetCursor(24,7);
\r
2557 write("tuple found on position = ",j2);
\r
2558 call fseek(R.plik, j2);
\r
2559 Rec := fget(R.plik);
\r
2560 R.ak := R.RecToTuple(rec);
\r
2561 call SetCursor(6,1);
\r
2562 call R.DrukujKrotke;
\r
2563 else (*nie znaleziono *)
\r
2564 call SetCursor(24,7);
\r
2565 writeln(" tuple not found");
\r
2567 fi (*wyboru klucza*);
\r
2573 when 'p': (*show the previous tuple*)
\r
2575 call SetCursor(4,19);
\r
2577 write("which index: authors(a)? or positions(p)? ");
\r
2578 cha := chr(inchar);
\r
2584 then (*aktualna krotka jest okreslona *)
\r
2585 call R.Index(1).PrevKey(R.IA.akl,j1);
\r
2590 R.IA.akl := R.IA.new klucz;
\r
2592 call SetCursor(24,7);
\r
2593 write("tuple found on position = ",j1);
\r
2594 call fseek(R.plik, j1);
\r
2595 Rec := fget(R.plik);
\r
2596 R.ak := R.RecToTuple(Rec);
\r
2597 call SetCursor(6,1);
\r
2598 call R.DrukujKrotke;
\r
2601 call SetCursor(24,7);
\r
2602 write("no key has been located yet");
\r
2606 then (*aktualna krotka jest okreslona *)
\r
2607 call R.Index(2).PrevKey(R.IB.akl,j2);
\r
2612 call SetCursor(24,7);
\r
2613 write("tuple found on position = ",j2);
\r
2614 call fseek(R.plik, j2);
\r
2615 Rec := fget(R.plik);
\r
2616 R.ak := R.RecToTuple(Rec);
\r
2617 call SetCursor(6,1);
\r
2618 call R.DrukujKrotke;
\r
2621 call SetCursor(24,7);
\r
2622 writeln("no key has been located yet");
\r
2627 when 'm': (*min or max*)
\r
2629 call SetCursor(3,25);
\r
2630 write("searching index of: authors(a)? or positions(p)?");
\r
2631 cha := chr(inchar);
\r
2637 call SetCursor(4,25);
\r
2638 write("searching index of authors: min(i)? or max(x)?");
\r
2639 cha := chr(inchar);
\r
2642 call SetCursor(5,1);
\r
2645 call R.IA.MinKey(R.IA.akl, j1);
\r
2646 call SetCursor(24,7);
\r
2647 writeln(" min key found on position = ",j1);
\r
2648 call fseek(R.plik, j1);
\r
2649 Rec := fget(R.plik);
\r
2650 R.ak := R.RecToTuple(Rec);
\r
2651 call SetCursor(6,1);
\r
2652 call R.DrukujKrotke;
\r
2654 call R.IA.MaxKey(R.IA.akl, j1);
\r
2655 call SetCursor(24,7);
\r
2656 writeln("max key found on position = ",j1);
\r
2657 call fseek(R.plik, j1);
\r
2658 Rec := fget(R.plik);
\r
2659 R.ak := R.RecToTuple(Rec);
\r
2660 call SetCursor(6,1);
\r
2661 call R.DrukujKrotke;
\r
2663 else (*wg pozycji*)
\r
2665 call SetCursor(4,25);
\r
2666 write("searching index of positions: min(i)? or max(x)?");
\r
2667 cha := chr(inchar);
\r
2670 call SetCursor(24,7);
\r
2673 call R.IB.MinKey(R.IB.akl, j2);
\r
2674 writeln("tuple found on position = ",j2);
\r
2675 call fseek(R.plik, j2);
\r
2676 Rec := fget(R.plik);
\r
2677 R.ak := R.RecToTuple(Rec);
\r
2678 call SetCursor(6,1);
\r
2679 call R.DrukujKrotke;
\r
2681 call R.IB.MaxKey(R.IB.akl, j2);
\r
2682 writeln("tuple found on position = ",j2);
\r
2683 call fseek(R.plik, j2);
\r
2684 Rec := fget(R.plik);
\r
2685 R.ak := R.RecToTuple(Rec);
\r
2686 call SetCursor(6,1);
\r
2687 call R.DrukujKrotke;
\r
2689 fi; (* end of minmax utility *)
\r
2692 when 'n': (*show the next tuple*)
\r
2693 call SetCursor(4,19);
\r
2695 write("which index: authors(a)? or positions(p)? ");
\r
2696 cha := chr(inchar);
\r
2699 call SetCursor(24,7);
\r
2703 then (*aktualna krotka jest okreslona *)
\r
2704 call R.Index(1).NextKey(R.IA.akl,j1);
\r
2709 writeln("tuple found on position = ",j1);
\r
2710 call fseek(R.plik, j1);
\r
2711 Rec := fget(R.plik);
\r
2712 R.ak := R.RecToTuple(Rec);
\r
2713 call SetCursor(6,1);
\r
2714 call R.DrukujKrotke;
\r
2717 writeln("no key has been located yet");
\r
2721 then (*aktualna krotka jest okreslona *)
\r
2722 call R.Index(2).NextKey(R.IB.akl,j2);
\r
2727 writeln("tuple found on position = ",j2);
\r
2728 call fseek(R.plik, j2);
\r
2729 Rec := fget(R.plik);
\r
2730 R.ak := R.RecToTuple(Rec);
\r
2731 call SetCursor(6,1);
\r
2732 call R.DrukujKrotke;
\r
2735 writeln("no key has been located yet");
\r
2739 when 'd': (*delete the actual tuple*)
\r
2741 call SetCursor(3,25);
\r
2742 write("from index of: authors(a)? or positions(p)?");
\r
2743 cha := chr(inchar);
\r
2748 then (* ustawic aktualna krotke*)
\r
2754 call SetCursor(25,4);
\r
2757 write("DELETING the actual tuple");
\r
2758 call R.Delete(R.ak);
\r
2762 call SetCursor(25,4);
\r
2767 call SetCursor(25,1);
\r
2771 call SetCursor(25,60);
\r
2772 write("press a key");
\r
2775 call SetCursor(1,76);
\r
2779 call SetCursor(3,1);
\r
2804 call SetCursor(24,1);
\r
2813 call SetCursor(25,60);
\r
2814 write("make your choice");
\r
2817 call SetCursor(1,76);
\r
2821 call SetCursor(1,76);
\r
2823 call SetCursor(25,60);
\r
2825 call SetCursor(5,1);
\r