Osse, das ist wirklich nicht einfach.
Die Daten werden also sortiert (nach einem bestimmten Schlüssel) abgelegt. Normalerweise speichert man ein Tupel, also (Schlüssel, Daten). Wenn ich also an ein Datum X will, das vorher mit dem Schlüssel 'ABC' gespeichert wurde, dann suche ich nach dem Schlüssel ABC.
Ich habe Speicher gespart, weil ich nur nach einem Schlüssel sortiert ablege und ich den Schlüssel jederzeit aus den Daten erzeugen kann. Die Methode 'TForm1.BtreeCompare' erzeugt eine totale Ordnung auf den Daten, indem es der Btree-Klasse sagt, welches von zwei 'TcsBtreeItems' (identisch mit dem CANrecord) größer ist.
Du kannst natürlich die Methode BtreeCompare an deine Bedürfnisse anpassen. Dabei musst Du aber darauf achten, das 'identische' Records (die also den Vergleichswert '0' liefern) als Identität behandelt, also auch überschrieben werden.
Zurück zum Thema: Wie suche ich einen Record? Da gibt es erstmal zwei Funktionen.
Delphi-Quellcode:
function TcsBtree.FindKey(Var aItem : TcsBtreeItem) : boolean;
function TcsBtree.FindNearest (Var aItem : TcsBtreeItem) : Boolean;
Is klar, was die machen: Du füllst dein TcsBtreeItem (TCANrcvMsg) mit den schlüsselrelevanten Daten und rufst FindKey auf. Der sucht im Baum und liefert eben den record zurück. Blöd ist hier, das Du ja vorher die Daten wissen musst, also wozu noch suchen
? Klar, das geht hier nicht. Die Funktion ist also z.B. für eine
DB gedacht, wo die Kundendaten gespeichert werden, und als Schklüssel die Kundennummer dient. Dann einfach TKundenRec.KundenNr='12345', FindKey und dann hat man den ganzen Kundendatensatz...
Also, suchst Du z.B. den 'nächstliegenden'. Z.B. Füllst Du dein record mit 'ID=12345' und als DATA=0,0,0,0. Dann liefert FindNearest eben den Record, der deinem Kriterium am ähnlichsten ist.
Oder du benutzt die 'BtreeCursors'. Die sind sehr praktisch, weil sie immer 'Bereiche' abdecken. Stell Dir einen B-Baum als sortierte Liste vor. Du willst nun alle recs zwischen ID=12345 und ID=12400.
Deklariere zwei TcsBtreeItems (a und b). Du belegst a mit den Daten, die garantiert 'links' vom ersten Record der ID=12345 liegt (oder identisch mit dem ist) und b belegst du mit Daten, die garantiert 'rechts' vom letzten Record der ID=12400 ist.
Angenommen, du willst alle 'Meyers' aus dem Telefonbuch. Dann suchst Du nach einem 'Meyer', Vorname'AAAAA' (Record a) und dem
'Meyer", Vorname "ZZZZZ". Wenn Du die Positionen hast, dann liegen alle Meyers garantiert dazwischen.
Das macht der Btree-Cursor.
Delphi-Quellcode:
Var
aCursor : TcsBtreeCursor;
aFirstRec, aLastRec : TcsBtreeItem;
Begin
aFirstRec.msgbuff.ID := 12345;
a.msgbuff.LEN := 0; // Garantiert die untere Grenze des zu suchenden Bereiches
aLastRec.msgbuff.ID := 12401;
a.msgbuff.LEN := 0; // Garantiert die obere Grenze des zu suchenden Bereiches
aCursor := TcsBtreeCursor.Create (aBtree, aFirstRec, aLastRec);
Try
aCursor.First; // Isser nach dem Create schon, aber sische' is sische'
While not aCursor.EOF Do begin
ProcessCANRec (aCursor.Pos); // aCursor.Pos ist die aktuelle CANrcvMSG
aCursor.Next; // Gehe zum nächsten record
End;
Finally
aCursor.Free;
End;
End;
Nochmal:
1. DU definierst erstmal, in welcher Reihenfolge die Daten sortiert werden sollen.
2. Dann erzeugst Du die Datei.
3. Dann kannst Du einen beliebigen Bereich innerhalb des Baumes finden, indem Du die untere und obere Grenze angibst.
If MoreQuestions Then Shout;