Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 16, 2025 16:34

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: OnDemand VirtualSystem?
BeitragVerfasst: So Feb 20, 2011 09:55 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Hallo,

ich habe eine Webanwendung erstellt, die aus verschiedenen Datastorages (Lokale Verzeichnisse) eine Virtuelle Ordner struktur in einem eigenen Virtual Treeview ausliest und darstellt.

Die Lokalen Verzeichnisse werden zu meiner Virtual Treeview zusammengefügt (Merge).

Jeder Datastorage wird Rekursiv aufgebaut, allerdings nur solange bis ein spezieller "Raum Ordner" gefunden wurde.
Dieser wird nicht weiter ausgelesen da dieser zig-tausende unterordner und dateien enthalten kann und somit den Prozess das Virtual Treeview aufzubauen erheblich verlangsamt. Solche ordner werden simpel erkannt wenn darin eine "index.htm" datei enthalten ist.

Jeder andere Ordner ist eine sogenannte "Kategorie" und kann Unterkategorien enthalten und "Raum Ordner".



Nun ist es so. Ich habe noch zusätzlich den Inhalte der "Raum Ordner" als Zip Datei enthalten.
Die sind unterschiedlich groß von 10 KB - 20 GB...

Ich will nun auch diese Zip Dateien als "Raum Ordner" erkennen lassen und bei bedarf (OnDemand) drauf zugreifen können ohne das Zip zu entpacken.



Ich hatte das anfangs gelöst indem ich zusätzlich zu dem Virtual Treeview ein VFS aufbaue und auf meine VFS Knoten drauf zugreife.

Das hat auch technisch wunderbar funktioniert, aber tötete die Performance um mehr als 1000% weil ich jedes Zip archive komplett in meine Interne Hashtable mit allen Ordner und Dateien gepackt habe (Nicht die inhalte der Dateien!!!).

Somit kann ich nicht jedes Zip archive komplett aufbauen lassen, das würde zu lange dauern, aber ich will bei bedarf auf Dateien darin zugreifen können die ich über einen kompletten Pfad auslesen kann.



Also bräuchte man also eigentlich meiner meinung nach ein VFS das nur die notwendigsten Ordner ausliest und
bei bedarf weitere Unterordner automatisch ausliesst.

Als beispiel habe ich z.b. ein Datastorage "c:\mydatastorage" und darin ist der einfachkeit halber folgende Ordner struktur im VFS eingetragen: (Links physical path - Rechts virtual path)

c:\mydatastorage\Cat a -> /Cat a
c:\mydatastorage\Cat a\Cat aa\Uncompressed Room aaa -> /Cat a/Cat aa/Uncompressed Room aaa
c:\mydatastorage\Cat a\Cat aa\Compressed Room aab.zip -> /Cat a/Cat aa/Compressed Room aab.zip

Greif ich nun auf Datei "/Cat a/Cat aa/Uncompressed Room aaa/bla/blubb/hello.xml" zu dann soll Automatisch der Ordner bla aufgelöst werden und darin der Ordner blubb und die Datei hello.xml.

Das gleiche soll auch funktionieren wenn ich auf "/Cat a/Cat aa/Compressed Room aab.zip/bla/blubb/hello.xml" zugreife also im Zip was nicht entpackt ist.

Was nicht funktionieren darf ist wenn ich versuche auf einen Ordner zuzugreifen den es nicht geben kann, z.b.
"/Cat b/some other folder".

Meine implementierung von einem normalem VFS sieht folgendermaßen aus:

Ich habe eine Hashtable wo alle meine Virtuellen Pfade definiert sind, als Key wird der Virtual pfad verwendet.
Jeder Eintrag ist ein Verzeichnis oder ein Stream. Ein Stream kann eine Datei sein, oder eine Datei in einem Zip.
Ein Verzeichnis kann entweder nur Virtual existieren oder auch Physikalisch.

Ich baue einmalig die Hashtable auf indem ich alle Lokalen Verzeichnisse/Dateien und Zip archive darin wiederspiegele.

Danach ist es simpel ich greif dann nur noch auf den Virtual pfad zu und kann ein "GetStream" machen von Stream einträge und bekomme wenn es sich um eine Datei handelt ein FileStream zurück und bei einem Zip ist es ein MemoryStream wo den Entpackten Inhalt im Speicher enthält.



Meine Frage ist nun: Wie setzt man ein OnDemand VFS auf, das genau auf diesen Anwendungsfall passt.

Ich kann bei bedarf wenn das hilft den code (C#) zu meiner VFS implementierung hier posten.


Danke fürs lesen =)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: OnDemand VirtualSystem?
BeitragVerfasst: So Feb 20, 2011 10:18 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Das hat auch technisch wunderbar funktioniert, aber tötete die Performance um mehr als 1000% weil ich jedes Zip archive komplett in meine Interne Hashtable mit allen Ordner und Dateien gepackt habe (Nicht die inhalte der Dateien!!!).

