PrioritySearchRefExample.mesa
Uses PrioritySearchRef to maintain sets of ROPE's that can be searched by alphabetic order and/or by length (a semi-independent ordering).
last modified by E. McCreight, May 16, 1985 2:04:07 pm PDT
written by E. McCreight, May 17, 1985 9:34:33 am PDT
DIRECTORY
Basics, Commander, CommandTool, FS, IO, PrioritySearchRef, Rope;
PrioritySearchRefExample: CEDAR PROGRAM
IMPORTS Commander, CommandTool, FS, IO, PrioritySearchRef, Rope =
BEGIN
bitsPerXChar: NAT = 1+Basics.bitsPerByte; -- high-order virtual bit is 1 if char present, 0 if not
ExampleDepth: PROC [ item1, item2: PrioritySearchRef.Item ] RETURNS [ Basics.Comparison ] =
BEGIN
r1: Rope.ROPE = NARROW[item1];
r2: Rope.ROPE = NARROW[item2];
RETURN [ SELECT r1.Length-r2.Length FROM
<0 => less,
>0 => greater,
ENDCASE => equal ];
END;
ExampleTreeHalf: PROC [ item: PrioritySearchRef.Item, index: PrioritySearchRef.RadixIndex ] RETURNS [ half: PrioritySearchRef.Half ] =
BEGIN
r: Rope.ROPE = NARROW[item];
charPos: NAT = index/bitsPerXChar;
half ← PrioritySearchRef.TreeHalfImpl[
LONG[(IF charPos<r.Length THEN ToXByte[r.Fetch[charPos]] ELSE 0)],
2*Basics.bitsPerWord-bitsPerXChar+(index MOD bitsPerXChar)];
END;
ExamplePrefix: PROC [ item1, item2: PrioritySearchRef.Item ] RETURNS [ prefix: PrioritySearchRef.RadixIndex ] =
BEGIN
r1: Rope.ROPE = NARROW[item1];
r2: Rope.ROPE = NARROW[item2];
minLen: NAT = MIN[r1.Length[], r2.Length[]];
FOR charPos: NAT ← 0, charPos+1 WHILE charPos<minLen DO
r1c: CHAR = r1.Fetch[charPos];
r2c: CHAR = r2.Fetch[charPos];
IF r1c # r2c THEN RETURN[bitsPerXChar*charPos+
PrioritySearchRef.PrefixImpl[LONG[ToXByte[r1c]], LONG[ToXByte[r2c]]]-(2*Basics.bitsPerWord -- that's bitsPerLongNumber, folks -- -bitsPerXChar)];
ENDLOOP;
RETURN[IF r1.Length[] # r2.Length[] THEN bitsPerXChar*minLen ELSE PrioritySearchRef.equal];
END;
ToXByte: PROC [ c: CHAR ] RETURNS [ b: CARDINAL ] =
TRUSTED INLINE BEGIN
b ← 256+LOOPHOLE[c, Basics.Byte];
END;
t: PrioritySearchRef.Tree ← NIL;
PSRExample: PROC [cmd: Commander.Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL] -- Commander.CommandProc -- =
BEGIN
TouchProc: PROC [ item: PrioritySearchRef.Item ] =
{cmd.out.PutF[" %g", IO.rope[NARROW[item]]]};
argv: CommandTool.ArgumentVector = CommandTool.Parse[cmd];
s: IO.STREAM = FS.StreamOpen[argv[1]];
tree: PrioritySearchRef.Tree = PrioritySearchRef.Create[prefix: ExamplePrefix, treeHalf: ExampleTreeHalf, depth: ExampleDepth];
t ← tree;
DO
r: Rope.ROPE ← s.GetCedarTokenRope[ ! IO.EndOfStream => EXIT ].token;
[] ← PrioritySearchRef.Insert[tree, r];
ENDLOOP;
s.Close[];
cmd.out.PutF["\nTree has %d entries ...\nQuery matches", IO.int[tree.Size]];
PrioritySearchRef.Search[tree, argv[2], argv[3], argv[4], TouchProc];
END;
Commander.Register["PSRExample", PSRExample, "Example of client usage of PrioritySearchRef package. Syntax is\n\n PSRExample fileName a b c\n\nwhere fileName is searched for all tokens alphabetically between b and c whose length is not greater than that of a."];
END. -- of PrioritySearchRefExample