[fpc-pascal] sorting and merging array of records

Tomas Hajny XHajT03 at hajny.biz
Thu Jan 12 02:35:03 CET 2012


On 11 Jan 12, at 17:46, waldo kitty wrote:
 .
 .
> 1. right now the compare is working on the catalog number (TTLERec.catnbr) and 
> with duplicates:=FALSE there are no duplicates... however, i need to be able to 
> choose which record to keep when there is a duplicate catnbr but the epoch 
> (TTLERec.epoch) is different... right now it is throwing out all but the 
> first... how can i tell it how to decide which one to throw away? i saw earlier 
> that one of the parent objects has neat functions like AtPut which would easily 
> allow me to overwrite an existing record that's too old... i just don't know if 
> i can use that in the middle of an insert or a search or just exactly where i 
> would even put code to do this...

The best solution is probably overriding the Insert method to fit 
your slightly modified logic. Copy the default implementation of 
TSortedCollection.Insert as found in objects.pp in FPC source tree 
and modify it according your needs (if Search returns true, perform 
the additional check for the epoch and depending on the result either 
use AtInsert (equally to the default implementation) or Dispose the 
previously stored record at position I ("I" returned by Search, "At 
(I)" used to access the previously stored record) and then use AtPut.


> 2. something else i'm running into is with duplicates:=FALSE, there's a whole 
> bucket load of records that are not disposed of when i wipe out the 
> collection... heaptrc hollers right nasty to me about'em on exit... i can only 
> assume that these are the duplicates but i don't understand why they are still 
> hanging around if insert or add threw them away already :/

If you already had them in the collection, they're not added again. 
You only dispose records added to the collection at the end, but 
these are lost this way. You can also sort this out in the overridden 
Insert method (if you don't want to use the newly created record, 
dispose it).


> [TRIM]
> >> data^.catnbr := Copy(data^.satdata[1],3,5);
> >> data^.epoch := Real_Value(data^.satdata[1],19,14);
> >> inc(sat_cnt);
> >> aTLECollection^.insert(data);
> >> dispose(data);
> >
> > Don't do this! You'll free the memory you allocated for your record. The
> > collection will only contain a pointer to this data! (Many of the rules I
> > mentioned for T(FP)List apply here as well)
> 
> uh? for some reason i thought that the insert was copying the data to a place 
> and then setting the pointer to there for the collection... i tried with and 
> without the dispose(data) but it still looked the same... of course i was tired 
> and might not have been looking at the right writeln debug output...
 .
 .

No, Insert doesn't do any copying by default. In your current code, 
the copying is performed by calling the PTLERec constructor (in 
"New(PTLERec, Init(...") but if the pointer isn't inserted, it is 
thrown away currently. If you use the overridden Insert method as 
suggested above, you can Dispose it from within the Insert call if 
you don't need to insert it.

Tomas




More information about the fpc-pascal mailing list