-
Gebiet der
Erfindung
-
Die
Erfindung betrifft Speichersysteme für Computerdaten und -dateien
und eine Struktur zum Indizieren von und Zugreifen auf Daten in
Speichersystemen für
Computerdaten und -dateien, und insbesondere eine neuartige Struktur
zum Umsetzen einer kompakten Darstellung eines 0-kompletten Baums
und eines Verfahrens zum Speichern und Abrufen eines Satzes von
Suchschlüsseln
in solch einer Struktur.
-
Hintergrund
der Erfindung
-
Ein
wiederkehrendes Problem in Speichersystemen für Daten und Dateien wie einer
Datenbank, insbesondere denen, die in Computersystemen umgesetzt
werden, ist die Suche nach und die Ortung von bestimmten Objekten
der Information, die in der Datenbank gespeichert ist. Derartige
Suchen werden allgemein durch Konstruieren eines Datenverzeichnisses
oder Index zu der Datenbank und Verwendung von Suchschlüsseln zum
Durchsuchen des Index umgesetzt, um Zeiger zu den wahrscheinlichsten
Orten der Information in der Datenbank zu finden, ob dieser Ort
innerhalb des Speichers oder des Speichermediums des Computers ist.
-
In
seiner gewöhnlichsten
Form ist ein Index zu Datenbankaufzeichnungen innerhalb eines Computers als
ein Baum strukturiert, der aus einem oder mehreren Knoten besteht,
die durch Zweige verbunden sind, und der innerhalb eines Speichereinrichtungs
des Computers gespeichert ist. Jeder Knoten schließt allgemein
ein oder mehrere Zweigfelder ein, die Information enthalten, um
eine Suche zu leiten, und jedes solches Zweigfeld enthält gewöhnlich einen
Zeiger oder Zweig zu einem weiteren Knoten und einen zugehörigen Zweigschlüssel, der
Bereiche oder Typen von Information anzeigt, die entlang des Zweigs
von dem Knoten geortet werden können.
Der Baum und irgendeine Suche des Baums beginnen bei einem einzigen
Knoten, der als der Wurzelknoten bezeichnet wird und gehen abwärts durch
die unterschiedlichen Zweigknoten voran, bis die Knoten, die entweder
die Objekte der Information oder gewöhnliche Zeiger zu Objekten
der Information enthalten, erreicht werden. Die informationsbezogenen
Knoten werden oft als Blattknoten oder, weil dies die Stufe ist,
bei der die Suche entweder erfolgreich ist oder versagt, als Versagensknoten
bezeichnet. Innerhalb einer Baumspeicherstruktur eines Computers
ist irgendein Knoten innerhalb eines Baums ein Elternknoten mit
Bezug auf alle Knoten, die von dem Knoten abhängen, und Unterstrukturen innerhalb
eines Baums, die von dem Elternknoten abhängen, werden oft als Unterbäume mit
Bezug auf den Knoten bezeichnet.
-
Die
Entscheidung, welche Richtung oder welcher Zweig durch eine Baumspeicherstruktur
in einer Suche genommen werden soll, wird durch Vergleichen des
Suchschlüssels
und der Zweigschlüssel
bestimmt, die in jedem Knoten gespeichert sind, auf den in der Suche
gestoßen
wird. Die Ergebnisse der Vergleiche zu den Zweigen, die von einem
vorgegebenen Knoten abhängen,
werden in dem nächsten
Schritt der Suche befolgt. In dieser Hinsicht bestehen Suchschlüssel meistens
aus einer Zeichenfolge von Buchstaben oder Zahlen, die sich auf
das Objekt oder die Objekte der Information beziehen, die innerhalb
des Computersystems gesucht werden sollen.
-
Der
Stand der Technik enthält
eine Vielzahl von Suchbaumdatenspeicherstrukturen für Computerdatenbanksysteme,
unter denen der offensichtliche Vorgänger, aus dem alle späteren Baumstrukturen
entwickelt wurden und die allgemeinste Form von bekannten Suchbäumen im
Stand der Technik, der „B-Baum" ist (siehe z.B.
Knuth. „The
Art of Computer Programming",
Band 3, Seiten 473–479).
Ein B-Baum sorgt sowohl für
einen zufriedenstellenden primären
Zugriff als auch einen guten sekundären Zugriff auf einen Datensatz.
Deshalb werden diese Bäume
gerne in einer Datenspeicherstruktur verwendet, die oft von Systemen
für Datenbänke und
Dateien verwendet wird. Dennoch gibt es Probleme, die mit der Verwendung
von B-Baumspeicherstrukturen innerhalb von Datenbanksystemen auftreten.
Jeder indizierte Attributwert muss in dem Index selbst nachgebildet
werden. Der kumulative Effekt des Nachbildens vieler sekundärer Indexwerte
ist es, Indizes zu erzeugen, die oft die Größe der Datenbank selbst überschreiten.
Dieser Zusatz kann Datenbankdesigner zwingen, potentiell nützliche
Zugriffswege zu verwerfen. Das Einschließen von Suchschlüsselwerten
innerhalb von Blöcken
des B-Baums verringert außerdem
die Blockauffächerung
beträchtlich
und erhöht
die Baumtiefe und die Abrufzeit.
-
Eine
weitere Baumstruktur, die in Computerdatenbanksystemen umgesetzt
werden kann, kompakte 0-komplette Bäume (d.h. C0-Bäume), beseitigt Suchwerte aus
Indizes, indem sie diese durch kleine Surrogate ersetzt, deren typische
Länge von
8 Bits für
die meisten Schlüssellängen (d.h.
weniger als 32 Bytes) angemessen sein wird. Tatsächliche Werte können somit
irgendwo in willkürlicher
Reihenfolge gespeichert werden, wodurch die Indizes zu der Baumstruktur
als lediglich hierarchische Sammlungen von Paaren (Surrogat, Zeiger) belassen
werden, die in einem Indexblock gespeichert sind. Diese Organisation
kann die Größe der Indizes um
ungefähr
50% bis 80% verringern und erhöht
den Verzweigungsfaktor der Bäume,
was für
eine Verringerung der Anzahl der Plattenzugriffe in dem System pro
Suche nach einer exakten Übereinstimmung
innerhalb der Computerdatenbanksysteme sorgt (Siehe Orlandic und
Pfaltz, „Compact
0-Complete Trees",
Proceedings of the 14th VLDB Conference, Seiten 372–381).
-
Während das
bekannte Verfahren zum Erzeugen von C0-Bäumen die Speicherverwendung
um 50% bis 80% gegenüber
B-Bäumen
erhöht,
gibt es eine Verschwendung von Speicherraum aufgrund des Vorhandenseins
von Fülleinträgen (Surrogat,
Zeiger = NULL), wobei die Anzahl der Indexeinträge auf der niedrigsten Stufe
des Baums die tatsächliche
Anzahl der gespeicherten Einträge übersteigt.
Die erwartete Speicherverwendung der Indexeinträge der C0-Bäume bei
der niedrigsten Baumstufe ist deshalb 0,567 gegenüber 0,693 für den Fall
von B-Bäumen.
-
Obwohl
B-Bäume
und C0-Baumspeicherstrukturen effiziente
Verfahren zum Suchen von Werten darstellen, erfordern beide Verfahren
außerdem
die anfängliche
Erzeugung der Baumdatenspeicherstruktur selbst. Keine dieser Computerspeicherstrukturen
speichert Information inhärent
in geordneter Reihenfolge.
-
Ein
Baum kann effizienter gebildet werden, wenn die Schlüsseleinträge anfänglich in
der Reihenfolge ihres Schlüsselfelds
geordnet werden, dann wenn die Einträge in zufälliger Reihenfolge sind. Ein
effizientes Computerdatenbanksystem sollte deshalb Sätze von
Schlüsseln
zuerst ordnen und dann einen Baum auf Grundlage von Schlüsseln bilden,
die in Intervallen aus den geordneten Schlüsseln extrahiert werden.
-
Wenn
die Werte in geordneter Reihenfolge sind, ist der nächste Schlüsselwert,
der gespeichert werden soll, wahrscheinlich innerhalb des Bereichs
der Schlüsselwerte
für den
gegenwärtigen
Blattindexblock oder Unterbaum. Zusätzlich kann das Indexblockteilen
verschoben werden, bis alte Schüssel
innerhalb eines vorgegebenen Schlüsselintervalls des gegenwärtigen Indexblocks
eingefügt
sind. Deshalb ist es ein Ziel, eine Datenspeicherstruktur und ein
Verfahren zu bilden, das effektiv eine geordnete Auswahl von Schlüsseleinträgen oder
Datenobjekten innerhalb eines Schlüsselbereichsintervalls in möglichst
effekti ver Weise eingibt. Insbesondere sollte die Datenspeicherstruktur
und das Verfahren den verschwendeten Speicherraum verringern und
während
der Eingabe die Suchschlüssel
sortieren, die auf die Datenobjekte zugreifen, die innerhalb des Speichermediums
oder des Speichers des Computers gespeichert sind. Dieses Ziel wird
erreicht, während gleichzeitig
die Vorteile beibehalten werden und die B-Baum- und C0-Baum-Computerspeicherstrukturen
des Besitzers genutzt werden.
-
Das
US-Patent Nr. 5,404,513 offenbart ein Verfahren zum Bilden einer
Datenbank mit Suchbaumknoten mit mehreren Dimensionen. Das US-Patent
4,774,657 offenbart ein Verfahren zum Durchsuchen von Binärbaumindizes
und insbesondere ein Verfahren zum Schätzen der Anzahl der Schlüssel in
einem Indexschlüsselbereich.
-
Es
ist eine Aufgabe der Erfindung, ein Computersystem zu schaffen,
das eine verbesserte Speicherstruktur hat.
-
Gemäß der vorliegenden
Erfindung wird ein Computersystem mit einer Speichereinrichtung
und einer dynamischen Datenspeicherstruktur zum Abrufen gespeicherter
Daten innerhalb der Speichereinrichtung geschaffen, wobei die Speicherstruktur
umfaßt:
eine hierarchische Baumstruktur, die einen kompakten 0-kompletten Binärbaum zum
Identifizieren eines Datenobjekts in den gespeicherten Daten beschreibt,
wobei die hierarchische Baumstruktur Indexblöcke einschließt, die
aus Einträgen
bestehen, die Tiefenwertelemente, entsprechende Datenvorhandenseinsanzeigerbits
und einen Zählwerteintrag
einschließen,
wobei das Tiefenwertelement ein Schlüsselintervall einschließt, wobei
die Datenvorhandenseinsanzeigerbits das Vorhandensein oder Fehlen
eines entsprechenden Zeigers zu einem Datenobjekt in den gespeicherten
Daten anzeigen, und wobei der Zählwerteintrag
für seinen
Indexblock die Anzahl der Datenvorhandenseins anzeigerbits anzeigt,
die das Vorhandensein eines entsprechenden Zeigers zu einem Datenobjekt
in den gespeicherten Daten anzeigen.
-
Gemäß der vorliegenden
Erfindung wird außerdem
ein Verfahren zum Identifizieren eines Datenobjekts geschaffen,
das einem Suchschlüssel
in einem Computersystem entspricht, das eine Speichereinrichtung
und eine dynamische Datenspeicherstruktur zum Abrufen von gespeicherten
Daten innerhalb der Speichereinrichtung hat, wobei die Speicherstruktur
eine hierarchische Baumstruktur umfasst, die einen kompakten 0-kompletten
Binärbaum
zum Identifizieren eines Datenobjekts in den gespeicherten Daten
beschreibt, wobei die hierarchische Baumstruktur Indexblöcke einschließt, die
aus Einträgen
bestehen, die Tiefenwertelemente, entsprechende Datenvorhandenseinsanzeigerbits,
und einen Zählwerteintrag
einschließen,
wobei das Tiefenwertelement ein Schlüsselintervall anzeigt, wobei
die Datenvorhandenseinsanzeigerbits das Vorhandensein oder Fehlen
eines entsprechenden Zeigers zu einem Datenobjekt in den gespeicherten
Daten anzeigen, und wobei der Zählwerteintrag
für seinen
Indexblock die Anzahl der Datenvorhandenseinsanzeigerbits anzeigt,
die das Vorhandensein eines entsprechenden Zeigers zu einem Datenobjekt
in den gespeicherten Daten anzeigen, wobei das Verfahren umfasst:
Bestimmen eines Tiefenwertelements, das ein Schlüsselintervall mit einer Entsprechung
zu dem Suchschlüssel
anzeigt; Bestimmen eines Zählwerts,
der dem Tiefenwertelement entspricht, unter Verwendung der Zählwerteinträge; und
Bestimmen des entsprechenden Zeigers zu dem Datenobjekt in gespeicherten
Daten unter Verwendung des Zählwerts,
der dem Tiefenwertelement entspricht.
-
Eine
Ausführungsform
der vorliegenden Erfindung schafft auch eine zusätzliche Effizienz hinsichtlich der
Speicherverwendung über
die bereits festgestellten Ersparnisse von 50% bis 80% der C0-Bäume
gegenüber
B-Bäumen
hinaus. Um das Problem der Verschwendung zu verringern, das durch
die C0-Bäume
bei den niedrigsten Stufen erzeugt wird, ersetzt eine bevorzugte
Ausführungsform
der Erfindung das Speichern der Einträge (Surrogatenzeiger) als physikalisch
benachbarte Paare von Werten mit zwei getrennten physikalischen
Strukturen innerhalb der Speichereinrichtung des Computers, nämlich 1)
einer Indexblocktiefenstruktur zu einer Liste von Surrogatenwerten,
die einen Tiefenwerte und einen Datenvorhandenseinsstrukturanzeiger einschließt, der
zwei Zustände
hat, und 2) einer Zeigerstruktur, die auf eine Liste von jedem Nicht-NULL-Zeigerwert
zeigt, wobei diese in lexikographischer Reihenfolge sind. In einer
bevorzugten Ausführungsform
der Erfindung wird ein NULL-Zeiger der früheren C0-Baumdatenspeicherstruktur
(d.h. Fülleintrag)
durch ein Datennichtvorhandenseinsanzeigerbit in dem Wert des Surrogats
selbst dargestellt. Die Metadaten von jedem Unterbaum spiegeln auch
den Zählwert
von Nicht-NULL-Einträgen
für jeden
Unterbaum wider, um eine schrittweise lexikalische Position für jeden
indizierten Schlüssel
innerhalb der Zeigerstruktur anzusammeln. Da die Zeigerstruktur
gar keine NULL-Zeiger enthält,
ist nur ein Bit des Speichers notwendig, um einen NULL-Zeiger anzuzeigen,
und minimale Metadaten werden gespeichert. Deshalb neigt die Speicherverwendung
dazu, auf das zurückzugehen,
was für
einen B-Baum erwartet wird.
-
Um
die Ineffizienz des Durchquerens einer mehrstufigen Baumstruktur
zu beseitigen, werden die Schlüssel,
die zu der Datenspeicherstruktur der bevorzugten Ausführungsform
der vorliegenden Erfindung hinzugefügt werden sollen, als eine
Sammlung oder mehr als ein Objekt in geordneter Reihenfolge verarbeitet. Auf
diese Weise kann eine größere Örtlichkeit
des Bezugs und Verringerung beim Durchqueren und der Beibehaltung
der Knoten des Baums (eingeschlossen des Indexblockteilens) von
der Wurzel zu dem Blatt für
jeden Schlüssel
umgesetzt werden.
-
Durch
Bestimmen, ob der nächste
Schlüssel
in dem Schlüsselintervallbereich
des gegenwärtigen
Indexblocks eingeschlossen ist, kann eine Verarbeitung einer vordefinierten
Funktion in dem gegenwärtigen
Indexblock weitergehen oder in seinem Elternblock wiederaufgenommen
werden. Durch dieses neue Verfahren wird das Teilen eines Indexblocks
verschoben, bis die gesamte Verarbeitung des gegenwärtigen Blocks
beendet ist oder die Blockgröße bei einem
extremen Maximum für
einen größeren als
den normalen Schwellwert ist, was somit die Zusammenhangsbeibehaltung
des Unterbaums ermöglicht,
bis alle relevanten Schlüssel
zu dem Unterbaum hinzugefügt
wurden.
-
Noch
weitere Ausführungsformen
der vorliegenden Erfindung werden Fachleuten aus der folgenden detaillierten
Beschreibung sofort offensichtlich werden.
-
Kurze Beschreibung
der Zeichnungen
-
Die
vorhergehenden Beschreibungen und alle Strukturen und Merkmale der
vorliegenden Erfindung und ihrer Ausführungsformen werden aus der
folgenden Beschreibung und den beiliegenden Zeichnungen offensichtlich
werden.
-
1a ist
eine schematische Ansicht und ein Blockdiagramm eines Computersystems,
welches die vorliegende Erfindung umsetzt.
-
1b ist
eine schematische Ansicht und Blockdiagramm eines Datenbanksystems
auf einem Computer zum Umsetzen der vorliegenden Erfindung.
-
2a ist
eine konzeptionelle Darstellung eines kompletten Binärbaums aus
dem Stand der Technik.
-
2b ist
eine konzeptionelle Darstellung eines 0-kompletten Binärbaums aus
dem Stand der Technik.
-
3a ist
ein Diagramm einer C0-Baumindexstruktur
aus dem Stand der Technik für
Werte, die in einer Datenbank gespeichert sind.
-
3b ist
ein Diagramm des C0-Baums aus 3a bevor
das Teilen auftritt.
-
4a veranschaulicht
eine Instantiierung eines C0-Baums der vorliegenden
Erfindung.
-
4b ist
ein detailliertes Diagramm der Inhalte der Speicherbehälter des
C0-Baums aus 4a.
-
5 veranschaulicht
eine beispielhafte Ausführungsform
eines C0-Baums mit drei Stufen gemäß der vorliegenden
Erfindung.
-
6a ist
das Diagramm eines beispielhaften Knotens der Speicherstruktur.
-
6b ist
das Diagramm eines beispielhaften INIT-Knotens.
-
7 ist
ein Flussdiagramm des sequenziellen Verarbeitungsverfahrens der
vorliegenden Erfindung.
-
8 ist
ein Flussdiagramm des Blattsuchverfahrens der vorliegenden Erfindung.
-
9 ist
ein Flussdiagramm des Blatteinfügeverfahrens
der vorliegenden Erfindung.
-
10 ist
ein Flussdiagramm des Zweigsuchverfahrens der vorliegenden Erfindung.
-
11 ist
ein Flussdiagramm des Zweigeinfügeverfahrens
der vorliegenden Erfindung.
-
12 ist
ein Flussdiagramm des Tiefensuchverfahrens der vorliegenden Erfindung.
-
13 ist
eine Figur des Mengenverarbeitungsverfahrens der vorliegenden Erfindung.
-
14 ist
eine Figur der bK-Rücksetzfunktion
der vorliegenden Erfindung.
-
15 ist
ein Flussdiagramm des Tiefenhinzufügeverfahrens der vorliegenden
Erfindung.
-
16a ist ein Flussdiagramm des Wurzelteilungsverfahrens
der vorliegenden Erfindung.
-
16b ist eine Veranschaulichung der Wurzelstufe
vor dem Teilen.
-
16c ist eine Veranschaulichung der Wurzelstufe,
nachdem das Teilen auftrat.
-
17 ist
ein Flussdiagramm des Kindteilungsverfahrens der vorliegenden Erfindung.
-
18 ist
ein Flussdiagramm des Minimaltiefenverfahrens der vorliegenden Erfindung.
-
19 ist
ein Flussdiagramm des Knotenteilungsverfahrens der vorliegenden
Erfindung.
-
Gleiche
Zahlen und Bezeichnungen in den Zeichnungen beziehen sich auf gleiche
Elemente.
-
Detaillierte Beschreibung
-
A) Computersystemübersicht
-
1a veranschaulicht
ein Computersystem, das einen programmierbaren Computer und Computerprogramme
zum Erzeugen eines Dateisystems und zum Verarbeiten von Operationen
auf dem Dateisystem gemäß der vorliegenden
Erfindung hat. Das System schließt einen programmierbaren Computer 1,
eine Anzeige 2, eine Computereingabevorrichtung 3 und
eine Speichereinrichtung ein. Die Speichereinrichtung umfasst eine
Speichervorrichtung 4, wie ein Magnetplattenspeichersystem
oder eine Unterteilung des Speichers des Computers zum Speichern
von Daten. Hardware und Software, die das Dateisystem einschließt, und Hardware
und Software zum Durchführen
von Verarbeitungsoperationen, die beschrieben werden sollen, werden
in einem Dateisystem 5 umgesetzt (das in gestrichelten
Linien gezeigt ist), welches mit dem Computer 1 verbunden
ist. Das System 5 koordiniert die unterschiedlichen Aktivitäten, welche
die Darstellung von Daten in dem Dateisystem betreffen, und das
Durchführen
von Operationen auf einer oder mehreren Da tendateien, die innerhalb
der Speichervorrichtung 4 gespeichert sind, in Verbindung
mit dem Computer 1. Das System 5 kann ein programmierter
Vielzweckcomputer, wie ein Personal-, Mini- oder Großcomputer,
oder ein Spezialzweckcomputer sein, der durch einen oder mehrere
integrierte Chips gebildet wird.
-
Mit
Bezugnahme auf 1b schließt das Dateisystem 5 eine
Dateiverarbeitungseinheit 7 und einen Befehlsübersetzer 6 ein.
Um auf spezielle Objekte der Information zuzugreifen, die auf dem
Computerdateisystem gespeichert sind, verwendet die Dateiverarbeitungseinheit 7 eine
neuartige kompakte 0-komplette Datenspeicherstruktur 40,
wie in 4 dargestellt, um den Betrag
der Information zu minimieren, der erforderlich ist, um Objekte
der Daten aufzufinden, die innerhalb der Speichervorrichtung 4 gespeichert
sind. Die Datenspeicherstruktur hat mehrere Einträge 30, 31, 80, 81, 82, 83, 84, 85, 86, 87, 88 zum
Indizieren von Suchschlüsseln 1420,
wobei jeder Eintrag einen Tiefenwert 89 und einen Datenvorhandenseinsanzeiger 90 umfasst,
wobei der letztere beispielsweise zwei Zustände hat, und eine neuartige
C0-Baumstruktur 43, die in der
Speichervorrichtung 4 des Computers gespeichert ist, der
die Einträge
verbindet und die Datenspeicherstruktur 40 bildet. Die
Datenspeicherstruktur 40 schließt außerdem ein Mittel 66 zum
Speichern des Zählwerts
der Nicht-NULL-Blatteinträge
ein, die zu einem Suchschlüsselintervallbereich
gehören.
Zusätzlich
verwendet die vorliegende Erfindung eine getrennte Zeigerstruktur,
die einen Kopf 36 und Einträge 36a umfasst, die
von der Baumstruktur 43 verschieden ist und in einer typischen
Ausführungsform
von der Datenspeicherstruktur 40 selbst verschieden sein
kann. Die Zeigerstruktur 36 und 36a greifen auf
die Datenobjekte innerhalb des Speicherbehälters 39 der Speichervorrichtung 4 zu.
-
Die
beschriebene Ausführungsform
der vorliegenden Erfindung schließt neuartige Verfahren zum Speichern,
Zugreifen auf und Abrufen von Daten ein, die durch die Baumdatenspeicherstruktur
indiziert sind. Diese Verfahren schließen ein Verfahren zum sequenziellen
Verarbeiten einer Anzahl Suchschlüssel innerhalb der Baumstruktur,
um eine vorbestimmte Funktion für
jeden Suchschlüssel
durchzuführen,
ein Verfahren zum Orten eines Suchschlüssels innerhalb der Baumstruktur
und ein Verfahren zum Speichern und Indizieren von Information für jeden
Suchschlüssel
innerhalb der Baumstruktur und ein Verfahren zum Teilen eines Indexblocks
der vorliegenden Erfindung ein.
-
B) Baumstrukturen aus
dem Stand der Technik
-
Mit
Bezugnahme auf 2a und 2b ist
ein kompletter Binärbaum
aus dem Stand der Technik beziehungsweise ein 0-kompletter Binärbaum und die Verwendung dieser
Bäume gezeigt,
um Daten zu indizieren.
-
1) Kompletter Binärbaum
-
Nun
mit Bezugnahme auf 2a ist ein Binärbaum 1402 eine
veranschaulichte Baumdatenspeicherstruktur mit benannten Kanten,
die aus Knoten besteht, die durch Punkte, wie 1406, 1408 und 1410,
bezeichnet sind und durch Bögen
oder Kanten wie 1412 und 1414 getrennt sind. Die
Knoten werden durch Klein- und Großbuchstaben a bis Z und A' identifiziert. Die
Endknoten werden Blattknoten oder Blätter genannt und mit Großbuchstaben
benannt. Alle weiteren inneren Knoten werden mit Kleinbuchstaben
benannt. Information, die abgerufen werden soll, ist an Speicherorten
gespeichert, auf die durch Zeiger gezeigt wird, die sich bei den Baumblättern wie
den Blättern 1416 und 1418 befinden.
Suchschlüssel 1420 sind
für die
Blätter
H, I, V, W, L, Z, A' und
Q gezeigt. In 2a sind die Suchschlüssel 1420 Zeichenketten
von Binärstellen
mit einer willkürlichen
uniformen Länge
bis zu irgendeiner maximalen Länge
in Bits, wobei beispielsweise 8 Bits verwendet werden. Die Suchschlüssel 1420,
die zu jedem dieser Blätter
gehören,
werden verwendet, um die Zeiger zu dem Speicherort für das entsprechende
Blatt in der Speichervorrichtung 4 zu orten. Nur diese
Blätter,
die durch einen zugehörigen
Suchschlüssel 1420 angezeigt
werden, haben einen Zeiger zu einem Speicherort, der zugehörige Dateneinträge speichert,
und werden deshalb als voll bezeichnet. Die Blätter G, K, O, S, T und Y haben keine
Zeiger zu einem Speicherort und werden deshalb als leer bezeichnet.
-
Das
Abrufen der Dateneinträge
in der Speichervorrichtung 4 wird durch sukzessives Vergleichen
von den binären
Symbolen 0 und 1 in einem der Suchschlüssel 1420 mit einer
Benennung 0 oder 1 der Kante auf jedem Bogen 1412 zwischen
den Knoten entlang eines Wegs der verbundenen Punkte und Bögen erreicht, wobei
mit dem Knoten a begonnen und mit dem gewünschten Blatt geendet wird.
Jeder Knoten oder jedes Blatt des Binärbaums ist entweder ein 0-Knoten
oder 0-Blatt, wenn der Startbogen 0 benannt ist, oder ein 1-Knoten
oder 1-Blatt, wenn der Startbogen 1 benannt ist. In einer Computerdatenbank
und einem Dateiverwaltungssystem ist ein Zugriffsweg zu einem Knoten
eine binäre
Zeichenkette, die durch Verketten der Kantenbenennungen 0 und 1 erhalten
wird, die von dem Wurzelknoten zu einem bestimmten fraglichen Knoten durchquert
werden.
-
Binärbaumstrukturen
werden „komplett" genannt, wenn jeder
Knoten entweder ein Blatt ist oder ein Knoten, der genau zwei nicht-leere
direkte Nachfolger hat (d.h. Knoten haben einen abhängigen 0-Knoten
und einen abhängigen
1-Knoten). In 2a erfüllt jeder Knoten vom Knoten
a zum Knoten A' die
zwei Bedingungen der 0-Komplettheit.
-
Somit
veranschaulicht 2a eine Baumspeicherstruktur
mit den Suchschlüsseln 1420,
die 00001000, 00100101, 01000010, 01000110, 1000001, 10101000, 10101010
und 10110010 einschließen,
um die Dateneinträge
bei den Blättern
H, I, V, W, L, Z, A' beziehungsweise
Q zu orten. Leere Blätter
G, K, O, T, S und Y sind innerhalb des Baums 1402 eingeschlossen,
um die Anforderung eines „kompletten" Binärbaums zu erfüllen.
-
2) 0-kompletter Binärbaum
-
Nun
mit Bezugnahme auf 2b ist ein 0-kompletter Binärbaum 1430 aus
dem Stand der Technik gezeigt, der die gleiche Struktur, Nomenklatur
und Bezugszeichen, wie in 2a verwendet,
hat, außer
es ist angemerkt. Der Binärbaum 1430 mit δ-Blättern wird
0-komplett genannt, wenn 1) das Geschwister von jedem 0-Blatt in dem Baum
vorhanden ist, und 2) es genau δ-1
1-Knoten in dem Baum gibt. Somit ist 2b eine Darstellung
eines 0-kompletten
Binärbaums
des Binärbaums
aus 2a, da jedes 0-Blatt H, V, L, T, C einen 1-Geschwisterknoten
hat, und es neun Blätter
H, I, V, W, L, T, Z, A' und
Q und acht 1-Knoten I, W, e, c, m, A', U und Q gibt. Der 0-komplette Baum 1430 wird
von dem Binärbaum 1402 aus 2a abgeleitet,
indem von dem Baum 1402 diese 1-Blätter gelöscht werden, die leer sind
(angezeigt durch das Fehlen eines zugehörigen Suchschlüssels) wie
die Blätter
G, K, O, S und Y. Anzumerken ist, dass das Löschen eines leeren 0-Blatts
die zweite Bedingung verletzt, die acht 1-Knoten im Baum 1430 erfordert,
so dass der Knoten T, obwohl er leer ist, in der Baumspeicherstruktur 1430 bleibt
und den erforderlichen Speicherraum erhöht.
-
Jeder
innere Knoten, der durch Kleinbuchstaben bezeichnet ist, hat einen
entsprechenden 0-Unterbaum und einen 1-Unterbaum. Die „vorsinnige
Durchquerung" eines
0-kompletten Baums beginnt bei dem Wurzelknoten a des Baums und
wiederholt dann die folgenden zwei Schritte, bis auf die letzten
Knoten zugegriffen wurde:
- 1) wenn der gegenwärtige Knoten
nni ein interner Knoten ist, dann wird der
nächste
Knoten nni+1 in der Reihenfolge sein 0-Sohn wegen der Definition
der 0-Komplettheit sein, daß jeder
innere Knoten einen 0-Sohnknoten haben muss;
- 2) wenn der gegenwärtige
Knoten nni ein Blatt ist, dann wird der
nächste
Knoten in der Vorreihenfolge der 1-Sohn des Knotens pp sein, dessen
0-Unterbaum nni enthält und dessen Tiefe maximal
ist.
-
Der
erste Knoten in der Vorreihenfolge ist somit der interne Wurzelknoten
a. Der nächste
Knoten ist sein 0-Sohnknoten b, auf den der 0-Sohnknoten d und dann
das Blatt H folgen. Der nächste
Knoten in der Vorreihenfolge ist der 1-Sohn des Knotens d, da H
ein Blattknoten ist und der 0-Unterbaum des Knotens d H enthält und seine
Tiefe in dem Baum maximal ist (d.h., eine Tiefe von 2 im Gegensatz
zum Knoten b, dessen Unterbaum H enthält und dessen Tiefe 1 ist).
Die komplette vorsinnige Durchquerung des Baums 1430, der
in 2b dargestellt ist, ist die Folge a, b, d, H,
I, e, j, n, r, V, W, c, f, L, m, p, T, u, x, Z, A', Q.
-
Vorgängerknoten
für jeden
Blattknoten H, I, V, W, L, T, Z, A' außer
dem letzten Blattknoten Q in der vorsinnige Durchquerung eines 0-kompletten
Baums sind auch von besonderer Bedeutung. Diese Knoten, die als
Randknoten bezeichnet werden, sind I, e, W, c, m, u, A' bzw. Q in 2b.
Da Randknoten mit Bezug auf die vorsinnige Durchquerung definiert
sind, hat jeder Blattknoten außer
dem letzten Q seinen eigenen einmaligen Randknoten. Zusätzlich zu
der vorher genannten Definition der vorsinnigen Durchquerung ist
jeder Randknoten ein 1-Knoten.
-
2a) Schlüsselintervalle
-
„Diskriminatoren" eines Knotens und
eines Randknotens können
verwendet werden, um ein Schlüsselintervall
einzurichten, das jedem Blatt in dem 0-kompletten Baum entspricht.
Der „Diskriminator" eines Blattknotens
ist eine binäre
Zeichenkette der gleichen Länge
wie die Suchschlüssel
und dessen Bits hoher Ordnung oder am weitesten links die binären Bits
der verketteten Bögen
oder des Wegs sind, der zu dem Blatt mit allen weiteren Bits am
weitesten rechts führt,
die 0-gesetzt sind.
-
Das „Schlüsselintervall" ist formal als der
Schlüsselbereich
zwischen dem Blattdiskriminator (eingeschlossen) und dem Diskriminator
seines Randknotens (nicht eingeschlossen) definiert. Die Ausnahme
ist wiederum das letzte Blatt (Q z.B.) bei der vorsinnigen Durchquerung,
dessen oberer Rand des Schlüsselintervalls immer
im Voraus bekannt ist und aus allen Eins-Bits besteht (d.h. 11111111).
-
In
Tabelle 1 sind die Schlüsselintervalle
von jedem Blattknoten H, I, V, W, L, T, Z, A', Q des 0-kompletten Baums 1430 in
lexikographischer Reihenfolge aufgelistet. Somit hat zum Beispiel
das Blatt V einen Diskriminator 01000000 und sein entsprechender
Randknoten hat einen Diskriminator 01000100; das Schlüsselintervall
des Blatts V ist wie in Tabelle 1 gezeigt, 01000000 (eingeschlossen)
bis 01000100 (nicht eingeschlossen) oder 01000000 bis 01000011 eingeschlossen.
-
Durch
das Untersuchen der Tabelle 1 ist die Kenntnis von Randknotendiskriminatoren
ausreichend, um das geeignete Schlüsselintervall von irgendeinem
Blatt und deshalb dem entsprechenden Dateneintrag mit irgendeinem
vorgegebenen Suchschlüssel
zu identifizieren. Beispielsweise wird unter Verwendung des Suchschlüssels 01000010
ein Suchverfahren, das die Randdiskriminatoren des Baums in ihrer
vorsinnige Durchquerungsfolge untersucht, das korrekte Schlüsselintervall
für den
Suchschlüssel
finden, wenn gefunden wird, daß der
erste Randdiskriminator größer als
der Suchschlüssel
01000010 ist. Der Diskriminator des ersten Randknotens I, 00100000,
ist kleiner als der Suchschlüssel
01000010. Der zweite Randdiskriminator des Randknotens e in der
Vorreihenfolge, 01000000, ist auch kleiner als der Suchschlüssel. Der
Diskriminator des dritten Randknotens W, 01000100, ist größer und
ist der nicht eingeschlossene obere Rand des Schlüsselintervalls
für das
Blatt V. Der eingeschlossene untere Rand des Schlüsselintervalls
für das
Blatt V ist der Diskriminator des vorhergehenden Randknotens e.
-
Zusammen
mit jedem Schlüsselintervall
in Tabelle 1 ist eine Zahl gezeigt, welche die „Tiefe" des Randknotens in dem 0-kompletten Baum 1430 für dieses
Schlüsselintervall
bezeichnet. Zum Beispiel ist der Randknoten des Blatts V das Blatt
W, das eine Tiefe von 6 in dem 0-kompletten Binärbaum hat. Für den letzten
Knoten Q, der definitionsgemäß keinen
Randknoten hat, ist der obere Rand seines Intervalls auf 11111111
mit einer zugeordneten Tiefe von 0 eingestellt.
-
Es
gibt eine offensichtliche Regelmäßigkeit
in der Beziehung zwischen Diskriminatoren eines Satzes Randknoten
und ihren Tiefen. Wenn die Tiefe eines Randknotens dd ist, dann
ist gemäß der Definition
eines Diskriminators das dd-te Bit des entsprechenden Diskriminators
auf 1 mit allen darauf folgenden Bits niedriger Ordnung 0 gesetzt.
-
In
Tabelle 1, wo die Schlüssellänge 8 Bits
ist, ist der anfängliche
Fülldiskriminator
00000000 und die Tiefe des ersten Randknotens I 3. Das dritte Bit
des ersten Randknotendiskriminators ist 1 und alle darauf folgenden
Bits niedriger Ordnung sind 0, um den Diskriminator 00100000 des
ersten Randknotens zu erhalten; die Tiefe des zweiten Randknotens
e ist zwei, unter Verwendung des Diskriminators des ersten Randknotens wird
das zweite Bit 1 gesetzt und werden alle darauf folgenden Bits 0
gesetzt, um den Diskriminator 01000000 des zweiten Randknotens zu
erhalten.
-
Die
Diskriminatoren des Rests der Randknoten sind auf ähnliche
Weise konstruiert.
-
3) C0-Bäume aus
dem Stand der Technik
-
Unter
Verwendung der Kenntnis, dass die Schlüsselintervalle aus Tiefen von
Randknoten in einem 0-kompletten Binärbaum konstruiert werden können, ist
eine kompakte Form aus dem Stand der Technik des 0-kompletten Baums
aus 2b bei 9 in 3a dargestellt.
Diese kompakte Form wird ein C0-Baum genannt. Die
Baumstruktur hat Indexblöcke 10, 11 und 12 mit
Einträgen 17.
Wenn ein C0-Baum gebildet wird, ist die
Maximalzahl der Einträge 17 in
einem Indexblock immer kleiner als oder gleich einer vorbestimmten
Indexblockvollzahl 14. Unter der Annahme einer vorbestimmten
Indexblockvollzahl 14 von 5 in 3a soll
nun betrachtet werden, wie die Baumstruktur 9 den 0-kompletten Binärbaum aus 2b darstellt.
Jeder Eintrag 17 der Indexblöcke 10, 11 und 12 hat
einen Tiefenwert 17a und einen Zeiger 17b zu einem
Speicherort 13. Die einzige Ausnahme wäre ein NULL-Eintrag wie 17b', der ein leeres
Blatt oder einen Knoten aus 2b, wie
ein Blatt T darstellt. Dieser Eintrag 17b' hat einen leeren Zeiger 17b mit
keinen entsprechenden Daten, die im Speicher gespeichert sind, und
verschwendet Speicherraum innerhalb des Computersystems.
-
In 3a mit
Bezug auf Tabelle 1 sind beispielsweise die Tiefenwerte 3, 2, 6,
1 der Randknoten I, e, W, c, die den Blättern H, I, V, W entsprechen,
im Indexblock 11 gespeichert. Die Tiefenwerte 3, 5, 7,
4 der Randknoten m, u, A',
Q, die den Blättern
L, T, Z, A' und
dem zugehörigen
Tiefenwert von 0 für
den letzten Blattknoten Q entsprechen, sind in dem Indexblock 12 gespeichert.
Der Zeiger 17b von jedem Eintrag 17 zeigt zu einem Speicherort 13,
der einen Suchschlüssel
und seinen zugehörigen
Dateneintrag im Speicher oder in der Speichervorrichtung ent spricht,
außer
dem leeren Zeiger 17b des Eintrags 17b', der einem
leeren Blatt T aus 2b entspricht. Der Wurzelindexblock 10 hat
Einträge 17 mit
Zeigern 17b, die auf einen bestimmten Blattindexblock 11 und 12 zeigen.
Der Tiefenwert 17a eines jeden Eintrags 17 des
Indexblocks 10 entspricht dem letzten oder minimalen Tiefenwert
1 und 0 eines jeden entsprechenden Blattindexblocks 11 und 12 und
sorgt für
den Schlüsselintervallbereich
von jedem Blattindexblock 11 und 12.
-
Nun
wird das bekannte Verfahren zum Teilen eines vollen Indexblocks
eines kompakten 0-kompletten Baums, wie in 3b gezeigt,
betrachtet, wobei die ersten sechs Suchschlüssel in lexikographischer Reihenfolge
indiziert wurden. Bei diesem Punkt ist die Baumstruktur ein einzelner
Indexblock 19, der sechs Einträge 17 hat und eine
kompakte Darstellung eines konzeptionellen 0-kompletten Binärbaums ist,
der sechs Indexsuchschlüssel
für Blattknoten
00001000, 00100101, 01000010, 01000110, 10000001, 10101000 hat.
Sobald der sechste Suchschlüssel
10101000 in der Reihenfolge indiziert ist, wird die vorbestimmte
Indexblockvollzahl 14 von fünf überschritten, und eine Teilung
des Indexblocks 19 muss auftreten. Die Teilung tritt bei
einer minimalen Tiefe der Tiefenwerte 17a des Indexblocks 19 auf,
die 1 ist. Die Teilung erzeugt einen Wurzelindexblock 20,
einen Blattindexblock 21, der Tiefenwerte 17a von
3, 2, 6 und 1 hat, und einen Blattindexblock 24, der Tiefenwerte 17a von
3 und 0 hat. Nach dem Teilen besteht der Elternindexblock 20 aus
zwei Einträgen 17.
Der erste Eintrag 22 hat einen Tiefenwert 17a von
1, welcher der Randknotentiefe eines Indexsuchschlüssels für Blattknoten
01000010 in einem konzeptionellen 0-kompletten Binärbaum nach
Eingabe der gleichen sechs Suchschlüssel entspricht, und der zweite
Eintrag 23 hat einen Tiefenwert 17a von 0, der
immer der zugewiesene Wert des letzten Blattknotens in der Vorreihenfolge
eines 0-kompletten Binärbaums
ist. Die Zei ger 17b der Einträge 22 und 23 zeigen
auf die Indexblöcke 21 bzw. 24.
-
B) Kompakte 0-komplette
Datenspeicherstruktur der vorliegenden Erfindung
-
Mit
Bezugnahme auf 4a ist nun eine Darstellung
der Datenspeicherstruktur 14 einer Ausführungsform der vorliegenden
Erfindung nach der Eingabe des gleichen Satzes Suchschlüssel 1420 wie
in 2a, 2b, 3a veranschaulicht.
Eine größere Anzahl
Suchschlüssel
kann in die Datenspeicherstruktur 40 eingegeben werden,
und es wäre
innerhalb des Könnens
eines Fachmanns, die beschriebene Ausführungsform für einen
größeren Satz
Schlüssel
anzuwenden. Im Gegensatz zu dem C0-Baum
aus 3a, der Blöcke 10, 11 und 12 mit
benachbarten Einträgen
von Tiefenwerten 17a und Einträgen 17 von Zeigern 17b hat,
hat die Datenspeicherstruktur aus 4 eine
Baumstruktur 43, die aus einem Wurzelknoten 47 mit
einem Indexblockkopf 47a, der zu Indexblockeinträgen 47c und
einem Unterbaumzeiger 47b indiziert ist, einem Knoten 34 mit einem
Indexblockkopf 34a, der mit Indexblockeinträgen 34c und
einem Unterbaumzeigern verbunden ist, und einem Knoten 35 mit
einem Indexblockkopf 35a, der mit Indexblockeinträgen 35c und
einem Unterbaumzeiger 35b verbunden ist, besteht.
-
Jeder
Eintrag in 47c, 34c und 35c enthält einen
Tiefenwert 89 und einen Datenvorhandenseinsanzeiger 90.
Zusätzlich
hat die Struktur 40 eine getrennte Zeigerstruktur, die
aus einem Zeigerkopf 36 mit entsprechenden Einträgen 36a besteht,
welche die Zeiger oder verweisbaren Indizes für entsprechende Tiefenwerte 89 der
Blattindexblockeinträge 34c und 35c enthalten,
die Nicht-NULL sind.
Die Tiefenwerte 89 in 34c und 35c und
die Indizes der Zeigereinträge 36a sind
für die
Tiefenwerte 17a und Zeiger 17b in Indexblöcken 11 und 12 aus 3a repräsentativ,
außer dass
leere Zeigern, die 0-Blatteinträgen
wie einem Blatt T entsprechen, ausgeschlossen sind, wodurch verschwendeter
Speicherraum verringert wird. Die Indexblockeinträge 47c des Knotens 47 schließen Einträge 30 und 31 ein,
die den Einträgen
im Indexblock 10 aus 3a entsprechen, welche
die letzten, d.h. Einträge
des minimalen Tiefenwerts, in den entsprechenden Indexblöcken 34c bzw. 35c ergeben.
Der Zeiger 47b der Wurzelstufe 41 zeigt zu der
Blattstufe 64 für
Schlüsselintervalle,
die jedem der Indexblockeinträge 47c entsprechen.
-
Zusätzlich zu
der Zerlegung der entsprechenden Tiefenwerte 89 in Indexblockeinträge 47c, 34c und 35c und
Zeigereinträge 36a wird
auf den Zählerkopf 66 mit
entsprechenden Einträgen 66a Bezug
genommen. Die Einträge 66a enthalten
Zählwerteinträge 32 und 33,
welche die Gesamtzahl von F oder volle Blatteinträge (Nicht-NULL)
in Indexblockeinträgen 34c bzw. 35c ergeben.
Somit hat der Zählwerteintrag 32 einen
Wert von 4, der anzeigt, dass es vier Nicht-NULL-Einträge 4 (oder
F-Werte) in Indexblockeinträgen 34c gibt.
Der Zählwerteintrag 33 hat
einen Wert von 4, der anzeigt, dass es vier Nicht-NULL-Einträge (oder
F-Werte) in den
Indexblockeinträgen 35c gibt.
Somit hat die Datenspeicherstruktur 40 eine neuartige C0-Baumstruktur 43, eine verschiedene
Zeigerstruktur 36 und 36a und einen Speicherbehälter 39.
Die Knoten 34, 35 und 47 und der Zählwertkopf 66 und
die Zählwerteinträge 66a sind
in der Baumstruktur 43, während die verweisbaren Indizes oder
Zeiger in der getrennten Zeigerstruktur sind, die aus dem Kopf 36 und
Einträgen 36a besteht.
-
Die
Baumstruktur 43 in dem Beispiel aus 4 hat
eine Höhe
von 2, Wurzelstufe 41 und Blattstufe 64. Indexblockeinträge 47c bei
der Wurzelstufe 41 schließen zwei Einträge 30 und 31 ein
und Strukturen 34c und 35c der Indexblockeinträge bei der
Blattstufe 64 schließen
vier Einträge 80, 81, 82, 83 bzw.
fünf Einträge 84, 85, 86, 87, 88 ein.
Die Höhe
oder Anzahl der Stufen einer C0- Baumspeicherstruktur
variiert abhängig
von der Anzahl der Datenobjekte und zugeordneten Suchschlüssel, die
innerhalb der Blatteinträge
der Baumstruktur 43 indiziert werden sollen, und von einer
vorbestimmten Indexblockvollzahl 79, die innerhalb des
Dateisystems gesetzt ist. Die beschriebene beispielhafte Ausführungsform
aus 4 hat eine vorbestimmte Indexblockvollzahl 79 von
5.
-
Tiefenwerte 89 befinden
sich in Indexblockeinträgen 47c, 34c, 35c,
die durch Indexblockköpfe 47a, 34a und 35a innerhalb
der Knoten 47, 34 bzw. 35 der Baumstruktur 43 verbunden
sind. Zeigereinträge 36a sind
mit der Baumstruktur 43 durch den Zeigerkopf 36 verbunden.
Bedeutsamerweise ist das Datenvorhandenseinsanzeigerbit 90 auch
in jedem der Indexblockeinträge 47c, 34c und 35c.
-
Jedes
Anzeigerbit 90 ist in einem der zwei Zustände F oder
T, die durch 0 beziehungsweise 1 dargestellt werden. In Tiefenwerten 89 bei
der Blattstufe 64 zeigt ein T oder erster Zustand an, dass
der entsprechende Eintrag ein NULL-Eintrag des C0-Baums
aus 3 oder ein leerer Knoten eines
konzeptionellen 0-kompletten
Binärbaums
wie eines Blatts T beim Tiefenwert 5 in 2a und 2b ist.
Ein F- oder zweiter Zustand zeigt den entsprechenden Eintrag an,
der zu einem entsprechenden Datenobjekt in der Speichervorrichtung
des Computers gehört,
wie Einträge 80 bis 84 und 86 bis 88,
die Blättern
H, I, V, W, L, Z, A' und
Q aus den 2a und 2b entsprechen.
Jeder der Nicht-NULL-Einträge 80 bis 84 und 86 bis 88 hat
ein entsprechendes Datenobjekt innerhalb des Speicherbehälters 39 des
Speichers 8 des Computers, der mittels einer der Zeigereinträge 36a adressiert
wird. Ein NULL- oder T-Eintrag wie 85 adressiert nicht
irgendeinen Indexeintrag in 36a oder irgendein Datenobjekt
in dem Speicherbehälter 39.
Jeder der Zeigereinträge 36a ist
ein Zeiger oder verweisbarer Index zu dem entsprechenden lexikalisch
geordne ten Datenobjekt oder alternativ zu einem der Suchschlüssel 1420,
der dem Datenobjekt zugeordnet ist, das innerhalb der Speichervorrichtung
des Computers gespeichert ist.
-
Es
wird die Datenspeicherstruktur des kompakten 0-kompletten Baums 40 mit
Bezug auf ihre Komponentendatenstrukturen betrachtet. 6a ist
ein beispielhaftes Diagramm der Struktur von jedem Knoten innerhalb
eines Computersystems. Knoten 34 ist beispielhaft gezeigt,
die weiteren sind identisch. Knoten 34 besteht aus 2 Strukturen.
Jede Struktur besteht aus einem Kopf zu einer Liste mit Einträgen 34c,
aber jede Struktur kann ein Feld oder irgendeine andere Form einer
Datenstruktur sein. Eine Struktur hat einen Abbildungskopf 34a,
der zu einer Liste mit Einträgen 34c zeigt,
und die andere ist ein zusammengesetzter Unterbaumzeiger 34b,
der zu einer Liste mit Elementen zeigt, die aus weiteren Listen
bestehen können.
-
Der
zusammengesetzte Kopf C, der jedem Indexblock zugeordnet ist, zeigt
zu der nächsten
niedrigeren Stufe, der Baumstruktur 43, wenn es irgendeine
gibt. Somit zeigt in 4 der zusammengesetzte
Kopf 47b zu einem Unterbaum der Kindknoten 34 und 35 in
einem Zweig. Jeder Zweig kann einen zusammengesetzten Kopf enthalten,
der zu einer niedrigeren Stufe des Baums zeigt, oder nicht. Wenn
der zusammengesetzte Kopf C nicht leer ist, wie im Knoten 47,
ist der Knoten 47 ein Zweigknoten vom Typ INNERER oder WURZEL.
Bei einer Blattstufe der Baumstruktur hängen keine Kinderknoten oder
Unterbäume
von den Knoten ab, und die entsprechenden zusammengesetzten Köpfe sind
leer, wie bei den Knoten 34 und 35 veranschaulicht,
wo die zusammengesetzten Zeiger 34b bzw. 35b zu
keiner weiteren Stufe des Baums zeigen. Zusammengesetzte Köpfe geben
einem Unterbaum seine Struktur, indem sie mehrere Stücke aufeinander
verwiesener Information zusammen gruppieren. In einer anfänglichen
Struktur 40' vom
Typ INIT, wie in 6b, zeigt der Abbildungskopf 47a' des Knotens 47' zu einem Eintrag
mit einem Tiefenwert 89' von
0 und einem Anzeigerbit 90',
das auf die erste Bedingung T oder NULL-Bedingung T gesetzt ist,
die anzeigt, dass es kein entsprechendes Datenobjekt für diesen
Eintrag in dem Speicherbehälter 39' gibt, bevor
irgendwelche Nicht-NULL-Werte hinzugefügt wurden.
-
Das
erste Element, zum Beispiel 42 in 4 der
zusammengesetzten Struktur ist bei der Wurzelstufe immer leer und
ist nur reserviert, so dass der Grundriss der zusammengesetzten
Struktur der Wurzelstufe den verschiedenen Unterstufen des Baumes ähnlich ist,
und für
den Fall, dass eine neue Wurzelstufe erzeugt werden muss, wenn der
Wurzelindexblock 47a des Knotens 47 übervoll
wird, wie wenn die Anzahl der Einträge 47c, die mit dem
Kopf 47a des Wurzelindexblocks verbunden sind, die vorbestimmte
Indexblockvollzahl 79 von fünf überschreitet. Der Zweck des
ersten Elements 42 auf den tieferen Stufen, die eine andere
als die Wurzelstufe des Baums sind, muß erklärt werden.
-
Das
vierte Element bei der Wurzelstufe 41 ist der Zeigerkopf 36,
der zu einer Liste mit Zeigereinträgen 36a zeigt. Das
fünfte
Element, das in 4 veranschaulicht
ist, ist ein Speicherbehälter 39 im
Speicher 8 oder der Speichervorrichtung 4 des
Computers, in dem die tatsächlichen
Datenobjekte der Information gespeichert sind. Datenobjekte können irgendeine
Form von Daten sein, die durch ein Computersystem gespeichert werden
können.
Jeder der Einträge 36a entspricht
einem der Indexblockeinträge 34c und 35c.
Jeder Eintrag der Einträge 36a enthält einen
verweisbaren Index oder einen Zeiger zu einem Datenobjekt im Behälter 39.
-
Die
letzten zwei Elemente 36 und 39 sind von der Baumstruktur 43 getrennt
und können
als verschiedene unterschiedliche Verfahren ausgeführt sein.
Im Gegensatz zu der in 4 beschrie benen
Ausführungsform
können
die zwei Elemente in einer unterschiedlichen zusammengesetzten Zeigerstruktur
abgelegt werden, die physikalisch nicht mit der Baumstruktur 43 benachbart
ist.
-
Die
Suchschlüssel 1420 und
die Datenspeicherstruktur 40 sind so organisiert, dass
das Dateisystem angeforderte Objekte einfach und effizient finden
kann. Wie in 4b gezeigt, enthält der Speicherbehälter 39 Datenobjekte,
die durch Suchschlüssel
in irgendeiner Reihenfolge dargestellt werden. Ein lexikalisch geordneter
verweisbarer Index oder Zeiger für
jeden Suchschlüssel
ist in Zeigereinträgen 36a abgelegt.
Schließlich adressiert
jeder Index oder Zeiger den Ort eines Datenobjekts im Behälter 39.
Eine Anzahl Objekte, die gleichzeitig eingefügt werden sollen, werden erst
innerhalb eines Puffers lexikalisch geordnet, dann in irgendeiner Ordnung
in dem Behälter 39 gespeichert.
Das Speichern der Datenwerte kann durch verschiedene Verfahren ausgeführt werden,
die einem Fachmann bekannt sind.
-
Zurück zur Baumstruktur 43 ist
das erste Element 66 der zusammengesetzten Struktur auf
irgendeiner Stufe wie der Stufe 64 außer der Wurzelstufe 41 ein
Zählwertkopf
zu Zählwerteinträgen 66a,
um aus den Anzeigern 90 Nutzen zu ziehen. Jeder der Zählwerteinträge 66a,
wie die Einträge 32 oder 33,
ist ein Zählwert
von Nicht-NULL-Blatteinträgen,
die einen Anzeiger 90 haben, der auf F gesetzt ist, in
den entsprechenden Indexblockeinträgen 34c und 35c innerhalb
der Unterbaumstufe 64, die mit dem Knoten 47 durch
den zusammengesetzten Kopf 47b verbunden ist. Da es zwei
Knoten 34 und 35 bei der Stufe 64 in 4 gibt, enthält die Zählwertstruktur genau zwei Einträge 32 und 33.
Der erste Eintrag 32 entspricht dem Zählwert der Indexblockeinträge 34c und
der zweite Eintrag 33 entspricht dem Zählwert der Indexblockeinträge 35c.
Da die ersten Indexblockeinträge 34c vier
Nicht-NULL-Einträge
oder F-Einträge 80, 81, 82, 83 einschließen, enthält der erste Eintrag 32 der
Zählwertstruktur
einen Zählwert
von 4. Da die zweiten Indexblockeinträge 35c vier Nicht-NULL-Einträge 84, 86, 87, 88 einschließen, hat
der zweite Eintrag 33 einen Zählwert von 4. Der Zählwert von
Nicht-NULL-Blatteinträgen,
wie von den Einträgen 32 und 33 eines
jeden Unterbaums von jeder Stufe, wird erhöht, wenn jeder neue Nicht-NULL-Eintrag,
der einem neuen Datenobjekt entspricht, in die entsprechenden Indexblöcke eingefügt wird
und für
jeden Nicht-NULL-Eintrag verringert wird, der von dem entsprechenden
Indexblock gelöscht
wird.
-
Während Operationen
auf der Datenspeicherstruktur 40 durchgeführt werden
und die Baumstruktur 43 von der Wurzelstufe 41 hinabgestiegen
wird, wird Zugriffsinformation zu den Zeigereinträgen 36a in
Form eines Zeigerindex, ps, von Nicht-NULL-Blatteinträgen oder F-Blatteinträgen in vorhergehenden
Unterbäumen durch
Ansammlung der Werte in dem ersten Element von jeder Unterbaumstufe
gehalten, wie Zählerkopf 66 und
Einträge 66a der
Stufe 64. Um den entsprechenden Zählerindex von einem gespeicherten
Datenobjekt abzuleiten, wird der vorhergehende Zählwert von vorhergehenden Unterbaumstufen
zu dem Zählwert
von Nicht-NULL-Einträgen
hinzugefügt,
die in dem gegenwärtigen
Blattindexblock bis zu dem Eintrag, der dem Schlüsselintervall des vorliegenden
Suchschlüssels
entspricht, verarbeitet werden. Dieser Index ps entspricht der Zeigerposition
des Datenobjekts in den Zeigereinträgen 36a, die auch
die lexikalische Position des Datenobjekts ist.
-
Mit
Bezugnahme auf 4a und 4b wird
nun ein Beispiel beschrieben, wie ein Schlüsselintervallbereich und Datenobjekt
eines Suchschlüssels
bestimmt wird. Weitere Details wie die Schritte, die bei so einer Bestimmung
durchgeführt
werden sollen, werden hier mit Bezugnahme auf die Programmstruktur
beschrieben, insbesondere das Tiefensuchverfahren aus 12.
-
Es
wird angenommen, daß eine
Suche mit dem Suchschlüssel
10101000 in Binärform
durchgeführt wird.
Der Suchschlüssel
wird durch eine Folge dargestellt, die Ordnungswertbitpositionen
der Eins-Bits in dem Suchschlüssel
enthält,
die beginnend von links Werte 1, 3 und 5 sind. Zusätzlich wird
ein letzter Wert nach dem letzten in der Folge hinzugefügt und ist
ein Wert, der die maximale Schlüssellänge in Bits
+1 darstellt, die in diesem Beispiel 9 ist, da der Schlüssel maximal
ein Byte ist. Im Ergebnis ist die Sequenz für den Suchschlüssel 10101000
1, 3, 5 und 9. Diese Suchschlüsselsequenz
wird mit den Tiefenwerten der Indexblöcke in der Baumstruktur 43 verglichen.
Zuerst werden die Tiefenwerte 89 der Indexblockeinträge 47c des
Wurzelknotens 47 mit den Elementen der Suchschlüsselsequenz
verglichen. Ein Vergleich der Tiefenwerte 89 wird wiederholt, bis
ein Eintrag gefunden wird, für
den der Tiefenwert geringer als ein Ordnungswert des Suchschlüsselelements
der Sequenz ist. Zusätzlich
werden ein Index zu einem Eintrag in dem gegenwärtigen Indexblock 47c und
ein Index zu den Ordnungspositionen des Elements der Suchschlüsselfolge
beibehalten. Der Tiefenwert des Eintrags 30 wird mit dem
ersten Ordnungselement der Suchschlüsselfolge verglichen. Da beide
gleich 1 sind, wird der Index zu dem Element der Suchschlüsselfolge
erhöht.
Da der Tiefenwert nicht geringer als der Ordnungswert ist, wird
dann der Index zu den Einträgen
in dem Indexblock erhöht.
-
Der
Tiefenwert des zweiten Eintrags 31 des Indexblocks 47c,
0, wird mit dem zweiten Ordnungselement der Sequenz 3 verglichen.
Da die zwei Werte nicht gleich sind und der Tiefenwert des Eintrags 31 nicht geringer
als der Ordnungswert 3 (d.h. 0 < 3)
ist, endet die Suche in dem Indexblock, und da dies ein Nicht-Blattknoten 47 ist,
wird der Kindindexblock, der dem Eintrag 31 entspricht,
erhalten und gesucht. In 4 ist dies die
Indexblockstruktur 35a und 35c. Zusätzlich wird
ein Zeigerindex zu den Zeigereinträgen 36a um den Wert erhöht, der
in dem Eintrag 32 der Zählwerteinträge 66a gespeichert
ist. Dieser Zeigerindex enthält
die Summe der vorhergehenden Nicht-NULL-Einträge (die durch die F-Einträge veranschaulicht
sind) in den Indexblockeinträgen 34c.
-
Ein
Zählwert
von Nicht-NULL-Einträgen
in dem gegenwärtigen
Blattindexblock der Einträge
von 35c, der auf eins beim Start der Suche bei irgendeiner
Unterbaumstufe initialisiert ist, wird beibehalten. Da der erste Eintrag 84 Nicht-NULL
ist, wird der Zählwert
der Nicht-NULL-Einträge
um 1 erhöht.
Der Tiefenwert des Eintrags 84, der 3 ist, wird mit dem
zweiten Ordnungssuchwert 3 der Suchschlüsselfolge verglichen, da das
Dateisystem die Suche der Ordnungswerte der Folge bei dem gleichen
Ort aufnimmt, wo die Suche in 47c des Elternknotens endete.
Der Tiefenwert des Eintrags 84 und das Ordnungselement
3 der Suchsequenz sind gleich. Somit wird auf den nächsten Eintrag 85 in 35c zugegriffen.
Da der Ordnungswert 3 gleich der Position des vorliegenden Bits
des Suchschlüssels
ist, wird zusätzlich
der nächste
Ordnungswert 5 der Suchschlüsselfolge
erhalten. Der Eintrag 85 ist ein NULL-Eintrag, so dass
der Zählwert
der Nicht-NULL-Einträge
nicht erhöht
wird. Der Tiefenwert des Eintrags 85 wird dann mit dem
dritten Ordnungswert 5 der Suchschlüsselfolge verglichen. Da die
beiden gleich sind (5 = 5), wird der nächste Eintrag 86 der
Indexblockeinträge 35c erhalten,
und wird das nächste
Element der Ordnungswertsequenz 9 erhalten. Der Eintrag 86 ist
Nicht-NULL, wodurch
der Zählwert
der Nicht-NULL-Einträge
auf zwei erhöht
wird. Zusätzlich
wird der Tiefenwert 89 des Eintrags 86 mit dem Ordnungswert
9 verglichen. Da der Tiefenwert 7 geringer als der Ordnungswert
9 in dem Suchschlüsselfeld
(7 < 9) ist. Die
Suche endet in diesem Indexblock und, da dies ein Blattknoten 34 ist,
wurde der richtige Eintrag, der dem Blatt Z in 2b und
Tabelle 1 entspricht, gefunden.
-
Zu
diesem Punkt wird der Zeigerindex ps, der gleich 4 ist, mit 2 summiert,
was 6 ergibt. Die 6 wird verwendet, um den sechsten Eintrag der
Zeigereinträge 36a auszuwählen, was
eine 8 ist. Der sechste Eintrag ist ein verweisbarer Index zu dem
achten Datenobjekt im Speicherbehälter 39, welches einem
Suchschlüssel 10101000
in Binärform
entspricht, wie in 4b gezeigt.
-
Die
Speicherstruktur 40 vermeidet so die Notwendigkeit der
Speicherung von irrelevanten (Füll-)NULL-Einträgen aus
dem Stand der Technik der 3a und 3b,
die durch die Anzeiger T/F und die Zählwertstruktur ersetzt werden.
Die Baumstruktur 43 und die Suchschlüssel 1420 zusammen
mit den Einträgen 66a,
welche die Anzahl der Anzeigerbits auf der Blattstufe zählen, die
auf F gesetzt ist, werden verwendet, um einen Index zu den Zeigereinträgen in 36a beizubehalten.
Die Zeigereinträge 36a umfassen
dann einen Index zu den Objekten, die in dem Speicherbehälter 39 gespeichert
sind.
-
Da
der Zeigerkopf 36 und die Zeigereinträge 36a von dem Rest
der Baumstruktur 43 unterschiedlich sind und verweisbare
Indizes zu den Schlüsseln 1420 in
lexikographischer Reihenfolge speichern, kann außerdem auf einen Suchschlüssel oder
ein Datenobjekt in lexikalischer Reihenfolge zugegriffen werden,
ohne die Baumstruktur 43 überhaupt zu verwenden. Durch
Kenntnis der lexikalischen Position des Datenobjekts, das geortet
werden soll, kann das Datenobjekt geortet werden, indem allein auf
die Einträge 36a zugegriffen wird.
-
Um
den C0-Baum der vorliegenden Erfindung zu
bauen, wird eine Struktur vom Typ INIT erzeugt, wie in 6b gezeigt.
Individuelle Suchschlüssel
werden dann in das Verfahren der Programmstruktur eingefügt, die
unten gezeigt ist. Wenn ein Indexblock voll ist, wird der Block
in zwei Teile auf die Weise geteilt, die unten beschrieben ist.
Das Bilden der C0- Baumdatenspeicherstruktur der bevorzugten
Ausführungsform
ist eine Angelegenheit iterativer Verarbeitung des Speicherns von
Indexinformation und Verfahren zum Teilen von Knoten und Indexblöcken, die
verwendet werden, um neue Datenobjekte oder Schlüssel in lexikographischer Reihenfolge
in einen vorhandenen C0-Baum der vorliegenden
Erfindung einzugeben.
-
C) Programmstruktur zum
Speichern und Abrufen von Schlüsseln
in der kompakten 0-kompletten Baumdarstellung
-
Die
Verfahren zur sequentiellen Verarbeitung einer Anzahl von Suchschlüsseln innerhalb
der Baumstruktur, um eine vorbestimmte Funktion für jeden
Suchschlüssel
durchzuführen,
ein Verfahren zum Orten eines Suchschlüssels innerhalb der Baumstruktur,
ein Verfahren zum Speichern und Indizieren von Information für jeden
Suchschlüssel
innerhalb der Baumstruktur und Teilen eines Indexblocks der vorliegenden
Erfindung werden nun beschrieben werden.
-
Das
Verfahren zur sequentiellen Verarbeitung einer Anzahl von Suchschlüsseln umfasst
das Durchsuchen der Datenspeicherstruktur für den Indexblock, der jedem
Suchschlüssel
entspricht, das Durchführen
einer vordefinierten Funktion wie einer Suche oder ein Einfügen von
Suchschlüsseln,
die durch die Baumstruktur indiziert werden sollen, das Teilen von
Indexblöcken,
wenn die Anzahl der Einträge
in jedem Block eine vorbestimmte Gesamtzahl überschreitet oder größer als
eine große
maximale Zahl wird, und das Verarbeiten einer leeren Zeichenkette
innerhalb der Suchschlüssel,
die innerhalb der Baumstruktur eingefügt werden soll.
-
Die
Computerprogrammstruktur der C0-Baumstruktur
ist schematisch in den Flussdiagrammen aus den 7–19 veranschaulicht.
Eine Zusammenfassung der Makrodefinitionen, die über die Programmstruktur verwendet
werden, ist in Tabelle 3 dargestellt, wobei der Makroname und eine
kurze Beschreibung angezeigt sind. Ähnlich ist eine Zusammenfassung
der Flussdiagramme aus 7–19 in
Tabelle 2 dargestellt, wobei der Flussdiagrammbezug und die Eingaben,
Variablen und Ausgaben angezeigt sind. Jedes der Verfahren wird
nun mit Bezugnahme auf Tabelle 2 und Tabelle 3 beschrieben werden.
Der Bequemlichkeit halber sind Blöcke, um die Schritte durchzuführen, die
mit Bezugnahme auf die 7–19 beschrieben
werden sollen, in Klammern.
-
1) Sequentielles Verarbeitungsverfahren
-
7 veranschaulicht
ein sequentielles Verarbeitungsverfahren, wobei eine vordefinierte
Funktion in einem Puffer innerhalb des Speichers 8 (1b)
lexikalisch geordneter Suchschlüssel
durchgeführt
wird. Das Programm ergreift anfänglich
eine Anzahl Suchschlüssel
und ordnet sie innerhalb des Speichers lexikalisch. Dann werden
die folgenden beschriebenen Schritte durchgeführt.
-
Der
Computer unter der Programmsteuerung holt von dem Speicherbehälter 39 den
gespeicherten Schlüssel,
der dem ersten Eintrag der Zeigereinträge 36a zugeordnet
ist, auf welche der Zeigerkopf 36 (100) zeigt.
Der gespeicherte Schlüssel
wird geprüft,
um zu sehen, ob er leer ist (102). Dieser Schritt ist Teil
einer Verarbeitungsroutine für
leere Zeichenketten und prüft,
um zu sehen, ob der erste Eintrag der Zeigereinträge 36a vorher
ein leeres Zeichenkettendatenobjekt indiziert hat.
-
Wenn
der gespeicherte Schlüssel
leer ist, wird ein anfänglicher
Index ps zu den Zeigereinträgen 36a, der
eine Summe der Nicht-NULL-Einträge
in der Baumstruktur ist, gleich 1 gesetzt, um anzuzeigen, dass eine leere
Zeichenkette innerhalb der Zei gereinträge 36a (104)
vorhanden ist. Wenn der Schlüssel
nicht leer ist, wird der anfängliche
Indexwert ps gleich 0 (106) gesetzt.
-
Ein
Suchschlüssel
K wird von dem Puffer (108) geholt. Der Suchschlüssel wird
dann verarbeitet, um zu sehen, ob er leer ist (d.h. eine leere Zeichenkette),
um zu bestimmen, ob eine leere Zeichenkette zu einem Speicherbehälter 39 hinzugefügt werden
soll und zu Zeigereinträgen 36a (110)
hinzugefügt
werden soll.
-
Wenn
der Suchschlüssel
nicht leer ist, wird eine Initialisierung der Variablen auftreten.
Eine nacheilende Variable di, die den Tiefenwert des vorhergehenden
Eintrags speichert, wenn von einem Indexblock INNERER zu einem Unterbaum
2 herabgestiegen wird, und eine Variable der Tiefe dj des Randknotens
in dem vorliegenden Indexblock werden auf 0 initialisiert. Die Variable
bK, die auf die gegenwärtige
und endende Bitposition des vorliegenden Suchschlüssels Bezug
nimmt, der durch das Datenbanksystem verarbeitet wird, wird auf
1 (112) initialisiert.
-
Die
tatsächliche
vordefinierte Funktion, die durchgeführt werden soll, wird durch
Untersuchen des Merkers LADEN (114) bestimmt. Wenn LADEN
angezeigt ist, dann verarbeitet das System sequentiell eine Einfügefunktion,
um die Indexinformation für
jeden Suchschlüssel
zu speichern und eine Knotentypüberprüfung wird durchgeführt, um
zu sehen, ob der vorliegende Knoten vom Typ WURZEL oder eine Struktur
von Typ INIT (116) ist. Wenn das System nicht lädt, dann
wird eine sequentielle Suche durchgeführt, um das Schlüsselintervall
zu orten, das dem vorliegenden Suchschlüssel entspricht, und eine Knotentypüberprüfung wird
durchgeführt,
um zu sehen, ob der Knoten vom Typ WURZEL oder vom Typ INIT ist
(118).
-
Wenn
geladen wird und der Knoten vom Typ WURZEL ist, wird das Zweigeinfügeverfahren
(120) durchgeführt.
Wenn der Kno ten vom Typ INIT ist, wird das Blatteinfügeverfahren
(122) durchgeführt.
Wenn der Schritt 118 anzeigt, dass der Knoten vom Typ WURZEL
ist, dann wird ein Zweigsuchverfahren durchgeführt (124). Wenn während Schritt 126 der
Knoten oben bei dem Baum 43 ein Typ INIT ist, dann wird
das Blattsuchverfahren (126) durchgeführt.
-
Nach
Durchführen
von irgendeinem von 120, 122, 124, 126,
wo der Baum 43 geändert
werden konnte, wird die Prüfung „KNOTEN ÜBERFÜLLT" durchgeführt, um
zu sehen, ob die Anzahl der Einträge in dem gegenwärtigen Indexblock
größer als
die vorbestimmte, erlaubte Indexblockvollzahl 79 (4) (128) ist. Wenn die Anzahl
der gegenwärtigen
Einträge
größer als
die Gesamtindexzahl ist, dann wird das Wurzelteilungsverfahren,
das beschrieben werden soll (130), durchgeführt. Wenn
nicht, geht das Programm zum Block 140, der hier beschrieben
ist.
-
Zurück zum Schritt 110,
wenn der Schlüssel
K leer ist und der gespeicherte Schlüssel Ki, auf den durch den
Eintrag p [1] Bezug genommen wird, leer ist, dann findet die weitere
Verarbeitung der leeren Zeichenkette statt und es wird eine Prüfung durchgeführt, um
zu sehen, ob der Index zu den Zeigereinträgen 36a ps gleich einem
der oben eingerichteten ist (132).
-
Wenn
ps 0 ist, dann weiß das
System, dass die Überprüfung, die
im Schritt 102 durchgeführt
wurde, keine leere Zeichenkette fand, die in dem Speicherbehälter 39 gespeichert
ist. Eine Überprüfung wird
durchgeführt,
um zu sehen, ob LADEN wahr ist und eine Ladeaufforderung (134)
wird auf dem Dateisystem durchgeführt. Falls wahr, wird das Laden
von Suchschlüsseln
in die Baumstruktur durchgeführt
und der Index zu den Zeigereinträgen 36a,
ps, wird auf 1 eingestellt, um das Hinzufügen eines Objekts (d.h. Hinzufügen der
leeren Zeichenkette) anzuzeigen (136).
-
Bei
diesem Punkt wurde bestimmt, dass der Suchschlüssel leer ist und dass eine
Ladeaufforderung durchgeführt
wird. Deshalb ist der Schlüssel
eine leere Zeichenkette. Ein Element wird beim ersten Eintrag eingefügt, das
mit einem Zeigerkopf 36a verbunden ist, und die erste Position
des Zeigervektors p [1] wird auf die Adresse des Schlüssels in
den Speicherbehälter 39 gesetzt
(138).
-
Schließlich wird
eine Bestimmung von irgendwelchen weiteren Schlüsseln durchgeführt (140),
um zu sehen, ob mehrere Suchschlüssel
von dem Puffer des Speichers 8 analysiert werden sollen.
Wenn dies so ist, wird der Schleife zum Schritt 108 gefolgt.
Wenn keine weiteren Suchschlüssel
analysiert werden sollen, wird das sequentielle Verarbeitungsverfahren
verlassen (199).
-
2) Blattsuchverfahren
-
Das
Blattsuchverfahren, das von dem sequentiellen Verarbeitungsverfahren
oder dem Zweigsuchverfahren aufgerufen wird, ist in 8 veranschaulicht.
Dieser Teil der Programmstruktur findet einen Eintrag innerhalb
der Baumstruktur mit einem Schlüsselintervall,
das dem vorliegenden Suchschlüssel
entspricht, und ortet somit den Suchschlüssel innerhalb der Baumstruktur,
wenn er nicht vorher indiziert wurde. Die folgenden beschriebenen
Schritte werden durchgeführt.
-
Die
Variablen j und c werden auf 1 initialisiert und b' wird gleich dj,
der Tiefe des Randknotens, gesetzt (200). Das Tiefensuchverfahren,
das beschrieben werden soll, ortet den Eintrag in dem vorliegenden
Indexblock, der ein Schlüsselintervall
hat, das den vorliegenden Suchschlüssel (202) entspricht.
Eine Bestimmung wird durchgeführt,
um zu sehen, ob der Anzeiger des georteten Eintrags ej ein NULL-Anzeiger
(d.h. Anzeiger 90 ist T) ist (204).
-
Wenn
der Eintrag ej ein NULL-Eintrag ist, dann wird der vorliegende Suchschlüssel nicht
innerhalb der Baumstruktur (206) gefunden. Wenn der Eintrag
Nicht-NULL ist (d.h. der Anzeiger 90 ist F), dann wird
der gespeicherte Schlüssel,
der dem Eintrag ej entspricht, in Ki von dem Speicherbehälter 39 unter
Verwendung des Eintrags p[c + ps] der Zeigereinträge 36a geholt,
die durch den summierten Zählwert
c + ps der Nicht-NULL-Einträge
indiziert sind (208). Der summierte Zählwert sorgt für den richtigen
Ort oder Index in den Zeigereinträgen 36a, da die Summe
der Nicht-NULL-Einträge in dem
vorhergehenden Indexblock ps und der Zählwert c der Nicht-NULL-Einträge in dem
gegenwärtigen
Indexblock, der von dem Tiefensuchverfahren geholt wird, beibehalten
wird. Durch Hinzufügen
der zwei Werte wird das Element der Zeigereinträge 36a, das zu dem
Eintrag ej gehört,
gefunden. Als nächstes
wird der geholte Schlüssel
Ki mit dem Suchschlüssel
K verglichen, um zu sehen, ob der Suchschlüssel der gleiche Wert ist wie
der Schlüssel,
der dem Blatteintrag ej entspricht (210). Wenn die zwei
Schlüssel
nicht gleich NE sind, wurde der Suchschlüssel K nicht gefunden und ist
nicht innerhalb der Baumstruktur (212) vorhanden.
-
Wenn
sie gleich sind, wurden die geeigneten Blatteinträge und Schlüssel K gefunden
(214). Das Mengenverarbeitungsverfahren, das beschrieben
werden soll, wird dann durchgeführt,
um auf den nächsten Suchschlüssel zuzugreifen
und das Unterscheidungsbit b' zwischen
dem vorliegenden Suchschlüssel
und dem nächsten
Schlüssel
innerhalb des Puffers zur Verarbeitung zu bestimmen (216).
-
Dann
wird eine Bestimmung durchgeführt,
ob der nächste
Suchschlüssel,
der verarbeitet werden soll, in dem Schlüsselintervallbereich des gegenwärtigen Indexblocks
(218) eingeschlossen ist, d.h. d' < b', wobei d' bei der Initialisierung
dieses Verfahrens eingerichtet oder zugewiesen ist. Wenn der nächste Suchschlüs sel innerhalb
des Schlüsselintervallbereichs
des gegenwärtigen
Indexblocks ist, wird die Rücksetzfunktion
bK durchgeführt,
wobei bK die Position des vorliegenden Schlüsselbits ist, bei der die Suche
für den
nächsten Suchschlüssel wiederaufgenommen
werden soll (220). Durch Wiederaufrufen der Schlüsselbitposition,
bei der eine Suche am Ende von jedem Such- oder Einfügeverfahren
endet, kann die bevorzugte Ausführungsform das
geeignete Schlüsselbit
bestimmen, bei dem die Verarbeitung der Suche des nächsten Suchschlüssels wiederaufgenommen
wird, da mehrere Suchschlüssel
in lexikalischer Ordnung der Werte verarbeitet werden. Wenn der
vorhandene Schlüssel
nicht in dem Schlüsselintervallbereich
des gegenwärtigen
Indexblocks eingeschlossen ist, wird zu der Routine zurückgekehrt,
welche die vorliegende Iteration des Blattsuchverfahrens aufrief,
wobei die geeigneten Werte des Unterscheidungsbits b' und die Position
bK des Schlüsselbits
beibehalten werden (299).
-
3) Blatteinfügeverfahren
-
Wenn
eine Ladeaufforderung im Schritt 114 durchgeführt wird,
dann werden die neuen Schlüssel
von dem Puffer der geordneten Schlüssel, die vorher nicht in der
Speichervorrichtung 4 vorhanden waren, individuell zu der
Datenspeicherstruktur hinzugefügt.
Das Blatteinfügeverfahren
ist in 9 veranschaulicht und fügt jeden neuen Suchschlüssel durch
Bestimmen seiner korrekten Platzierung ein und speichert die Indexinformation
des Schlüssels.
Die Schritte des Blatteinfügeverfahrens
werden unten beschrieben.
-
Die
Variablen des Verfahrens f = 0, j = 1 und d' = dj (die Randtiefe) werden initialisiert
(300). Das Tiefensuchverfahren wird durchgeführt, um
den Eintrag zu orten, dessen Schlüsselintervall den vorliegenden Suchschlüssel (302)
einschließt.
Eine Überprüfung wird
dann durchgeführt,
um zu sehen, ob der Eintrag ej, der durch das Tiefensuchverfahren
geortet ist, ein NULL-Eintrag ist, der einen T-Anzeiger 90 hat
(304).
-
Wenn
der Eintrag ein NULL-Eintrag ist, dann wird der Punkt des Einfügeeintrags
gefunden. Die Variablen c und n werden erhöht, um das Hinzufügen des
neuen Eintrags wiederzugeben, der als ein Nicht-NULL-Eintrag eingefügt werden
soll, und um den neu eingefügten
Zeiger zu dem Schlüssel
(306) wiederzugeben. Ein Element wird in die Zeigereinträge 36a eingefügt und ihm
wird die Adresse des Schlüssels und
seines verwiesenen Datenobjekts (308) zugeordnet, die in
dem Speicherbehälter 39 gespeichert
sind. Der Anzeiger des Eintrags ej wird von NULL (T) zu Nicht-NULL
(F) geändert,
um die Zugehörigkeit
des Eintrags zu einem Speicherelement in dem Speicherbehälter 39 und
der Zeigereinträge 36a (310)
wiederzugeben.
-
Wenn
während
Schritt 304 der Eintrag kein NULL-Eintrag ist, wird ein
Schlüssel,
der durch das Element p[c + ps] der Zeigereinträge 36a adressiert
wird, geholt und in Ki (312) geladen. Der vorliegende Schlüssel K wird
mit dem geholten Schlüssel
Ki verglichen, um zu sehen, ob sie gleich sind (d.h. um zu bestimmen, ob
der vorliegende Schlüssel
bereits im Speicherbehälter 39 vorhanden
ist (314). Wenn sie gleich sind, wird das Mengenverarbeitungsverfahren
durchgeführt,
um zu bestimmen, ob der nächste
Schlüssel,
der verarbeitete werden soll, innerhalb des Schlüsselintervalls des gegenwärtigen Indexblocks
(316) ist.
-
Wenn
der vorliegende Schlüssel
und der geholte Schlüssel
nicht gleich sind, wird der Zählwert
n der neuen Einträge,
der zu den Zeigereinträgen 36a hinzugeführt wird,
erhöht,
da der vorliegende Schlüssel
nicht vorhanden war (318). Das Tiefenhinzufügeverfahren,
das beschrieben werden soll, wird dann durchgeführt, um irgendwelche Fülleinträge hinzuzufügen und
die korrekte Lage des neuen Eintrags zu bestimmen. Die Routine geht
auf ei nen Merker f zurück,
der bezeichnet, ob der vorliegende Schlüssel, der verarbeitet wird,
größer oder
gleich einem geholten Schlüssel
Ki (320) ist und zeigt die Position oder den Index in den
Zeigereinträgen 36a an.
Ein Element wird in die Zeigereinträge 36a eingefügt und ihm
wird die Adresse des Schlüssels
und sein verwiesenes Datenobjekt in der richtig indizierten Lage
zugewiesen, die der Summe der Anzahl ps der Nicht-NULL-Einträge in den
vorhergehenden Unterbäumen,
der Anzahl c der Nicht-NULL-Einträge des vorliegenden Indexblocks
und des Werts des Merkers f (322) entspricht.
-
Das
Mengenverarbeitungsverfahren wird dann durchgeführt, das b', das Unterscheidungsbit (324),
zurückgibt.
Dann wird eine Prüfung
durchgeführt,
um zu sehen, ob die Anzahl der Einträge in dem vorliegenden Indexblock über MAX,
größer als
das erlaubte Maximum ist. Das Maximum wird bei einer sehr hohen
Schwelle eingestellt, die viel größer als die vorbestimmte Indexblockvollzahl 79 für Einträge eines
Indexblocks ist, z.B. fünf
in 4(326).
-
Wenn
die Anzahl der Einträge
in dem vorliegenden Indexblock nicht größer als das Maximum ist, wird eine
Bestimmung durchgeführt,
ob d' kleiner als
b' ist, was anzeigt,
daß der
nächste
Schlüssel,
der verarbeitet werden soll und während des Mengenverarbeitungsverfahrens
geholt wurde, innerhalb des Schlüsselintervallbereichs
des vorliegenden Indexblocks (328) ist. Falls dies so ist,
wird ein Rücksetzverfahren
bK durchgeführt (336),
bevor zu dem Schritt 302 zurückgekehrt wird. Dennoch geht
das Verfahren schließlich
zu dem Aufrufverfahren mit dem Wert des Unterscheidungsbits b', der vorliegenden
Schlüsselbitposition
bK, und der Anzahl der neuen Elemente in den Zeigereinträgen 36a zurück (399).
-
4) Zweigsuchverfahren
-
Wenn
das Zweigsuchverfahren aus 10 von
dem sequentiellen Verarbeitungsverfahren aus 7 aufgerufen
wird, dann werden die folgenden Schritte beim Durchsuchen der Zweige
der Co-Baumdatenspeicherstruktur durchgeführt, um
die richtige BLATT-Stufe und den Indexblock zu orten, um das Blattsuchverfahren
durchzuführen.
-
Zuerst
werden die Variablen j = c = 1 und d' = dj initialisiert (400),
wobei dj die Randtiefe ist. Das Tiefensuchverfahren wird durchgeführt, um
den geeigneten Eintrag in den vorliegenden Zweigindexblock INNERER
mit einem Schlüsselintervall
zu orten, das den vorliegenden Schlüssel (402) enthält. Da das
System bei einer Zweigstufe ist, gehört der Eintrag zu einem Unterbaum
der Baumstruktur.
-
Der
geortete Kindknoten, der einem Eintrag ej des Zweigs entspricht,
wird geholt (404) und dann überprüft, um den Knotentyp (406)
zu bestimmen. Wenn der Knotentyp eines Kindblocks ein BLATT ist,
dann wird das Blattsuchverfahren durchgeführt (408). Wenn der
Knotentyp ein Nicht-Blatt ist, d.h. vom Typ INNERER, dann wird das
Zweigsuchverfahren durchgeführt
(410).
-
Das
Verfahren bestimmt, ob der vorliegende Schlüssel innerhalb des Schlüsselintervallbereichs
des vorliegenden Indexblocks ist, d.h. d' < b' (414).
Wenn das so ist, wird das Rücksetzverfahren
bK, das beschrieben werden soll, durchgeführt (416) und eine
Schleife zum Schritt (402) wird ausgeführt. Wenn nicht, gibt das Programm
den Wert des Unterscheidungsbits b' und der Position des Schlüsselbits
bK zu dem sequentiellen Verarbeitungsverfahren zurück und die
vorliegende Iteration der Zweigsuche ist beendet (499).
-
5) Zweigeinfügeverfahren
-
Wenn
die vordefinierte Funktion, die für die geordneten Suchschlüssel in
dem Puffer durchgeführt
werden soll, eine Ladung ist und der Typ des Indexblocks aus Schritt 116 des
sequentiellen Verarbeitungsverfahrens als ein Indexblock WURZEL
bestimmt ist, dann wird das Zweigeinfügeverfahren in Schritt 120 aufgerufen und
die Schritte, die in 11 gezeigt sind, durchgeführt wie
folgt, bis der Blattindexblock, der das Schlüsselintervall des vorliegenden
Suchschlüssels
enthält,
geortet ist.
-
Der
Index zu dem Eintrag, dessen Intervall den gegenwärtigen Suchschlüssel enthält, wird
auf 1 eingestellt, d.h. j = c = 1, der vorliegende Grenztiefenwert
wird zugeordnet, d.h. d' =
dj und der Zählwert
des neuen Suchschlüssels,
der zu dem Elternindexblock gehört,
wird 0 gesetzt, d.h. cn = 0 (500). Dann wird das Tiefensuchverfahren
durchgeführt,
um den Eintrag, der den vorliegenden Schlüssel hat, in dem Schlüsselintervall (501)
zu orten. Dieses Verfahren gibt die Position des Schlüsselbits,
um das Suchverfahren des Suchschlüssels wiederaufzunehmen, und
dem Index zu dem Eintrag innerhalb des gegenwärtigen Indexblocks aus, dessen
Schlüsselintervall
den Suchschlüssel
enthält.
-
Da
der Computer ein Zweigeinfügeverfahren
durchführt,
ist der Indexblocktyp des vorliegenden Indexblocks entweder INNERER
oder WURZEL. Nach dem Orten des Eintrags mit dem vorliegenden Schlüssel in dem
Schlüsselintervall
des Eintrags wird die nachlaufende Tiefenvariable di aktualisiert,
wenn der Index j zu den Tiefeneinträgen des vorliegenden Indexblocks
größer als
1 (502) ist. Das Programm bemerkt, dass der geortete Eintrag
nicht der erste Eintrag des vorliegenden Indexblocks vom Typ INNERER
ist, und die nachlaufende Variable di wird zu dem Tiefenwert des
Eintrags ej-1 vor dem georteten Eintrag in dem vorliegenden Indexblock
(503) aktualisiert. Die Variable dj wird dann auf die Tiefe
des Eintrags ej (504) eingestellt.
-
Zu
dieser Zeit wird der indizierte Kindknoten, das j-te Kind in dem
Unterbaum V des gegenwärtigen Indexblocks,
das dem georteten Eintrag entspricht, einschließlich der Tiefenwerteinträge des Indexblocks
und des Unterbaums des Kindindexblocks geholt (505). Dieser
Schritt gibt eine aktualisierte Summe der Nicht-NULL-Einträge ps aus,
mit denen die Zeigereinträge 36a indiziert
werden. Da das erste Element, die Zählwertstruktur der zusammengesetzten
Struktur, der vorliegenden Stufe des Baums die Zählwertinformation der Nicht-NULL-Einträge enthält, werden
insbesondere die Elemente der Zählwerteinträge bis zu
dem Wert von j miteinander summiert und zu der früheren Summe
des Zählwerts
der Nicht-NULL-Einträge hinzugefügt, um zu
der neuen Summe (506) zu gelangen.
-
Dann
wird eine Bestimmung des Typs des geholten Kindknotens vom Schritt 504 (507)
durchgeführt. Wenn
der Kindknoten ein BLATT ist, dann wird das Blatteinfügeverfahren
durchgeführt
(508). Wenn der Kindknoten ein INNERER ist, dann wird das
Zweigeinfügeverfahren
durchgeführt
(510).
-
Nachdem
die Verarbeitung von dem Zweigeinfügen oder Blatteinfügen zurückkehrt
ist, wird der Zählwerteintrag
c[j], der dem vorliegenden Indexblock entspricht, auf seinen vorherigen
Wert plus der Zahl n der neuen Schlüssel gesetzt, die zu den Einträgen des
Kindindexblocks gehören
(514). Der Zählwert
cn der neuen Schlüssel,
die zu dem Elternindexblock gehören,
wird um den Zählwert
n der neuen Schlüssel
erhöht,
die zu den Einträgen
des Kindindexblocks gehören
(514).
-
Das
Verfahren bestimmt dann, ob der vorliegende Kindknoten geteilt werden
soll, durch Bestimmen, ob der Indexblock übervoll ist (520).
Wenn die Indexblockeinträge
die vorbestimmte Indexblockvollzahl der Einträge überschritten haben, die pro
Index block erlaubt sind, dann wird das Kindteilungsverfahren, das
beschrieben werden soll, durchgeführt (522).
-
Eine Überprüfung wird
durchgeführt,
um zu sehen, ob der vorliegende Schlüssel innerhalb des Schlüsselintervallbereichs
des vorliegenden Indexblocks (524) ist, d.h. d' < b'.
Wenn dies so ist, wird das Unterscheidungsbit b' 0 gesetzt, was das Einfügen bis
zu der Wurzelstufe beendet, weil eine Kindteilung auftrat (526).
In jedem Fall wird die Anzahl n der neuen Schlüssel, die zu den Einträgen des
Kindindexblocks gehören,
als eine Ausgabevariable zu dem Zählwert der neuen Schlüssel cn
für den
gegenwärtigen
Indexblock (536) eingestellt.
-
Wenn
der Indexblock nicht übervoll
ist, wird eine Prüfung
durchgeführt,
um zu sehen, ob der vorliegende Schlüssel innerhalb des Schlüsselintervallbereichs
des vorliegenden Indexblocks ist, d.h. d' < b' (534). Wenn
der vorliegende Schlüssel
innerhalb des Schlüsselintervalls
des vorliegenden Indexblocks ist, wird das Rücksetzverfahren bK durchgeführt (538).
Ungeachtet geht das Verfahren mit dem Zählwert der neuen Schlüssel n,
die zu dem Kindindexblock hinzugefügt sind, dem Unterscheidungsbit
b' und der Position
bK des Schlüsselbits
(599) zu dem Aufrufverfahren zurück.
-
6) Tiefensuchverfahren
-
Wie
in 12 veranschaulicht, wird jedes Mal, wenn eine
Suche oder ein Einfügen
für die
C0-Baumdatenspeicherstruktur durchgeführt wird,
das Tiefensuchverfahren durchgeführt,
um den Eintrag innerhalb des vorliegenden Indexblocks zu orten,
wobei das Schlüsselintervall
dem vorliegenden Schlüssel
entspricht.
-
Die
Indexvariable k wird 1 gesetzt und die eingegebene Variable, der
Zählwert
c der Nicht-NULL-Einträge,
wird erniedrigt (600).
-
Das
Verfahren erhält
das Ordnungselement b[k] des vorliegenden Suchschlüssels, das
zumindest so groß wie
die Position bK des vorliegenden Schlüssels ist, um die Suche nach
dem vorliegenden Schlüssel
zu beginnen (602). Die Ordnungselemente bestehen aus den
Werten der 1-Bit-Positionen in dem Alphabet mit den zwei Buchstaben
0 und 1 in dem gegenwärtigen
Suchschlüssel,
der analysiert wird. Dann wird bestimmt, ob der vorliegende Eintrag
ej ein NULL-Eintrag ist (604). Wenn der Eintrag ein NULL-Eintrag
ist, wird der Zählwert
c der Nicht-NULL-Einträge des vorliegenden
Indexblocks erhöht
(606).
-
Die
bevorzugte Ausführungsform
bestimmt dann, ob ein Tiefenwert dj des Eintrags ej des vorliegenden Indexblocks
gleich (610) dem vorliegenden Ordnungselement b[k] ist
und, wenn er nicht gleich ist, kleiner (612) ist. Wenn
er gleich ist, wird die Indexvariable k erhöht (616). Wenn er
nicht gleich und größer ist,
dann wird die Indexvariable j zu den Tiefeneinträgen des Indexblocks erhöht (618).
Wenn er geringer ist, dann wird die Position des vorliegenden Schlüsselbits
gleich dem vorliegenden Ordnungswert b[k] gesetzt (614).
Schließlich geht
das Verfahren zu der Aufrufroutine (699) zurück. Die
Werte der Indexvariabel j, die verwendet wird, um die Tiefenwerte
zu indizieren, die dem Schlüsselintervall
des vorliegenden Schlüssels
K entsprechen, der Zählwert
c der Nicht-NULL-Einträge
des vorliegenden Indexblocks, der verwendet wird, um auf die Zeigereinträge 36a zuzugreifen,
und die Bestimmung der Position bK des vorliegenden Schlüsselbits,
die es dem Dateisystem erlaubt, die vorliegende Schlüsselbitposition
der Suchschlüssel,
die verarbeitet werden, abzurufen, wird ausgegeben.
-
6.a) Mehrstufige Suche
-
Nun,
da die sachbezogene Programmstruktur, um nach einem Suchschlüssel zu
suchen, beschrieben wurde, wird ein detaillier teres Beispiel, wie
der Schlüsselintervallbereich
und das Datenobjekt eines Suchschlüssels eines C0-Baums
bestimmt werden, der aus mehr als zwei Stufen besteht, mit Bezugnahme
auf 5 und Tabelle 4 beschrieben. Die Datenspeicherstruktur 1540 besteht
aus drei Stufen: Stufe WURZEL, Stufe INNERER und Stufe BLATT. Bestimmte
Informationsobjekte innerhalb der Struktur 1540, die nicht
zu diesem Beispiel gehören,
wurden in 5 nicht veranschaulicht und
wurden durch den Buchstaben X ersetzt. Somit haben die Indexblockeinträge der Stufe
WURZEL 1541 und der Stufe INNERER 1564 ein X,
welches das vorliegende Anzeigerbit veranschaulicht, da das Anzeigerbit
nur das Vorhandensein eines entsprechenden Datenobjekts bei Strukturen
der Stufe BLATT, wie 1570, veranschaulicht. Außerdem sind
die Tiefenwerte von jedem der Indexblockeinträge bei der Stufe BLATT andere
Einträge
als 1575c, als ein X gezeigt, da sie von dem vorliegenden
Suchbeispiel nicht verwendet werden. Schließlich wurden die Inhalte der
Zeigereinträge 1536a und
des Speicherbehälters 1539 nicht
besonders beschrieben, da sie für
das vorliegende Beispiel nicht notwendig sind.
-
Angenommen
eine Suche wird mit dem Suchschlüssel
10011001, wie in Tabelle 4 gezeigt, durchgeführt. Der Suchschlüssel wird
durch eine Sequenz b[k] dargestellt, die Bitpositionen der Ordnungswerte
der Eins-Bits in dem Suchschlüssel
enthält,
die von links beginnend 1, 4, 5 und 8 sind. Wie in dem vorhergehend beschriebenen
Beispiel wird ein letzter Wert 9 nach dem letzten in der Sequenz
hinzugefügt.
Deshalb ist die Folge b[k] = <1,
4, 5, 8, 9>. Zuerst
werden die Tiefenwerte 89 der Indexeinträge 1547c des
Wurzelknotens 1547 mit den Elementen der Suchschlüsselfolge
verglichen. Ein Index j zu den Indexblockeinträgen 1547 wird beibehalten
und ein Index k zu der Ordnungsposition der Suchschlüsselfolge
wird beibehalten. In Schritt 1 aus Tabelle 4 wird der Tiefenwert
d[j] des Eintrags 1530 mit dem ersten Ordnungselement b[k]
der Suchschlüssel sequenz
verglichen, der gleich 1 ist. Da der Tiefenwert d[j] größer als
das Ordnungselement b[k] ist, wird der Index j zu den Indexblockeinträgen 1547c erhöht.
-
Im
Schritt 2 der Tabelle 4 wird der Tiefenwert d[j] des zweiten
Eintrags 1531 der Indexblockeinträge 1547c mit dem ersten
Ordnungselement b[k] verglichen. Da sie gleich sind, wird der Index
k zu der Suchschlüsselsequenz
erhöht.
Dann wird der Index j zu den Indexblockeinträgen 1547c erhöht.
-
Da
j = 3 und k = 2 im Schritt 3 wird der Tiefenwert d[j] des
dritten Eintrags 1532 mit dem zweiten Ordnungselement b[k]
verglichen. Da die zwei Werte nicht gleich sind und der Tiefenwert
d[j] des Eintrags 1532 kleiner als der Ordnungswert b[k]
ist (d.h. 0 < 4),
endet die Suche in diesem Indexblock, der den Kopf 1547a hat.
Da dies ein Nicht-Blattknoten 1547 ist, werden der Kinderknoten
und der Indexblock, der dem Eintrag 1532 entspricht, erhalten
und gesucht. In 5 ist dies Knoten 1535 mit
dem Unterbaum 1570, Indexblockkopf 1535a und Einträgen 1535c.
Zusätzlich
wird die Endposition bK des Schlüsselbits
auf den vorliegenden indizierten Ordnungswert b[k] gesetzt (d.h.
bK = 4), so dass das Computersystem einfach und effizient das Suchverfahren
bei dem Kindindexblock wiederaufnehmen kann.
-
Wie
in Schritt 4 aus Tabelle 4 gezeigt, wird ein Zeigerindex
ps zu der Zeigerstruktur 1536 zusätzlich um die Werte erhöht, die
in den Einträgen 1557 und 1558 des
Zählwertkopfs 1556 der
Stufe INNERER 1564 gespeichert sind, da diese Einträge dem dritten
Eintrag vorangehen, welcher der Unterbaum ist, der durchsucht werden
soll. Dieser Zeigerindex ps enthält
die Summe der vorhergehenden Nicht-NULL-Einträge (die durch die Einträge F veranschaulicht
sind) in den vorhergehenden Geschwistern dieses Knotens 1535.
Somit entsprechen die Einträge 1557 Nicht-NULL-Blatteinträgen, die
von dem zusammengesetzten Kopf C des Knotens 1537 abhängen, und
der Eintrag 1558 entspricht den Nicht-NULL-Blatteinträgen, die
von dem zusammengesetzten Kopf C des Knotens 1538 abhängen. Der
Zeigerindex ps ist deshalb vorliegend gleich 14, da acht Nicht-NULL-Blatteinträge von dem
Knoten 1537 abhängen
und sechs Nicht-NULL-Blatteinträge von dem
Knoten 1538 abhängen.
-
In
Schritt 5 aus Tabelle 4 wird die Indexvariable j auf 1
initialisiert. Der erste Tiefenwert d[j] der Einträge 1535c wird
mit dem zweiten Ordnungssuchwert b[k] verglichen. (Der zweite Ordnungswert,
der gleich 4 ist, wird verwendet, da das Computersystem in Schritt 602 in 12 den
Index k erhöht
und das Ordnungselement in der Suchschlüsselsequenz erhält, das
größer oder
gleich der Endposition bK des Schlüsselbits ist, die auf 4 eingestellt
wurde, als die Suche nach dem Elternknoten 1547 endete.)
Da d[j] gleich b[k] ist, wird der Index k zu der Suchschlüsselfolge
erhöht.
Dann wird der Index j zu den Einträgen 1535c erhöht.
-
In
Schritt 6 wird der Tiefenwert d[j] des zweiten Eintrags 1554 der
Indexblockeinträge 1535c dann
mit dem dritten Ordnungselement b[k] verglichen, das gleich 5 ist.
Da der Tiefenwert d[j] kleiner als das Ordnungselement b[K] ist
(d.h. 2 < 5), endet
die Suche in diesem Indexblock, der 1535a als Kopf hat.
Da der Knoten 1535 ein Knoten INNERER ist, wird der Kindknoten
und der Indexblock, der dem Eintrag 1535 entspricht, erhalten.
In 5 ist dies der Knoten 1575. Die Endposition
bK des Schlüsselbits
wird auf den vorliegend indizierten Ordnungswert b[k] gesetzt (d.h.
bK = 5). Dann wird der Zeigerindex ps in Schritt 7 aktualisiert,
so dass er zusätzlich
die Anzahl der Nicht-NULL-Einträge in vorhergehenden
Geschwistern des Knotens 1575 enthält. Da bei einer Stufe BLATT
jeder Zählwerteintrag,
wie der Eintrag 1561, der mit dem Zählwertkopf 1560 verbunden
ist, der Anzahl der Nicht-NULL-Einträge in einem entsprechenden
Kno ten in einer BLATT-Struktur 1570 entspricht, entspricht
der erste Zählwerteintrag 1561 der
Anzahl der Nicht-NULL-Einträge
in dem ersten Knoten 1576 der Struktur 1570. Der
Zeigerindex ps ist deshalb gleich neuzehn, sein vorhergehender Wert
vierzehn plus dem Wert fünf,
der in dem Zählwerteintrag 1561 gefunden
wurde.
-
Die
Indexvariablen j und k werden wieder auf 1 gesetzt. Das Computersystem
erhöht
den Index k und erhält
das Ordnungselement b[k], das größer oder
gleich der Endposition bK des Schlüsselbits ist. Somit erhält es das
dritte Element, das gleich 5 ist.
-
Ein
Zählwertindex
c der Nicht-NULL-Einträge,
der am Beginn der Suche der Einträge 1575c auf 0 initialisiert
ist, wird beibehalten. Da das Ordnungselement b[k] kleiner als der
Tiefenwert d[j] des Eintrags 1580 der Indexblockeinträge 1575c in
Schritt 8 ist, wird der Index j zu den Einträgen 1575c erhöht. Ein
Index c zu den Einträgen 1575c wird
nicht erhöht,
da der Eintrag ej ein NULL-Eintrag
ist. In Schritt 9 ist das Ordnungselement wieder kleiner
als der Tiefenwert d[j] des Eintrags 1581. Somit wird der
Index j erhöht.
Der Index c wird erhöht,
da der Eintrag ej ein Nicht-NULL-Eintrag
ist. Der Tiefenwert d[j] des Nicht-NULL-Eintrags 1582 ist gleich
dem vorliegenden Ordnungselement b[k] in Schritt 10. Deshalb
wird der Index k auch erhöht.
-
In
Schritt 11 wird der Tiefenwert d[j] des vierten Nicht-NULL-Eintrags 1583 mit
dem dritten Ordnungselement b[k] verglichen. Wiederum sind die Werte
gleich (d.h. 8 = 8). Die Indizes k, j und c werden erhöht. Schließlich wird
der Tiefenwert d[j] des fünften
Eintrags 1584 mit dem vierten Ordnungselement b[k] verglichen.
Der Tiefenwert d[j] ist kleiner als das Ordnungselement b[k] (d.h.
6 < 9), und, da
die BLATT-Stufe vorliegend durchsucht wird, wur de der richtige Eintrag,
der dem Suchschlüssel
10011001 entspricht, gefunden.
-
An
diesem Punkt wird der Zeigerindex ps um den Zählwertindex c (d.h. 19 + 4
= 23) im Schritt 13 erhöht.
Dies sorgt für
die Gesamtheit der Nicht-NULL-Einträge vor dem und einschließlich des
Eintrags 1584. Die 23 wird verwendet, um den dreiundzwanzigsten
Eintrag in den Zählereinträgen 1536a auszuwählen, der den
verweisbaren Index oder Zeiger zu dem richtigen Datenobjekt in dem
Speicherbehälter 1539 enthält.
-
7) Mengenverarbeitungsverfahren
-
Das
Mengenverarbeitungsverfahren, das den nächsten Schlüssel zur Verarbeitung innerhalb
des Puffers erhält,
auf den in 8 und 9 Bezug
genommen wird, ist in 13 veranschaulicht. Sein Zweck
ist es, den nächsten
Schlüssel
Ki zur Verarbeitung in den Puffer im Speicher 8 zu holen
und das Unterscheidungsbit zwischen dem vorhergehenden Schlüssel K und
dem nächsten
Schlüssel
Ki zu bestimmen.
-
Das
Verfahren bestimmt, ob es mehrere Schlüssel innerhalb des Puffers
(700) gibt. Wenn mehr Schlüssel innerhalb des Puffers
vorhanden sind, wird der nächste
Schlüssel
in dem Speicher zur Verarbeitung in Sequenz in Ki geholt. (702).
Als nächstes
folgt eine Bestimmung, ob der frühere
Schlüssel
K und der vorliegende Schlüssel
Ki, der verarbeitet werden soll, gleich sind (704). Da
die Suchschlüssel,
die sequentiell verarbeitet werden, in dem Puffer in lexikalischer
Reihenfolge geordnet sind, kann die vorliegenden Ausführungsform
bestimmen, ob ein duplizierter Schlüssel vorhanden ist, und diesen
Suchschlüssel
nicht verarbeiten. Wenn dieser Schritt bestimmt, dass die zwei Schlüssel gleich
sind, wird deshalb eine Rückkopplungsschleife zum
Schritt 700 durchgeführt.
Wenn bestimmt ist, dass die zwei Schlüssel nicht gleich NE sind,
dann wird das Unterscheidungsbit der zwei Schlüssel gefunden (706).
Die bevorzugte Ausführungsform
richtet dann den vorliegenden Schlüssel K ein; mit anderen Worten
bewegt das Programm den neuen Schlüssel Ki, der verarbeitet werden
soll, in die vorliegende Schlüsselvariable
K (708).
-
Wenn
es keine weiteren Schlüssel
gibt, die innerhalb des vorliegenden Puffers verarbeitet werden
sollen, dann wird das Unterscheidungsbit b' auf 0 gesetzt, was die Verarbeitung
zu der WURZEL-Stufe beendet (710). Indem dies getan wird,
können
die Verfahren der vorher beschriebenen Programmstruktur bestimmen, dass
es nicht mehr Schlüssel
zur Verarbeitung innerhalb des Puffers gibt, insbesondere wenn bestimmt
wird, ob der nächste
Schlüssel
innerhalb des Schlüsselintervalls
des vorliegenden Indexblocks in den Schritten 218, 328, 414, 524 und 534 ist.
Schließlich
geht das Verfahren mit dem Wert des Unterscheidungsbits b' und dem neuen Schlüssel K (799)
zu seiner Aufrufroutine zurück.
-
8) Rücksetzfunktion bK
-
Nun
wird die Rücksetzfunktion
bK, auf die in 8, 9, 10 und 11 Bezug
genommen wurde, detailliert in 14 veranschaulicht.
Dieses Verfahren bestimmt die Position bK des Schlüsselbits,
um die sequentielle Verarbeitung für den vorliegenden Suchschlüssel wiederaufzunehmen.
Das Verfahren kann die Position des Schlüsselbits bestimmen, da die
Suchschlüssel,
die in Sequenz verarbeitet werden, in lexikalischer Reihenfolge
innerhalb des Puffers sind. Diese Eigenschaft einer geordneten Sequenz
erlaubt es der vorliegenden Ausführungsform,
wie entworfen zu funktionieren. Das Verfahren bestimmt zuerst, ob
der vorliegende Index j zu dem gegenwärtigen Eintrag ej der erste
in dem gegenwärtigen
Indexblock (800) ist. Wenn das so ist, wird das Un terscheidungsbit
b' mit der Position
bK des vorliegenden Schlüsselbits
verglichen (802). Wenn es zumindest so groß wie die
Position des Schlüsselbits
ist, wird die Position bK des Schlüsselbits mit der nachlaufenden
Variable di und dem Unterscheidungsbit b' verglichen (804).
-
Ein
Vergleich des Unterscheidungsbits b' mit der nachlaufenden Variable di,
einer Eingabevariable zu der Rücksetzfunktion
bK und der vorliegenden Position des Schlüsselbits bK wird durchgeführt (806).
Wenn die nachlaufende Variable di kleiner als das Unterscheidungsbit
b' ist, das kleiner
als die gegenwärtige
Position bK des Schlüsselbits
ist, dann wird die Position des Schlüsselbits bK auf die nachlaufende
Variable di plus 1 gesetzt (808).
-
Wenn
Schritt 800 bestimmt, dass der vorliegende Index j zu den
Tiefeneinträgen
nicht 1 NE ist, wird eine Bestimmung durchgeführt, ob das Unterscheidungsbit
b' kleiner als die
Position bK des vorliegenden Schlüsselbits ist (810).
Wenn dies so ist, wird die Position bK des Schlüsselbits auf den Wert des Unterscheidungsbits
b' (812)
gesetzt. Ungeachtet wird der Wert der Position bK des Schlüsselbits
zurückgegeben
(899).
-
9) Tiefenhinzufügeverfahren
-
Das
Tiefenhinzufügeverfahren,
das durch den Schritt 320 von dem Blatteinfügeverfahren
aufgerufen wird, ist in 15 veranschaulicht.
Sein Ziel ist es, das korrekte Setzen des Indexeintrags zum Speichern
der Indexinformation eines vorliegenden Suchschlüssels relativ zu dem georteten
Eintrag zu bestimmen, wobei der Suchschlüssel zu dem Schlüsselintervall
gehört,
das durch den Eintrag durch Hinzufügen eines Eintrags oder von
Einträgen
zu dem gegenwärtigen
Indexblock definiert ist. Dies geschieht, da der vorliegende Suchschlüssel und
ein früherer
Indexschlüssel
beide in das gleiche Schlüsselintervall
gehören.
-
Um
die richtige Lage zu bestimmen, muss das Programm die Tiefe des
Blattknotens, der zu dem georteten Eintrag gehört, und den vorher indizierten
Suchschlüssel
in einem konzeptionellen 0-kompletten
Baum bestimmen, wie dem Baum 1430, der in 2b dargestellt
ist. Dies ist in der C0-Baumdarstellung
nicht aufgezeichnet. Nur die Tiefen der Randknoten sind in den Einträgen aufgezeichnet.
Die Tiefe des Blattknotens in einem konzeptionellen 0-kompletten
Baum, wie in 2b veranschaulicht, kann durch
die Definition eines kompakten 0-kompletten Baums bestimmt werden.
Das Verfahren bestimmt zuerst, ob der gegenwärtige Eintrag ej der erste
in einem Indexblock (900) ist. Wenn nicht, dann wird die
Tiefe des vorliegenden Eintrags d[j] in dem Indexblock mit der Tiefe
des früheren
Eintrags d[j-1] verglichen (902). Auf Grundlage dieses
Vergleichs, wenn die Tiefe des georteten Eintrags geringer als LT
die Tiefe des früheren
Eintrags ist, wird die Tiefe li des Blattknotens in dem konzeptionellen
0-kompletten Baum
gleich der Tiefe des früheren
Eintrags in dem Indexblock d[j-1] gesetzt (908). Wenn die
Tiefe des georteten Eintrags größer als
GT ist, wird die Tiefe li des Blattknotens in dem konzeptionellen
0-kompletten Baum gleich der Tiefe des vorliegenden Eintrags d[j]
gesetzt (906). Wenn der geortete Eintrag der erste in dem
Indexblock ist, wird die tatsächliche
Tiefe li des Blatts in dem konzeptionellen 0-kompletten Baum gleich
der vorliegenden nachlaufenden Variable di gesetzt, die der Tiefenwert
des vorhergehenden Eintrags des Elternindexblocks ist (904).
-
Als
nächstes
wird eine Indexvariable i auf den gegenwärtigen Index j zu den Indexblockeinträgen gesetzt
und werden das Unterscheidungsbit b' des vorliegenden Schlüssels K,
der verarbeitet wird, und der Schlüssel Ki, der durch den georteten
Eintrag indiziert wird, bestimmt (910). Wenn das Unterscheidungsbit
b' geringer als
die Tiefe li des Blatts in dem konzeptionellen 0- kompletten Baum ist (912),
dann folgt der Indexeintrag, der hinzugefügt werden soll, dem georteten
Eintrag in der Vorreihenfolgesequenz. Mehr Einträge müssen zu der vorliegenden Baumstruktur
hinzugefügt
werden, um einen Unterschied zwischen den Zugriffswegen des vorliegenden
Suchschlüssels
und des Schlüssels
des georteten Eintrags beizubehalten. Um sicherzustellen, dass der
konzeptionelle Baum immer noch 0-komplett ist, kann es notwendig
sein, NULL-Einträge
hinzuzufügen,
wobei das Anzeigerbit auf wahr gesetzt ist.
-
Das
Ordnungselement b[k] des Suchschlüssels wird erhalten, welches
größer als
die Tiefe li des Blatts in dem konzeptionellen 0-kompletten Baum
plus 1 ist. Das vorliegend indizierte Ordnungselement b[k] wird dann
mit dem Unterscheidungsbit b' verglichen
(918). Wenn es kleiner als LT das Unterscheidungsbit b' ist, wird ein Eintrag
zu dem gegenwärtigen
Indexblock vor dem vorliegend indizierten Eintrag ei eingefügt (924). Der
Tiefenwert des neu eingefügten
indizierten Eintrags ei wird auf die gegenwärtig indizierte Ordnungsposition
b[k] des gegenwärtigen
Suchschlüssels
gesetzt, und der Anzeiger des vorliegend indizierten Eintrags ei wird
auf T gesetzt, was einen NULL-Eintrag bedeutet (932). Der
Index k zu den Ordnungselementen des gegenwärtigen Suchschlüssels wird
erhöht
(938). Als nächstes
wird ein Index i zu dem Eintrag des vorliegenden Indexblocks erhöht (940)
und die Schleife geht zum Schritt 918 weiter. Wenn der
vorliegende Schlüssel
K, der verarbeitet wird, größer als
der Schlüssel
Ki ist, der vorher durch den georteten Eintrag (920) geortet
wurde, wird der Merker f auf 1 gesetzt (922). Wenn er kleiner
ist, wird der Merker f auf 0 gesetzt (926). Ein Eintrag
wird dann vor dem vorliegend indizierten Eintrag ei eingefügt, (930).
Der Tiefenwert des neu eingefügten
indizierten Eintrags ei wird auf das Unterscheidungsbit b' gesetzt und der
Anzeiger des vorliegend indizierten Eintrags wird auf Nicht-NULL
oder (F) (934) gesetzt, und das Verfahren gibt den Merker
an die Aufrufroutine aus (999).
-
10) Teilungsroutinen
-
Die
Verfahren zum Teilen eines Indexblocks werden nun mit besonderer
Bezugnahme auf das Teilen eines Indexblocks nach dem Bestimmen,
dass die Anzahl der Einträge
in dem Indexblock größer als
eine vorbestimmte Indexblockvollzahl ist, und auf das Teilen eines
Blocks nach dem Bestimmen, dass die Anzahl der Einträge größer als
eine maximale Schwellzahl ist, beschrieben.
-
10a) Wurzelteilungsverfahren
-
Das
Wurzelteilungsverfahren ist in 16a veranschaulicht
und ein Beispiel eines Wurzelknotens, der geteilt wird, ist in 16b und 16c veranschaulicht.
Das Beispiel in 16b und 16c wird
nun genauer mit Bezugnahme auf die Beschreibung des Verfahrens in 16a beschrieben werden. Der Zweck dieses Verfahrens
ist es, den Wurzelknoten und Indexblock zu teilen, wenn er die vorbestimmte
Indexblockvollzahl erreicht hat, oder wenn das Programm bestimmt,
dass ein Indexblock die maximale Schwellzahl der Einträge TH erreicht
hat. Die Schritte des Verfahrens sind wie folgt.
-
Der
alte Wurzelknoten R, der in 16b veranschaulicht
ist, wird geteilt, um den neuen Wurzelknoten R' zu erzeugen, der den Indexblock I' und den Unterbaum
V' in 16c umfasst. Der alte Wurzelknoten hängt von
dem Unterbaum V' des
neuen Wurzelknotens ab. Ein neuer Wurzelknoten I', V' wird
erzeugt (1000) und das Minimaltiefenverfahren aus 18,
das beschrieben werden soll, wird aufgerufen (1002), um
den Tiefeneintrag zu bestimmen, der den minimalen Tiefenwert in
dem Wurzelindexblock I hat, der geteilt werden soll. Der Tiefenwert
des ersten Eintrags e1 des neuen Wurzelindexblocks I' wird auf den vorbestimmten
Minimaltiefenwert dmin des ersten Indexblocks I des alten Wurzelknotens
R gesetzt (1004), und der Tiefenwert des zweiten Eintrags
e2 wird auf 0 gesetzt, was der letzte Tiefenwert des Indexblock
I der alten Wurzel R, wie in 16b,
ist (1006). Der zusammengesetzte Unterbaum V' der neuen Wurzel
R' ist mit dem alten
Wurzelknoten R verbunden, der geteilt wird (1008). Die
Summe der Nicht-NULL-Einträge,
die von jedem entsprechenden Unterbaum abhängen, wird bestimmt und in
die Einträge
der Zählwertstruktur
c gelegt, wobei der erste Eintrag c[1] dem Unterbaum V0 entspricht
(1010) und der zweite Eintrag c[2] dem zweiten Unterbaum
V1 entspricht (1012). Wenn jedoch der alte Wurzelknoten
R nun eine Blattstufe ist, dann enthalten die Zählwertstruktureinträge c[1]
und c[2] einfach die Anzahl der Nicht-NULL-Einträge in ihren entsprechenden
Indexblöcken
I0 und I1. Das Verfahren
Knotenteilung, das beschrieben werden soll, teilt den alten Wurzelknoten
I, V in zwei Knoten und zwei Indexblöcke, wobei es einen Wert n
ausgibt, der gleich der Anzahl der Einträge in dem zweiten Indexblock
I1 ist (1014). Wenn das Kind oder
der zweite Indexblock I1 der zwei Indexblöcke, die
von dem neuen Wurzelknoten R' abhängen, übervoll
ist, d.h. n > TH (1016),
dann wird der zweite Kindknoten (1018) erhalten und dieses
Kind (1020) geteilt.
-
Wenn
der erste Indexblock I0, der von dem zusammengesetzten
Unterbaum V' des
neuen Wurzelknoten R' abhängt, übervoll
ist (1022), dann wird der erste Kindknoten erhalten (1024)
und geteilt (1026). Unbeachtet wird das Verfahren verlassen
(1099). Wie in 16b und 16c gezeigt, ist der alte Wurzelknoten R, der
vorher einen Indexblock I hatte, nun in zwei Indexblöcke, I0 und I1 mit entsprechenden
Unterbäumen
V0 und V1 geteilt.
-
10b) Kindteilungsverfahren
-
Das
Kindteilungsverfahren wird von dem Wurzelteilungsverfahren in den
Blöcken 1020, 1026,
das Kindteilungsverfahren im Block 1216 und das Zweigeinfügeverfahren
im Block 522 aufgerufen, wenn bestimmt wird, dass ein Indexblock übervoll
ist. Das Verfahren ist in 17 veranschaulicht.
Das Verfahren teilt weiterhin die Knoten und ihre entsprechenden
Indexblöcke,
solange bestimmt ist, dass ein Indexblock eines Kindknotens übervoll
ist. Die Schritte des Verfahrens sind wie folgt.
-
Ein
Zählwert
der Anzahl der Teilungen der Indexblöcke TEILUNGEN wird auf 0 initialisiert
(1200). Die minimale Tiefe des vorliegenden Indexblocks
wird durch Aufrufen des Minimaltiefenverfahrens bestimmt, das hier
beschrieben werden soll (1202). Als nächstes wird der vorliegende
Indexblock Ij des j-ten Knotens in zwei Indexblöcke Ij und Ij + 1 geteilt und
in zwei Unterbäume
Vj und Vj + 1 durch das hier beschriebene Knotenteilungsverfahren
geteilt (1204). Der Zählwert
der Anzahl von TEILUNGEN wird erhöht (1206). Als nächstes wird ein
Eintrag vor dem Eintrag ej in den Elternindexblock des Indexblocks
Ij, der vorliegend geteilt wird, eingefügt (1208). Der Eintrag
ej des Elternindexblocks des gegenwärtigen Indexblocks Ij, der
geteilt wird, hat seinen Tiefenwert, der auf die minimale Tiefe
dmin des gegenwärtigen
Indexblocks gesetzt wird, der geteilt wird (bestimmt durch das Minimaltiefenverfahren)
und seinen Anzeiger auf Nicht-NULL, F, gesetzt (1210).
-
Es
wird bestimmt, ob der Index imin des Eintrags, nach dem die Teilung
in dem gegenwärtigen
Indexblock auftritt, größer als
die vorbestimmte Indexblockvollzahl TH ist (1212). Wenn
dies so ist, dann wird das j-te Kind oder der erste der zwei Knoten,
die durch die vorliegende Teilung erzeugt werden, von dem Unterbaum
V geholt (1214) und geteilt (1216). Der Zählwert der
Anzahl der Teilungen wird um die Anzahl von TEILUNGEN ls in dem
j-ten Kindindexblock erhöht,
die während
des Aufrufs, das Kind im Schritt 1216 (1218) zu teilen,
auftraten, wie es der Index j des Kinds ist, das geteilt werden
soll (1220).
-
Dann
wird eine Bestimmung durchgeführt,
ob die Anzahl der Einträge
n in dem neu erzeugten Block der Teilung kleiner als die Indexblockvollzahl
TH ist (1222). Wenn nicht, dann wird der Index j des Knotens
und der entsprechende Indexblock, der geteilt werden soll, erhöht (1226)
und der neue j-te Kindknoten, der geteilt werden soll, wird von
dem Elternunterbaum des vorher geteilten Knotens und dem entsprechenden
Indexblock (1228) geholt. Wenn die Anzahl der Einträge n in
dem neuen Indexblock, der nach der Teilung erzeugt wurde, kleiner
als die Indexblockvollzahl TH ist, geht das Verfahren zu seiner
Aufrufroutine mit der Anzahl der Teilungen n zurück (1299).
-
10c) Minimaltiefenverfahren
-
Das
Minimaltiefenverfahren, das durch das Knotenteilungsverfahren in
den Blöcken 1102 und
das Kindteilungsverfahren im Block 1202 verwendet wird,
um den Index des Eintrags für
die Teilung zu bestimmen, nachdem der minimale Tiefenwert innerhalb
des Indexblocks erhalten wurde, wird durch die Schritte durchgeführt, die
in 18 veranschaulicht sind.
-
Zuerst
werden der Zählwert
cnt der Nicht-NULL-Einträge,
die vorangehen und den vorliegenden Eintrag einschließen, und
der Zählwert
c der Nicht-NULL-Einträge,
die vorangehen und den minimalen Tiefenwerteintrag einschließen, initialisiert.
Der Index imin des minimalen Eintrags und der Index j zu dem Indexblock werden
auch auf 1 gesetzt. Der Index ilast des letzten Eintrags in dem
Indexblock wird auf die Anzahl der Einträge in dem vorliegenden Indexblock
gesetzt. Schließlich
wird der Index imid des Mittelpunkts der Tiefenwerte der Einträge des gegenwärtigen Indexblocks
auf den Mittelwegspunkt ilast/2 des Index ilast des letzten Eintrags
gesetzt (1300). Der Tiefenwert dmin des Minimaltiefeneintrags
wird auf die maximale Länge
eines Suchschlüssels
plus einen M + 1 gesetzt (1302). Die Tiefe dj des vorliegenden
Eintrags wird zugeordnet (1304). Dann wird eine Bestimmung
durchgeführt
hinsichtlich dessen, ob der Anzeiger des vorliegenden Eintrags ej
T ist, was einem NULL-Eintrag entspricht (1306). Falls
nicht, wird der Zählwert
cnt der Nicht-NULL-Einträge, die
vorangehen und den vorliegenden Eintrag einschließen, erhöht (1308).
-
Es
wird bestimmt, ob der Tiefenwert dj des vorliegenden Eintrags kleiner
als der Wert des Minimaltiefeneintrags dmin ist (1310).
Wenn er kleiner ist, wird außerdem
bestimmt, ob der Index j zu dem gegenwärtigen Indexblock größer als
der Index imid des Mittelpunkts der Tiefenwerte des vorliegenden
Indexblocks ist (1312). Wenn der Index j zu dem gegenwärtigen Indexblock
kleiner als oder gleich dem Index imid des Mittelpunkts ist, dann
wird der Index imin des minimalen Eintrags auf den Index j des gegenwärtigen Eintrags
ej gesetzt und der Zählwert
c der Nicht-NULL-Einträge, die
vorangehen und den Minimaltiefeneintrag des vorliegenden Indexblocks
einschließen,
wird auf den Zählwert
CNT der Nicht-NULL-Einträge
gesetzt, die vorangehen und den vorliegenden Eintrag einschließen (1318).
Der Tiefenwert dmin des Tiefenwerteintrags wird auf den vorliegenden
Tiefenwert dj gesetzt (1320) und der Index j zu dem Eintrag
in dem gegenwärtigen
Indexblock wird erhöht (1322).
-
Wenn
der Index j zu dem gegenwärtigen
Indexblockeintrag größer als
der Index imid des Mittelpunkts in dem gegenwärtigen Indexblock beim Schritt 1312 ist,
dann wird bestimmt, ob der Index imid des Mittelpunkts minus dem
Index imin des Minimaleintrags zumindest so groß wie der Index j des gegenwärtigen Indexblockeintrags
minus dem Index imid des Mittelpunkts der Tie fenwerte des gegenwärtigen Indexblock
ist (1314). Wenn er zumindest so groß ist, dann wird der Index
imin des Minimaleintrags auf den Index j zu dem gegenwärtigen Indexblockeintrag
gesetzt, und der Zählwert
c der Nicht-NULL-Einträge,
die vorangehen und den minimalen Tiefenwert einschließen, wird
gleich dem Zählwert
cnt der Nicht-NULL-Einträge
gesetzt, die vorangehen und den vorliegenden Eintrag ej einschließen (1316).
-
Im
folgenden Schritt 1322 wird bestimmt, ob der Index j zu
dem gegenwärtigen
Indexblockeintrag gleich dem Index ilast des letzten Eintrags in
dem vorliegenden Indexblocks ist (1324). Wenn er kleiner
ist, dann geht die Schleife zu Schritt 1304 zurück. Ungeachtet
geht das Verfahren zu seiner Aufrufroutine mit dem Zählwert c
der Nicht-NULL-Einträge
zurück,
die vorangehen und den Minimaltiefenwert, den Index imin des minimalen
Eintrags und den Wert imin des Minimaltiefeneintrags einschließen (1399).
-
10d) Knotenteilungsverfahren
-
Das
Knotenteilungsverfahren, das von dem Wurzelteilungsverfahren im
Block 1014 und dem Kindteilungsverfahren im Block 1204 aufgerufen
wird, teilt den vorliegenden Knoten und seinen entsprechenden Indexblock
bei seinem Minimaltiefenwert. Das Verfahren ist in 19 veranschaulicht.
Zwei Knoten, von denen jeder einen Indexblock hat, werden erzeugt
werden. Der Indexblock I des ersten Knotens schließt den ersten Eintrag
des geteilten Indexblocks bis zu dem Minimaltiefeneintrag ein und
der Indexblock Ij p + 1 des zweiten Knotens schließt den Eintrag,
der nach dem Minimaltiefenwert auftritt, bis zu dem letzten Eintrag
der Teilung des Indexblocks ein.
-
Ein
Knoten Ij + 1, Vj + 1 wird in die vorliegende Stufe nach dem Indexblock
Ij und dem Unterbaum Vj des Knotens, der geteilt wer den soll, eingefügt (1400).
Der neu erzeugte Indexblock Ij + 1 des neuen Knotens wird Einträge von dem
Indexblock Ij, der geteilt werden soll, beginnend mit dem Eintrag
eimin+1, enthalten, der nach dem Minimaltiefenwert
bis zu dem letzten Eintrag eilast in dem
Indexblock, der geteilt werden soll, auftritt (1402). Der
Indexblock Ij, der geteilt werden soll, wird aktualisiert werden,
um seinen vorhergehenden ersten Eintrag bis zu dem Eintrag eimin zu enthalten, der den minimalen Tiefenwert
enthält
(1404). Die Anzahl n der Einträge in dem neu erzeugten Indexblock
Ij + 1 wird auf den Index ilast der Anzahl der Einträge in dem
vorliegenden Indexblock Ij, der geteilt werden soll, minus dem Index
imin des Minimaltiefeneintrags gesetzt, nach dem geteilt werden
soll (1406).
-
Das
Verfahren bestimmt dann, ob der Knoten, der geteilt werden soll,
vom Typ BLATT ist, indem es den Unterbaum Vj überprüft (1408). Wenn er
es nicht ist und der Knotentyp INNERER ist, dann wird die Zählwertstruktur
c, welche die Zählwertelemente
in dem Unterbaum Vj des Knotens einschließt, der geteilt werden soll,
geholt (1410). Die Anzahl cnt der Nicht-NULL-Einträge, die
vorangehen und den Minimaltiefenwerteintrag einschließen, wird
gleich der Summe des ersten Elements der Zählwertstruktur c bis zu dem
Element der Zählwertstruktur
gesetzt, das durch den Index imin des Eintrags indiziert ist, der
danach geteilt werden soll (1412). Die Zählwertstruktur
für die
Unterbäume
Vj + 1 des neu erzeugten Knotens enthält die Elemente der Zählwertstruktur
der Knotenteilung, die durch den Index imin + 1 des Eintrags indiziert
ist, um danach bis zu dem Index ilast des letzten Eintrags in dem
Indexblock geteilt zu werden, der geteilt wird (1414).
Die Unterbäume
von j + 1 des neu erzeugten Knotens werden auf die Unterbaumelemente
des geteilten Knotens eingestellt, der durch den Index imin + 1
des Eintrags indiziert ist, um danach bis zu dem Index ilast der
Anzahl der Einträge
in dem Indexblock Ij des vorliegend geteilten Knotens geteilt zu
werden (1416).
-
Die
Zählwertstruktur,
die zu dem Unterbaum Vj des geteilten Knotens gehört, wird
angepasst, um das erste Element bis zu dem Element einzuschließen, das
durch imin des Knotens indiziert ist, bei dem geteilt werden soll
(1418). Außerdem
werden die Unterbäume
des j-ten Knotens des geteilten Knotens angepasst, so dass sie die
Elemente, die durch das erste Element indiziert sind, bis zu dem
Index imin des Eintrags einschließen, bei dem geteilt werden
soll (1420). Die Zählwertstruktur
in der vorliegenden Stufe des Knotens, der geteilt werden soll,
wird geholt (1422). Ein Eintrag wird in die Zählwertstruktur
nach dem Element eingefügt,
das durch den Index j des Unterbaums indiziert ist, der geteilt
werden soll (1424). Dieses neu erzeugte Element c[j + 1] gehört zu dem
Zählwert
c[j] der Nicht-NULL-Einträge in dem
vorhergehenden Element der Zählwertstruktur
minus der Anzahl cnt der Nicht-NULL-Einträge, die vorangehen und den
Minimaltiefeneintrag (1426) einschließen. Das Element c[j] der Zählwertstruktur,
das durch den Index j des Unterbaums, der geteilt werden soll, indiziert
ist, wird der Anzahl cnt der Nicht-NULL-Einträge zugeordnet, die vorangehen
und den Minimaltiefeneintrag einschließen (1428). Das Verfahren
gibt dann die Anzahl n der Einträge
in dem neu erzeugten Indexblock aus (1499). Die Programmstruktur
der bevorzugten Ausführungsform
der vorliegenden Erfindung wurde oben mit Bezugnahme auf die relevanten
Verfahren im Detail beschrieben.
-
-
-
-
-
-
-
Tabelle
4 Suchschlüssel = 10011001 b[K]
= <1, 4, 5, 8,
9>