Danke erst mal an Der_Unwissende, das war mal sehr informativ. (Und du hast dir viel Mühe mit dem Text gegeben)
Das mit dem Abbrechen beim nächsten Buchstaben finde eine sehr sinnvolle Idee.
Um mal etwas konkreter zu werden, poste ich hier meine Datenstruktur, die durchsucht wird:
Delphi-Quellcode:
type
TID3Tag = record
Titel : string;
Artist : string;
Album : string;
Year : string;
Comment : string;
Genre : string;
Track : integer;
end;
type TMp3Eintrag = record
Filename : string;
Path : string;
Anzeige : boolean;
Id3tag : Tid3tag;
end;
Es ist also ein einfaches
Array [0..max]
, das (hoffentlich) im
Ram liegt und das im Grunde nach folgendem Schema abgefragt wird:
Delphi-Quellcode:
if
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].Filename ) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].Path ) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].id3tag.Titel ) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].id3tag.Artist ) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].id3tag.Album) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].id3tag.Genre) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].id3tag.Comment) ) <>0 )
or
( pos( ( CurrentSearch ) ,
ansilowercase( Mp3Daten[ListenNummer,ArrayIndex].id3tag.year) ) <>0 )
then match:=true else match:=false;
Um diese Abbrage habe ich mir einige rekursive Konstrukte ausgedacht, die es mir ermöglichen OR und AND Argumente (auch kombiniert) in meiner Suchabfrage zu verwenden. An einem zusätzlichen NOT bin ich bisher gescheitert; ich denke, das kriege ich aber auch noch hin.
Ach ja: Bisher läuft das so:
Zitat:
Beispiel einer UND-Suche: "Coldplay Live" (Das Leerzeichen ist das Trennzeichen)
Findet alle Live-Titel von Coldplay
Beispiel einer ODER-Suche: "Madonna; H.I.M" (Der Semikolon ist das Trennzeichen)
Findet alle Titel von Madonna und von H.I.M
Anmerkung: Die ODER-Suche ist höherwertiger als die UND Suche: "Coldplay Live; ACDC Highway"
Findet alle Live-Titel von Coldplay und Highway to Hell von ACDC, aber keine Live-Titel von ACDC.
Ist das Semikolon ein legitimes Trennzeichen? Welches sollte man in einem Suchfeld nehmen, gibts da einen Standard?
Mein Ziel es es nicht, einfach ein fertiges Datenbankprodukt zu nehmen (ala
SQL Lite o.Ä.), sondern ich betrachte es als Hobby, sowas selbst zu finden.
Ich hoffe mal, dass Delphi selbstständig abbricht, wenn ein OR der if-Abfrage erfüllt ist und nicht bis zum Ende durchprobiert.
Das Problem ist aber, dass ich hier eine Mp3-Datenbank durchsuche, und meistens suche ich ja nur nach einem Künstler oder Titel, sodass bei meiner Abfrage nur vielleicht 1% der ganzen Arrayelement ein positives "Result" produzieren, also wird bei 99% aller Fälle die ganze If-Abfrage mit all ihren ORs durchlaufen, was natürlich Zeit kostet.
Da fällt mir gerade ein, ich könnte vor der Suche eine Kopie der Datenbank erstellen, in der alles klein geschreiben ist, dann würden schonmal die ganzen ansilowercase wegfallen, was zwar den ersten Buchstaben bei einer Suchabfrage verzögert, aber die anderen unter Umständen beschleunigt. (ich weiß leider nicht wie langsam so ein ansilowercase arbeitet)
Da es aber eine Volltextsuche ist und ich alle Werte abklappern muss, weiß ich nicht, wie Hashwerte (auch wenn ich deren Prinzip noch nicht ganz verstanden habe) das irgendwie beschleunigen könnten. ich weiß ja nicht vorher, ob der Nutzer einen Liedtitel oder einen Albumnamen eingibt. Verschiedene Eingabefelder die dann nur spezifische Elemente abfragen will ich aber dem Nutzer nicht zumuten.
Zumindest skaliert meine Art zu suchen annähernd linear (wenn meine GetTickCount()s zur Messung stimmen), d.H. ich brauche bei doppelt so vielen Einträgen nur die doppelte Zeit.
Codito, ergo sum. - I code therefore I am