home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TBTREE.ZIP / BTREE2.INC < prev    next >
Encoding:
Text File  |  1988-05-18  |  17.1 KB  |  439 lines

  1.  
  2. (* This routine locates all values within the index which meet a condition
  3.    (cond) and returns a list of logical record numbers corresponding to these
  4.    values.
  5.  
  6.    note - In the case of  cond = EX (exists) all entries in the index will be
  7.    returned.  paramValue is not really used in this case so anything (a dummy)
  8.    can be passed in as the parameter corresponding to paramValue.            *)
  9.  
  10. procedure GetValuesFromBTree(iFName : FnString;
  11.                              var paramValue;
  12.                              cond : Condition;
  13.                              var lrLst : LrList);
  14.  
  15. var
  16.     pRec : ParameterRecord;                    (* holds the index parameters *)
  17.     sNode : NodePtrType;         (* used as pointer to current sequence node *)
  18.     vCnt : Byte;                                (* count of values in a node *)
  19.     result : Comparison;
  20.     page : SinglePage;
  21.     finished,
  22.     done : Boolean;
  23.     cnt : Byte;               (* used to count number of values *)
  24.     lrNum : LrNumber;
  25.     bytePtr : PageRange;      (* used to keep track of current byte *)
  26.  
  27.     (* used to simplify the body of GetValuesFromBTree *)
  28.  
  29.     function Completed : Boolean;
  30.  
  31.     begin
  32.     if cnt > vCnt then
  33.         begin
  34.         Completed := TRUE;
  35.         end
  36.     else
  37.         begin
  38.         case cond of
  39.             GE : Completed := (CompareValues(page[bytePtr + RNSIZE],
  40.                                              paramValue,
  41.                                              pRec.vType) <> LESSTHAN);
  42.  
  43.             GT : Completed := (CompareValues(page[bytePtr + RNSIZE],
  44.                                              paramValue,
  45.                                              pRec.vType) = GREATERTHAN);
  46.             end;                                    (* end of case statement *)
  47.         end;
  48.     end;                                         (* end of Completed routine *)
  49.  
  50.     begin
  51.     CreateLrList(lrLst);
  52.     case cond of
  53.         EX,
  54.         NE,
  55.         LT,
  56.         LE,
  57.         GE,
  58.         GT : begin
  59.              FetchIndexParameters(iFName,pRec);
  60.              bytePtr := 1;
  61.              cnt := 1;
  62.              case cond of
  63.                   EX,LT,LE,NE :
  64.                                 begin
  65.                                 sNode := pRec.fSNode;
  66.                                 FetchPage(iFName,sNode,page);
  67.                                 vCnt := page[VCNTLOC];
  68.                                 end;
  69.                   GE,GT :
  70.                                 begin
  71.                                 sNode := FindSNode(iFName,pRec.rNode,
  72.                                                    paramValue,pRec);
  73.                                 FetchPage(iFName,sNode,page);
  74.                                 vCnt := page[VCNTLOC];
  75.                                 while not Completed do
  76.                                     begin
  77.                                     bytePtr := bytePtr + pRec.vSize + RNSIZE;
  78.                                     cnt := cnt + 1;
  79.                                     end;
  80.                                 end;
  81.                   end;                        (* end of inner case statement *)
  82.              done := FALSE;
  83.              while not done do
  84.                  begin
  85.                  if cnt <= vCnt then
  86.                      begin
  87.                      finished := FALSE;
  88.                      end
  89.                  else
  90.                      begin
  91.                      done := TRUE;
  92.                      finished := TRUE;
  93.                      end;
  94.                  while not finished do
  95.                      begin
  96.                      if cond <> EX then
  97.                          begin
  98.                          result := CompareValues(page[bytePtr + RNSIZE],
  99.                                                  paramValue,
  100.                                                  pRec.vType);
  101.                          end;
  102.                      if ((result = GREATERTHAN)
  103.                             and ((cond = LT) or (cond = LE))) or
  104.                         ((result = EQUALTO)
  105.                             and (cond = LT)) then
  106.                          begin
  107.                          finished := TRUE;
  108.                          done := TRUE;
  109.                          end
  110.                      else
  111.                          begin
  112.                          if (cond <> NE) or (result <> EQUALTO) then
  113.                              begin
  114.                              Move(page[bytePtr],lrNum,RNSIZE);
  115.                              AddToLrList(lrNum,lrLst);
  116.                              end;
  117.                          if cnt = vCnt then
  118.                              begin
  119.                              finished := TRUE;
  120.                              Move(page[NEXTLOC],sNode,RNSIZE);
  121.                              if sNode = NULL then
  122.                                  begin
  123.                                  done := TRUE;
  124.                                  end
  125.                              else
  126.                                  begin
  127.                                  FetchPage(iFName,sNode,page);
  128.                                  vCnt := page[VCNTLOC];
  129.                                  bytePtr := 1;
  130.                                  cnt := 1;
  131.                                  end;
  132.                              end
  133.                          else
  134.                              begin
  135.                              bytePtr := bytePtr + pRec.vSize + RNSIZE;
  136.                              cnt := cnt + 1;
  137.                              end;
  138.                          end;
  139.                      end;
  140.                  end;
  141.              end;
  142.         EQ : begin
  143.              GetEqualsFromBTree(iFName,paramValue,lrLst);
  144.              end;
  145.         end;                                        (* end of case statement *)
  146.     end;                                (* end of GetValuesFromBTree routine *)
  147.  
  148. (*\*)
  149. (* This routine locates all values within the index within a given range and
  150.    returns a list of logical record numbers corresponding to values within
  151.    that range.  The range is determined by paramValue1 and paramValue2.
  152.    paramValue1 must be less than paramValue2.  cond1 and cond2 are used to
  153.    determine if the range is inclusive or exclusive.  cond1 must be either
  154.    GE or GT and cond2 must be either LE or LT for this to work.  If any of
  155.    the above conditions is not true then an empty list will be returned.     *)
  156.  
  157. procedure GetRangeFromBTree(iFName : FnString;
  158.                             var paramValue1;
  159.                             cond1 : Condition;
  160.                             var paramValue2;
  161.                             cond2 : Condition;
  162.                             var lrLst : LrList);
  163.  
  164. var
  165.     pRec : ParameterRecord;                    (* holds the index parameters *)
  166.     sNode : NodePtrType;         (* used as pointer to current sequence node *)
  167.     vCnt : Byte;                                (* count of values in a node *)
  168.     result : Comparison;
  169.     page : SinglePage;
  170.     finished,
  171.     done : Boolean;
  172.     cnt : Byte;               (* used to count number of values *)
  173.     lrNum : LrNumber;
  174.     bytePtr : PageRange;      (* used to keep track of current byte *)
  175.  
  176.     (* used to simplify the body of GetRangeFromBTree *)
  177.  
  178.     function Completed : Boolean;
  179.  
  180.     begin
  181.     if cnt > vCnt then
  182.         begin
  183.         Completed := TRUE;
  184.         end
  185.     else
  186.         begin
  187.         case cond1 of
  188.             GE : Completed := (CompareValues(page[bytePtr + RNSIZE],
  189.                                              paramValue1,
  190.                                              pRec.vType) <> LESSTHAN);
  191.  
  192.             GT : Completed := (CompareValues(page[bytePtr + RNSIZE],
  193.                                              paramValue1,
  194.                                              pRec.vType) = GREATERTHAN);
  195.             end;                                    (* end of case statement *)
  196.         end;
  197.     end;                                         (* end of Completed routine *)
  198.  
  199.     begin
  200.     CreateLrList(lrLst);
  201.     FetchIndexParameters(iFName,pRec);
  202.     if (cond1 in [GT,GE]) and
  203.        (cond2 in [LT,LE]) and
  204.        (CompareValues(paramValue1,paramValue2,pRec.vType) = LESSTHAN) then
  205.         begin
  206.         bytePtr := 1;
  207.         cnt := 1;
  208.         sNode := FindSNode(iFName,pRec.rNode,paramValue1,pRec);
  209.         FetchPage(iFName,sNode,page);
  210.         vCnt := page[VCNTLOC];
  211.         while not Completed do
  212.             begin
  213.             bytePtr := bytePtr + pRec.vSize + RNSIZE;
  214.             cnt := cnt + 1;
  215.             end;
  216.         done := FALSE;
  217.         while not done do
  218.             begin
  219.             if cnt <= vCnt then
  220.                 begin
  221.                 finished := FALSE;
  222.                 end
  223.             else
  224.                 begin
  225.                 done := TRUE;
  226.                 finished := TRUE;
  227.                 end;
  228.             while not finished do
  229.                 begin
  230.                 result := CompareValues(page[bytePtr + RNSIZE],
  231.                                              paramValue2,
  232.                                              pRec.vType);
  233.                 if (result = GREATERTHAN) or
  234.                    ((result = EQUALTO) and (cond2 = LT)) then
  235.                     begin
  236.                     finished := TRUE;
  237.                     done := TRUE;
  238.                     end
  239.                 else
  240.                     begin
  241.                     Move(page[bytePtr],lrNum,RNSIZE);
  242.                     AddToLrList(lrNum,lrLst);
  243.                     if cnt = vCnt then
  244.                         begin
  245.                         finished := TRUE;
  246.                         Move(page[NEXTLOC],sNode,RNSIZE);
  247.                         if sNode = NULL then
  248.                             begin
  249.                             done := TRUE;
  250.                             end
  251.                         else
  252.                             begin
  253.                             FetchPage(iFName,sNode,page);
  254.                             vCnt := page[VCNTLOC];
  255.                             bytePtr := 1;
  256.                             cnt := 1;
  257.                             end;
  258.                         end
  259.                     else
  260.                         begin
  261.                         bytePtr := bytePtr + pRec.vSize + RNSIZE;
  262.                         cnt := cnt + 1;
  263.                         end;
  264.                     end;
  265.                 end;
  266.             end;
  267.         end;
  268.     end;                                 (* end of GetRangeFromBTree routine *)
  269.  
  270.  
  271. (*\*)
  272. (* This routine locates partial string matches in an index of type
  273.    STRINGVALUE.  A partial string match occurs when the string passed in as
  274.    paramValue is contained within a string entry in the index.  You must
  275.    specify where in the string the match must occur.  You accomplish this by
  276.    using cond.  cond can be CO which stands for contains.  In this case, a
  277.    match occurs if the string passed in as paramValue is anywhere in the
  278.    string in the index.  Another option for cond is ST which stands for
  279.    starts.  A match will occur in this instance if paramValue is located at
  280.    the start of the string in the index.  The last option for cond is EN which
  281.    stands for ends.  A match here occurs if paramValue matches the last
  282.    characters in the index string.  Be aware that if paramValue and the string
  283.    being checked are the same length and they match exactly, then a match
  284.    would occur if any of the three options were selected (not earth shattering
  285.    but true nonetheless).
  286.  
  287.    Otherwise, this works like any of the other retrieval routines.  A list of
  288.    logical record numbers will be returned.
  289.  
  290.    This is exceptionally useful for many applications.  For example, a field
  291.    might be a 7 digit code stored as a string (STRINGVALUE).  The last two
  292.    digits might mean something in particular (part category, state, or
  293.    whatever).  Using this you can look for all the matches on only the last
  294.    two digits.
  295.  
  296.    One reality note here!! - For cond <> ST I have to look at every entry in
  297.    the index for matches.  Why this is true should be reasonably obvious.
  298.    Anyway, for cond = EN or cond = CO it will be somewhat slower than for cond
  299.    = ST.  How much slower depends on the size of the index.  It boils down to
  300.    the difference between a O(LOG(n)) algorithm and a O(n) algorithm, the
  301.    former being much faster for n = a large number.  If any of the above is
  302.    confusing ignore it and experiment.  It is still better to use this routine
  303.    than to grovel through all of the data records yourself!!                 *)
  304.  
  305.  
  306. procedure GetSubstringFromBTree(iFName : FnString;
  307.                                 var paramValue;      (* must be a string var *)
  308.                                 cond : StringCondition;
  309.                                 var lrLst : LrList);
  310.  
  311. var
  312.     pRec : ParameterRecord;                    (* holds the index parameters *)
  313.     sNode : NodePtrType;         (* used as pointer to current sequence node *)
  314.     vCnt : Byte;                                (* count of values in a node *)
  315.     result : Comparison;
  316.     page : SinglePage;
  317.     finished,
  318.     done : Boolean;
  319.     cnt : Byte;               (* used to count number of values *)
  320.     lrNum : LrNumber;
  321.     bytePtr : PageRange;      (* used to keep track of current byte *)
  322.  
  323.     (* used to simplify the body of GetSubstringFromBTree *)
  324.  
  325.     function Completed : Boolean;
  326.  
  327.     begin
  328.     if cnt > vCnt then
  329.         begin
  330.         Completed := TRUE;
  331.         end
  332.     else
  333.         begin
  334.         Completed := (SubstringCompare(page[bytePtr + RNSIZE],
  335.                       paramValue) <> LESSTHAN);
  336.         end;
  337.     end;                                         (* end of Completed routine *)
  338.  
  339.     begin
  340.     CreateLrList(lrLst);
  341.     FetchIndexParameters(iFName,pRec);
  342.     bytePtr := 1;
  343.     cnt := 1;
  344.     case cond of
  345.         CO,EN :
  346.                       begin
  347.                       sNode := pRec.fSNode;
  348.                       FetchPage(iFName,sNode,page);
  349.                       vCnt := page[VCNTLOC];
  350.                       end;
  351.         ST :
  352.                       begin
  353.                       sNode := FindSNode(iFName,pRec.rNode,
  354.                                          paramValue,pRec);
  355.                       FetchPage(iFName,sNode,page);
  356.                       vCnt := page[VCNTLOC];
  357.                       while not Completed do
  358.                           begin
  359.                           bytePtr := bytePtr + pRec.vSize + RNSIZE;
  360.                           cnt := cnt + 1;
  361.                           end;
  362.                       end;
  363.         end;                                  (* end of inner case statement *)
  364.     done := FALSE;
  365.     while not done do
  366.         begin
  367.         if cnt <= vCnt then
  368.             begin
  369.             finished := FALSE;
  370.             end
  371.         else
  372.             begin
  373.             done := TRUE;
  374.             finished := TRUE;
  375.             end;
  376.         while not finished do
  377.             begin
  378.             case cond of
  379.                 ST :
  380.                      begin
  381.                      if StartsWithSubstring(paramValue,
  382.                                             page[bytePtr + RNSIZE]) then
  383.                          begin
  384.                          Move(page[bytePtr],lrNum,RNSIZE);
  385.                          AddToLrList(lrNum,lrLst);
  386.                          end
  387.                      else
  388.                          begin
  389.                          finished := TRUE;
  390.                          done := TRUE;
  391.                          end;
  392.                      end;
  393.                 CO :
  394.                      begin
  395.                      if ContainsSubstring(paramValue,
  396.                                           page[bytePtr + RNSIZE]) then
  397.                          begin
  398.                          Move(page[bytePtr],lrNum,RNSIZE);
  399.                          AddToLrList(lrNum,lrLst);
  400.                          end;
  401.                      end;
  402.                 EN :
  403.                      begin
  404.                      if EndsWithSubstring(paramValue,
  405.                                           page[bytePtr + RNSIZE]) then
  406.                          begin
  407.                          Move(page[bytePtr],lrNum,RNSIZE);
  408.                          AddToLrList(lrNum,lrLst);
  409.                          end;
  410.                      end;
  411.                 end;                                (* end of case statement *)
  412.             if not finished then
  413.                 begin
  414.                 if cnt = vCnt then
  415.                     begin
  416.                     finished := TRUE;
  417.                     Move(page[NEXTLOC],sNode,RNSIZE);
  418.                     if sNode = NULL then
  419.                         begin
  420.                         done := TRUE;
  421.                         end
  422.                     else
  423.                         begin
  424.                         FetchPage(iFName,sNode,page);
  425.                         vCnt := page[VCNTLOC];
  426.                         bytePtr := 1;
  427.                         cnt := 1;
  428.                         end;
  429.                     end
  430.                 else
  431.                     begin
  432.                     bytePtr := bytePtr + pRec.vSize + RNSIZE;
  433.                     cnt := cnt + 1;
  434.                     end;
  435.                 end;
  436.             end;
  437.         end;
  438.     end;                             (* end of GetSubstringFromBTree routine *)
  439.