Ich schreibe einen B+ Baum aus verschiedenen Gründen und bin hierher gekommen, um eine Frage zur Implementierung seiner Knoten zu stellen. Meine Knoten sehen derzeit wie folgt aus:
struct BPlusNode
{
public:
//holds the list of keys
keyType **keys;
//stores the number of slots used
size_t size;
//holds the array of pointers to lower nodes NULL if this is a leaf node
BPlusNode **children;
//holds the pointer to the next load to the 'left'
BPlusNode *next;
//Data page pointers NULL if this is a branch node
Bucket **pages;
};
Wie Sie sehen können, verwendet meine aktuelle Implementierung * * an der Stelle, an der ich mich frage, ob ich * * oder * verwenden sollte.
Ich bin mir der Tatsache bewusst, dass * * zwei Dereferenzierungsoperationen erfordert und daher langsamer ist als die Verwendung von *, aber diese Klasse verwendet sehr viele Rekursionen, und es ist viel bequemer, Zeiger an Unteraufrufe rekursiver Funktionen zu übergeben. Um dies mit * zu tun, müsste ich eine Zeigerarithmetik durchführen und den resultierenden Zeiger übergeben.
Mit **
someFunction(BPlusNode* currNode)
{
......
someFunction(currNode->children[ChildIndex]);
}
mit *
someFunction(BPlusNode* currNode)
{
......
someFunction((currNode->children) + ChildIndex);
}
Ich kann sehen, dass es ein zusätzliches Lesen des Speichers gibt, um den Zeiger zu erzeugen, der in der * * Version gewünscht wird, aber die * * Version ist auch einfacher für mich zu denken (sie entspricht eher den Diagrammen, die ich in "The Art of Computer Programming" und auf Wikipedia sehe).
Hat jemand eine Idee für die eine oder andere Seite? Vorschläge für eine dritte Option? Beweise dafür, warum die eine der anderen überlegen ist? usw.?
Edit :
Ich könnte dies als Antwort unten posten, aber ich habe gerade festgestellt, dass ich mit dem * * Schema nicht den gesamten Inhalt jedes Unterknotens oder Buckets kopieren muss, wenn ich einen in der Mitte des Arrays einfügen möchte (d.h. die Größe des Arrays ändern). Wenn es 20 Unterknoten für das * Schema gibt und ich das Array neu zuordne, müsste ich 20*sizeof(BPlusNode) Bytes kopieren, im Gegensatz zu 20*sizeof(BPlusNode*) Bytes für das * * Schema.
Andererseits kam mir der Gedanke, dass, da ich alle Einfügungen und Seitenteilungen im Voraus durchführe, diese erhöhte Effizienz bei der Durchführung vielleicht unnötig ist und die Vorteile von * gegenüber * * bei der Suche überwiegen.