Index struktur

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Index struktur

      Ich habe ein Allgemeines Coding Problem von etwas größeren Ausmaßen.

      Ich muss Strings der Länge "LenS" in einer Datei struktureirt abspeichern. Jedem String ist eine Uid (Länge 64 Byte) zugeordnet. Bei dem einfügen von Daten darf die Datei nicht umsortiert werden sondern die Daten werden ans Ende gehangen und in eine Art Index eingetragen. Es muss möglich sein in der Datei nach Strings zu suchen. Dabei darf nicht die ganze Datei mit einer For-Loop durchgegangen werden sondern es muss über besagten Index gesucht werden.

      [cpp]
      template<int LenS>;
      struct Item
      {
      char m_aData[LenS];
      char m_Uid[64];
      };
      [/cpp]

      Diese Struct ist ein Item welches in die Datei eingefügt werden soll.

      Ich würde mich über effizienten, funktionierenden Code freuen.
    • Also mit dem nur Anhängen wird es echt schwer.

      Die Möglichkeiten, die mir so einfallen:
      1. Du könntest jeweils die Länge des Strings mit in die Datei schreiben, damit du den String jedes mal überspringen kannst. Dadurch hast du aber relativ viele Lesezugriffe. Also nicht zu empfehlen.
      2. Du nimmst 2 Dateien. In der ersten stehen die UID, die Stringposition und Stringlänge. Und in der 2. die Strings, die du dann genau ansteuern kannst. Dann musste nur die erste Datei durchloopen.
      3. Du definierst eine maximale Größe für den String. Z.b. 1024 Bytes. Dann ist ein Informationsblock genau 1024 + 64 Bytes groß. Dann gibt es allerdings auch recht viele Lesezugriffe, weil du nicht weißt, wo genau welche UID ist.
      4. Ähnlich wie 2, bloß in einer Datei. Du hast einen Header, der 4 Bytes groß ist, also ein Integer mit der Anzahl der Einträge. Anschließend folgt ein Index mit den UIDs, jeweils die UID, die Position des zugehörigen Strings in der Datei und seine Größe. Um alles zu initialisieren, ließt du erstmal die ersten 4 Bytes. Dann weißt du die Anzahl n der Einträge. Daraus ergibt sich die Größe des indexes: n * (64 + 8). n ist wie gesagt die Anzahl der Einträge, 64 ist die Größe der UID und 8 Bytes nochmal für die zwei Integer, die die Position des Strings und die Länge angeben. Dann weißt du die Größe des Indexes und kannst ihn komplett einlesen und im Arbeitsspeicher bereit halten und weist genau die Position der Strings. Das Problem hierbei ist, dass du ja nur ans Ende der Datei schreiben willst. Da müsstest du entsprechend freien Platz im Index bereithalten und dann jeweils einen Teil überschreiben. Also du weißt, dass du nicht mehr als 1000 Einträge haben wirst, dann machste den Index 1000 * (64 + 8) groß, also 72000 Bytes. Das sind erstmal leere Daten, wo du dann einfach neue reinschreiben kannst, ohne, dass sich die Datei dahinter verändert.
      5. Die ersten 4 Bytes geben wieder die Länge des Indexes an. Dann folgen die Strings hintereinander und der Index (wie bei 4.) kommt ans Ende der Datei. Jedes mal, wenn du dann einen String hinzufügst, entfernst du den Index, hängst den String an und fügst den Index wieder an.

      Ich denke, Variante 2 dürfte am einfachsten umzusetzen sein.
    • So jetzt kommt es. Es geht nich um Gigabyte es handelt sich um einige Terabyte an Daten. Man kann sich das ganze so vorstellen wie ein Wörterbuch. Ein String kann mehrere Uids haben. Wenn ich jetzt dem Programm einen String übergebe soll der mir die zugehörigen Uids ausgeben.
      Also brauche ich einen Algorithmus der (ohne die Daten zu sortieren) eine schnelle Suche ermöglicht. Außerdem müssen später noch Strings hinzugefügt werden können. Dabei kann natürlich nicht die Datei neu sortiert werden da das schon bei einigen GB zu lange dauern würde. Deshalb muss eine Art dynamischer Index angelegt werden der belibig erweiterbar ist. Nehmen wir an wir haben eine Datei die 1.000.000.000 Datensätze enthält. Jeder Datensatz besteht aus 2 String je 64 Byte. Also haben wir mehr als 100 GB an rohdaten. Eine suche nach einer Uid (anhand eines Strings) soll maximal 10 ms dauern. Das einfügen eines neuen Strings maximal 2ms.

      Das sind die ungefähren Größenordnungen. Nach oben sollte das ganze nicht(bzw nur durch Hardware) begrenzt sein. Danke schonmal für die Arbeit die du dir bis jetzt gemacht hast. Vllt hat noch jemmand lust mit zu denken? ;)
    • Die Lösung ist ganz einfach:
      Es gibt keine. Alleine eine HDD hat eine Zugriffszeit, die schon dein Zeitfenster größtenteils ausschöpft.
      Außerdem kannst du bei unsortieren Daten nur ausprobieren, nie aber die Position des gesuchten Schlüssels berechnen. D.h. du musst auf jedenfall den Index solange scannen bis du ein Ergebnis hast.

      Allerdings... was hast du vor? Terabyte? Frag mal in Cern nach, die müssten das Problem gelöst haben⸮
      Erzähl lieber mal, was du genau machen willst. Denn du brauchst keine Lösung, sondern erstmal den richtigen Ansatz, hab ich das Gefühl.
      Oder du wartest, bis es Quantencomputer gibt.
    • SQLite oder MySQL? Ne Datenbank ist besonders für große Datenmengen geeignet. Flatfiles eher weniger.


      Ansonsten schreib nen Header-index für die Datei in Zeile 1:

      Quellcode

      1. LenS|Zeile;LenS|Zeile;LenS|Zeile;

      Zeile ist dabei eine bestimmte Position in der Datei. Und LenS halt dein String nach dessen Inhalt du suchst.


      Bei der LVL-Mod war die Situation eine ähnliche:
      Zuerst wurde alles in flatfiles (Textdateien) gespeichert. Eine Datei im Serververzeichnis als Index und in einem Unterordner die Infos zu den Spielern. Somit wusste der Server, welche Spieler es gibt und hat nach bedarf die passende Spielerdatei ausgelesen/beschrieben.

      Da das ganze aber ziemlich Langsam war ist Sushi auf die MySQL-Datenbank umgestiegen, mit seinem zuvor geschriebenem Wrapper.




      RIP in Peaces Basti
      ˙˙˙ɥǝɯ
      'oqɯılnɐǝʌıu uǝzuɐʇ ɹıʍ pun
      ლ(ಠ益ಠლ) Y SO MAD?