Ist hier eine Hashtable wirklich sinnvoll? Für große Datenmengen ist ein B-Baum meiner Meinung nach besser geeignet. Um die Strings (Pfade) effizienter zu speichern kannst du Prefix- und Suffix-Kompression einsetzen. D.h. das Prefix eines Pfades das bei allen Elementen identisch ist wird nur in den Eltern-Knoten gespeichert. In einem internen Knoten wird nur soviel gespeichert wie notwendig ist um die Verzweigung zu definieren. Erst im Blatt-Knoten wird der Rest des Pfades gespeichert.

Da du aber von einer Webanwendung sprichst....eine nativ implementierte Hashtable kann natürlich trotzdem schneller sein als eigener JavaScript-Code. Hashtablen tendieren aber dazu etwas mehr Speicher zu brauchen, insbesondere weil du nicht komprimieren kannst.

Des weiteren könntest du neben das ZIP-File ein Index-File legen, welches bereits einen fertig sortierten B-Baum (oder Hash-Table) enthält. Ggf. im JSON-Format, das kannst du nativ mit dem Browser parsen. Somit musst du nicht erst die Dateipfade aus dem ZIP extrahieren, sondern kannst direkt mit dem Suchen anfangen.

Wenn kein Index-File existiert oder dieser veraltet ist hast du natürlich das gleiche Problem. Aber nachdem du deinen Index für das ZIP erzeugt hast kannst du diesen als File speichern damit er beim nächsten mal da ist.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: OnDemand VirtualSystem?
BeitragVerfasst: Mo Feb 21, 2011 10:03 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Das mit dem Index File ist eine gute idee.
Wieso bin ich da nicht selbst drauf gekommen...
Danke dafür =)

Kann man eigentlich ein VFS auch mit einer Datenbank implementieren?
Also das man die Tabelle nicht im Speicher hält sondern in der Datenbank und mittels select Query zugreift auf den Pfad der auf die Physikalischen Datei zeigt.

Allerdings habe ich noch nie eine Baumstruktur in eine Datenbank geschrieben, bzw. würde wissen wie man es erstellt aber nicht wie es am effiziensten geht.

Btw. Das ganze läuft alles Server seitig ab (ASP.NET) und nicht über Javascript.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: OnDemand VirtualSystem?
BeitragVerfasst: Mo Feb 21, 2011 11:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Allerdings habe ich noch nie eine Baumstruktur in eine Datenbank geschrieben, bzw. würde wissen wie man es erstellt aber nicht wie es am effiziensten geht.

Wenn wir mal von einer relationalen Datenbank ausgehen (> 95%), dann könnte man dies ungefähr wie folgt machen. Hier mal als Beispiel MySQL.

Wir erstellen zwei Tabellen:
Code:
CREATE TABLE files (
    virtualname TEXT NOT NULL,
    id UNSIGNED NOT NULL,
    isDirectory TINYINT NOT NULL,
    realname TEXT NOT NULL,
    description MEDIUMTEXT,
    PRIMARY KEY(virtualname),
    INDEX files_idx_id(id)
);
CREATE TABLE directories (
    directoryID UNSIGNED NOT NULL,
    fileID UNSIGNED NOT NULL,
    PRIMARY KEY(directoryID)
);


Die erste Tabelle speichert zu jedem virtuellen Dateinamen (Verzeichnisse sind auch Dateien) eine ID und zusätzlich ob es sich um ein Verzeichnis handelt. Außerdem wird noch der reale Pfad und optional eine Beschreibung gespeichert. Der primäre Index (PRIMARY KEY) weißt die Datenbank an die Tabelle nach der Spalte virtualname zu sortieren. Intern handelt es sich um einen B-Baum. Zusätzlich wird ein zweiter Index (auch B-Baum) über die id Spalte erstellt, dieser enthält Zeiger auf die Blattknoten im ersten B-Baum. Damit lassen sich also jetzt effizient virtuelle Dateinamen zu ID's zuordnen und umgekehrt. Wenn benötigt könnte man auch noch weitere Indices erstellen, etwa über realname.

Die zweite Tabelle ordnet einem Verzeichnis die Dateien darin zu. Der Gedanke ist die kurzen 32bit IDs zu benutzen und nicht immer mit langen Dateipfaden zu hantieren.

Um nun auf eine Datei zu zu greifen machst du z.B.:
Code:
SELECT isDirectory,realname FROM files WHERE name = 'c:\mydatastorage\Cat a\Cat aa\Uncompressed Room aaa';


