[fpc-pascal] sorting and merging array of records

waldo kitty wkitty42 at windstream.net
Thu Jan 12 20:11:34 CET 2012


On 1/12/2012 12:42, Tomas Hajny wrote:
> On Thu, January 12, 2012 17:23, waldo kitty wrote:
[TRIM]
>> but the the problem still comes of how do i know if the record was
>> inserted into the list or not? insert doesn't seem to return a true
>> or false on success... i guess this is where it is required(?) to
>> override the insert method? does everyone have to override the
>> insert method if they are in duplicates := FALSE mode? how do they
>> handle the throwing away of the unneeded data??
>
> There are multiple options. You can search before (as suggested by you)
> and only call Insert if not finding the result, you can override the
> Insert call as suggested by me,

this is what i've done and it works as per my previous message in this thread... 
however, i have found another problem... the program mostly works.. i mean that 
if a dupe catnbr with an epoch >= to the existing record is found it is thrown 
out but when another dupe catnbr is found it, too, is also inserted... this 
seems to only be happening with entries that have more than one duplicate... it 
doesn't make sense... i'm suspecting the compare routine to be the problem... 
epochs are read from the file and converted to a double by this original routine 
from TSKelso's SGP4-26A source code archive...

Function Real_Value(buffer : string; start,length : integer) : double;
     Takes the segment of {buffer} beginning at {start} and having length
     {length} and converts it to a double precision real number.


Function Real_Value(buffer : string; start,length : integer) : double;
var
   MyResult : integer;
   answer   : double;

begin
   buffer := Copy(buffer,start,length);
   Convert_Blanks(buffer);
   if buffer = '' then
     buffer := '0';
   Val(buffer,answer,MyResult);
   if MyResult = 0 then
     Real_Value := answer
   else
     Real_Value := 0.0;
end; {Function Real_Value}


but yet i find this in my debug output...

03597   5.04184917406000E+003   .....................   ** inserting record
[...]
03597   1.20109577665600E+004   .....................   ** inserting record


here's my compare and insert routines... i'm suspecting my use of CompareValue 
is in error :/


Function CompareReal(num1,num2 : double) : integer;
begin
   CompareReal := CompareValue(num1, num2);
end;


procedure TTLEColl.Insert (Item: Pointer);
var
   I: Sw_Integer;
   old: Pointer;
   foo: integer;
begin
    If NOT Search(KeyOf(Item), I) OR Duplicates Then   { Item valid }
      begin
        {$IFDEF DEBUG}
        write(PTLERec(Item)^.catnbr^);
        write('  ');
        write(PTLERec(Item)^.epoch);
        write('   ');
        write('.....................');
        writeln('   ** inserting record');
        {$ENDIF}
        AtInsert(I, Item);                             { Insert the item }
      end
    else                                               // otherwise
      begin
        {$IFDEF DEBUG}
        write(PTLERec(At(i))^.catnbr^);
        write('  ');
        write(PTLERec(At(i))^.epoch);
        write('  ');
        write(PTLERec(Item)^.epoch);
        {$ENDIF}
        // compare the epochs
        foo := CompareReal(PTLERec(At(i))^.epoch,PTLERec(Item)^.epoch);
        case foo of
          -1 : begin                       // replace existing record
                 {$IFDEF DEBUG}
                 writeln('   ** replacing record');
                 {$ENDIF}
                 old := At(i);             // save existing pointer first!
                 AtPut(i, Item);           // now put in the new record
                 PTLERec(old)^.Done;       // time to remove the old data
                 dispose(old);             // and finally dispose it
               end;
           0 : begin                       // we're tossing this one out
                 {$IFDEF DEBUG}
                 writeln('   ** epochs are same');
                 {$ENDIF}
                 PTLERec(Item)^.Done;      // so remove the data first
                 dispose(Item);            // and then dispose the item
               end;
           1 : begin                       // we're tossing this one out
                 {$IFDEF DEBUG}
                 writeln('   ** existing is newer');
                 {$ENDIF}
                 PTLERec(Item)^.Done;      // so remove the data first
                 dispose(Item);            // and then dispose the item
               end;
          end; {case}
      end;
end;



[TRIM]
>   .
>   .
>> yeah, that went over like a lead balloon... i'm digging into the insert
>> method
>> override, instead... just gotta figure out how to access the epoch in the
>> current record and the one in the passed record for the decision making
>> comparison...
>
> PROCEDURE TTLECollection.Insert (Item: Pointer);
> VAR I: Sw_Integer;
> BEGIN
>     If NOT Search(KeyOf(Item), I) OR Duplicates Then   { Item valid }
>       AtInsert(I, Item)                                { Insert the item }
>     else
>       if PTLERec (At (I))^.Epoch>  PTLERec (Item)^.Epoch then
>         begin
>           FreeItem (At (I));
>           AtPut (I, Item);
>         end
>       else
>        FreeItem (Item); (* or "Dispose (PTLERec (Item), Done)" instead *)
> END;

that's pretty close to what i did (see above) :lol: i might be able to tighten 
mine up a bit instead of doing the .done and then a dispose... or does that matter?




More information about the fpc-pascal mailing list