[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