Um die realen Dateien in einem Verzeichnis zu ermitteln könnte man so vorgehen:
Code:
SELECT isDirectory,realname FROM files WHERE id =
    (SELECT fileID FROM directories WHERE directoryID =
        (SELECT id FROM files WHERE name = 'c:\mydatastorage\Cat' and isDirectory='1')
    );


Vielleicht geht es auch eleganter, aber das ist die Lösung die mir nach wenigen Minuten überlegen einfällt. Ausprobiert habe ich das natürlich auch nicht. Aber das sollte einen Überblick geben was so geht. Die SQL-Sprache ist relativ einheitlich, also es ist relativ egal welche Datenbank du benutzt. Es kann aber z.B. Unterschiede bei den Datentypen geben.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: OnDemand VirtualSystem?
BeitragVerfasst: Mo Feb 21, 2011 13:13 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Ah ich glaube du hast mich falsch verstanden.

Ich meinte wie man eine Baumstruktur in einer Datenbank wiederspiegelt.
Also so das du bei / anfängst zu suchen und nur die Ordner von / bekommst,
aber trotzdem an eine Datei direkt rankommst indem du direkt z.b. /bla/blubb/rofl.xml zugreift das dann auf c:\mydatasatorage\bla\blubb\rofl.xml zeigt.

Im grunde fehlt zu deinem Model nur die Parent ID für Directory oder ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: OnDemand VirtualSystem?
BeitragVerfasst: Mo Feb 21, 2011 13:38 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Ah ich glaube du hast mich falsch verstanden.

Möglich.

Zitat:
Also so das du bei / anfängst zu suchen und nur die Ordner von / bekommst,

Genau das ist doch meine zweite SQL-Anfrage. Hier werden alle Dateien und Ordner in einem Ordner gelistet. Mit einem zusätzlichen Test auf isDirectory='1' kann man das auch leicht nur auf Ordner beschränken. Vielleicht verstehe ich aber auch wirklich was falsch.

Für den Fall das du rekursiv alle Dateien&Ordner haben möchtest, du kannst auch eine Bereichsanfrage stellen:
Code:
...WHERE virtualname >= '/bla/blubb/0' and virtualname <= '/bla/blubb/zzzzzzzzzzzzzzzz'

Also so in der Art, müsste man mal genau checken in welcher Reihenfolge Strings verglichen werden. Wahrscheinlich ist das aber einfach ASCII, ggf. den Bereich noch weiter ausdehnen für Sonderzeichen, Umlaute usw.


Zitat:
Im grunde fehlt zu deinem Model nur die Parent ID für Directory oder ?

Das fehlt nicht, sondern ist implizit enthalten. Es werden ja die Verzeichnispfade gespeichert an denen du das Parent-Verzeichnis ablesen kannst. Für bessere Performance könnte man aber in der Tabelle files noch eine Spalte parentID hinzufügen, das ist richtig.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: OnDemand VirtualSystem?
BeitragVerfasst: Di Feb 22, 2011 10:46 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Es macht nicht wirklich Sinn eine Datenbank zu verwenden, da diese nicht so gut performanen wird.
Schau dir lieber mal Dateisysteme an, es gibt in der Linuxwelt mehrere, die auf bestimmte dinge ausgelegt sind. So gibt es welche für schnellen Dateizugriff, welche für übertrieben viele Datein und so weiter.
Mein Vorschlag wäre folgender, nimm ein großen Speicherblock, bau dir ein Informationsknoten(iNode bei ntfs und ext3), dieser enthält die allgemeinen informationen, dann gibt es ein offset zu den Datenblock. iNodes enthalten z.B. einen Namen, Datentyp(file,dir,symlink,hardlink,..), blockcount, dataoffset.
Im Datenblock steht dann der Datei oder Ordnerspezifische kram, wie z.B. welche iNodes liegen im Ordner, Dateigröße, Dateiformat(mime-type bei linux).
Dann kannst du wie bei nem Baum durchwandern, suchen sind schnell, abfrühstücken von speziellen Verhalten sind einfacher(hangelst bis zum file, mimetype sagt dir wie du es behandeln kannst, lädst die Strukturdaten vom Archieve und hangelst dich dort weiter durch).
Leider können die wenigsten Archieveformate streaming, weswegen man große Teile vom Archieve einlesen muss um an die Struktur zu kommen.

edit:Üblicherweise werden iNodes und der Datenbereich voneinander getrennt. Die iNodes hängen zusammen in einem Block,damit man die schnell in den Speicher bekommt(serialisieren) und die Datenblöcke können nachgeladen werden(bei Directory geht Serialisierung bei Files ned). Das erste iNode wäre übrigens "/".

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 10 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 16 Queries | GZIP : On ]