X-Git-Url: https://git.llucax.com/z.facultad/75.52/treemulator.git/blobdiff_plain/d9f6b6c969656b47f1e6a051cfc65959bd5c069f..5ade66d0aa29a2fed034a93326a49b2edcd2e7ec:/src/btree.h?ds=sidebyside diff --git a/src/btree.h b/src/btree.h index df427ed..ef9f242 100644 --- a/src/btree.h +++ b/src/btree.h @@ -2,32 +2,53 @@ #ifndef _B_TREE_H #define _B_TREE_H -/** - * La estructura general del archivo seria : +/** \page page_btree Árbol B + * + * \section page_model_estructura Estructura del árbol en disco. + * + * La estructura del archivo donde se almacena el árbol es una secuencia + * de bloques de tamaño fijo parametrizable. Cada bloque representa un nodo + * del árbol, exceptuando el bloque 0 que corresponde al encabezado donde se + * guardan los parámetros del árbol. + * + *
+ * Bloque 0 Bloque 1 Bloque 2 Bloque N * +----------+----------+----------+-----+----------+ - * |FileHeader| Bloque 0 | Bloque 1 | ... | Bloque N | + * |FileHeader| Nodo 0 | Nodo 1 | ... | Nodo N-1 | * +----------+----------+----------+-----+----------+ - * + *+ * * Cada bloque tiene su propio encabezado siguiendo la siguiente * estructura : + *
* +--------------+-----------------------------------+ * | BloqueHeader | Area de Claves | * +--------------+-----------------------------------+ + ** * El area de claves depende del tipo de arbol (INDICE o EXAHUSTIVO) - * y del tipo de clave (Longitud fija o variable). + * y del tipo de Clave (ClaveFija o ClaveVariable). * - * Los nodos que "hojas" (es decir, aquellos que no tienen hijos) no + * Los nodos que son "hojas" (es decir, aquellos que no tienen hijos) no * tienen "punteros", por lo que el area de datos seria algo como : + *
* +--------------+--------------+--------------+--------------+ * | clave1,dato1 | clave2,dato2 | ............ | claveN,datoN | * +--------------+--------------+--------------+--------------+ + *+ * + * El par (claveN,datoN) es representado por la clase BTreeLeafData. * * Ahora, los bloques intermedios tienen punteros a los hijos, y * quedaria algo como : + *
* +---------+----------------------+-------+----------------------+ * | HijoIzq | clave1,dato1,HijoDer | ..... | claveN,datoN,HijoDer | * +---------+----------------------+-------+----------------------+ + *+ * + * El puntore HijoIzq es representado en memoria por la clase BTreeChildData, y + * el resto por BTreeData. * * El tamaño de la clave es variable, por lo que la cantidad de claves * que puede almacenar se basa en la cantidad de espacio libre. @@ -38,7 +59,7 @@ * juntar nodos, ya que el arbol B este es particular (Preguntar a Cerveto?). * * - * TODO : + * \todo : * * Ver como manejar las claves de manera transparente a las APIs de * agregar y de borrar (EMUFS lo solucionaba bastante bien, se puede * tomar una idea simimar) @@ -52,6 +73,7 @@ #include "clave_fija.h" #include "clave_variable.h" #include "btree_data.h" +#include "exception.h" /* alias para codear menos :) */ @@ -83,6 +105,14 @@ struct BTreeNodeHeader { unsigned int item_count; }; +/** Resultado de la búsqueda de una clave */ +struct BTreeFindResult { + /** Número de nodo que contiene la clave buscada. */ + uint node; + /** Encabezado del nodo que contiene la clave. */ + BTreeNodeHeader header; +}; + /** Modelo del árbol B * * \param filename Nombre del archivo a crear @@ -92,52 +122,77 @@ struct BTreeNodeHeader { */ class BTree { public: - BTree (const std::string &filename, unsigned int block_size, int k_t = KEY_FIXED, bool create_new_file = false); + BTree (const std::string &filename, unsigned int block_size, int t_t = TYPE_UNIQUE, int k_t = KEY_FIXED, bool create_new_file = false); ~BTree (); /** Tipos de clave a usar */ enum { - KEY_FIXED, - KEY_VARIABLE + KEY_FIXED, /**< Utilización de clave de longitud fija */ + KEY_VARIABLE /**< Utilización de clave de longitud variable */ }; + enum { + TYPE_UNIQUE, + TYPE_SELECTIVE + }; + /** Agrega una nueva clave al árbol. */ void AddKey (const Clave &k); /** Elimina una clave del árbol. */ void DelKey (const Clave &k); /** Busca si existe una clave en el árbol * - * \TODO : Deberia retornar algun tipo de dato + * \return Un BTreeFindResult que el usuario debe liberar. */ - bool FindKey (const Clave &k); + BTreeFindResult *FindKey (const Clave &k); - protected: + //protected: + /* Funciones de Alta */ Clave* AddKeyR (const Clave *k, uint node_num, uint &left_child, uint &right_child); Clave* AddKeyOtherR (const Clave *k, uint node_num, uint &left_child, uint &right_child); Clave* AddKeyLeafR (const Clave *k, uint node_num, uint &left_child, uint &right_child); - bool FindKeyR (const Clave *k, uint node); + /* Funciones de Baja */ + void DelKeyR (BTreeData *k, uint node, uint padre); + void DelKeyFromLeaf (Clave *k, uint node_num, uint padre); + void DelKeyFromNode (Clave *k, uint node_num, uint padre, uint left, uint right); + void FindBrothers (uint node_num, uint padre, uint &left, uint &right); + Clave *ReplaceKeyInFather (uint node_num, uint padre, Clave *k); + Clave *GetKey (uint node_num, char maxmin); + void JoinNodes (uint node1, uint node2, uint padre, int); + + /* Funciones de Búsqueda */ + BTreeFindResult *FindKeyR (const Clave *k, uint node); + + /* Funciones de manejo de archivo */ void WriteFileHeader (); + /* Manejo de Bloques */ void WriteBlock (uchar *block, uint num); uchar *ReadBlock (uint num); uchar *NewBlock (uint &num); + /* Manejo de headers */ void ReadNodoHeader (uchar *node, BTreeNodeHeader *header); void WriteNodoHeader (uchar *node, BTreeNodeHeader *header); + /* Manejo de claves en memoria */ std::list