4 BTree::BTree (const std::string &name, unsigned int block_size, int tt, int kt, bool create_new_file)
9 fp = fopen (name.c_str(), "wb+");
11 /* TODO : mandar una exception ? */
15 /* Nombre de archivo */
18 /* Inicializo el header */
19 header.block_size = block_size;
20 header.tree_type = tt;
24 /* Creo el primer bloque vacio */
25 node = new uchar[block_size];
26 ReadNodoHeader (node, &nh);
28 nh.free_space = block_size - sizeof (BTreeNodeHeader);
30 WriteNodoHeader (node, &nh);
41 void BTree::WriteFileHeader ()
43 fseek (fp, 0L, SEEK_SET);
44 fwrite (&header, 1, sizeof (BTreeFileHeader), fp);
47 void BTree::WriteBlock (uchar *block, uint num)
50 fseek (fp, num*header.block_size, SEEK_SET);
51 fwrite (block, 1, header.block_size, fp);
54 void BTree::AddKey (const Clave &k)
60 kout = AddKeyR (k.Clone (), 0, left, right);
61 } catch (Exception *e) {
67 /* Debo dejar la raiz en el nodo 0, por lo que paso el nodo
68 * que esta usando el hijo izquierdo a un nuevo nodo */
69 std::list<BTreeData *> node_keys;
70 BTreeNodeHeader node_header;
71 uchar *node = ReadBlock (left);
72 ReadNodoHeader (node, &node_header);
73 node_keys = ReadKeys (node, node_header);
74 level = node_header.level + 1;
76 uchar *new_node = NewBlock (left);
77 delete [] new_node; /* No me interesa, voy a usar lo leio antes */
79 WriteKeys (node, node_header, node_keys);
80 WriteNodoHeader (node, &node_header);
81 WriteBlock (node, left);
82 DeleteKeys (node_keys);
85 /* Leo y actualizo la Raiz */
87 ReadNodoHeader (node, &node_header);
88 node_keys = std::list<BTreeData *>();
90 node_keys.push_back (new BTreeChildData (left));
91 node_keys.push_back (new BTreeData (kout, right));
93 node_header.level = level;
94 node_header.item_count = 1;
96 WriteKeys (node, node_header, node_keys);
97 WriteNodoHeader (node, &node_header);
100 DeleteKeys (node_keys);
105 Clave* BTree::AddKeyR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
107 uchar *node = ReadBlock (node_num);
108 BTreeNodeHeader node_header;
109 ReadNodoHeader (node, &node_header);
112 if (node_header.level == 0) {
114 return AddKeyLeafR (k, node_num, left_child, right_child);
115 } catch (Exception *e) {
121 return AddKeyOtherR (k, node_num, left_child, right_child);
122 } catch (Exception *e) {
127 Clave* BTree::AddKeyLeafR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
130 std::list<BTreeData *> node_keys;
132 BTreeData *data = new BTreeLeafData (k->Clone ());
134 /* Leo el nodo raiz para empezar a agregar */
135 uchar *node = ReadBlock (node_num);
136 BTreeNodeHeader node_header;
137 ReadNodoHeader (node, &node_header);
139 if (node_header.free_space > data->Size ()) {
141 node_keys = ReadKeys (node, node_header);
142 std::list<BTreeData *>::iterator it = node_keys.begin ();
144 while (it != node_keys.end ()) {
146 if (header.tree_type == TYPE_IDENTIFICACION) {
147 /* Verifico que la clave no existea ya en el arbol */
148 if ((*data) == (*datait)) {
149 throw new AddException ();
154 if ((*data) < (*datait))
155 /* Me pase, lo agrego aca! */
159 node_keys.insert (it, data);
160 WriteKeys (node, node_header, node_keys);
161 WriteNodoHeader (node, &node_header);
162 WriteBlock (node, node_num);
163 DeleteKeys (node_keys);
166 PrintNode (node_num);
168 /* Split : Creo e inicializo el nuevo nodo */
169 std::list<BTreeData *> new_node_keys;
170 std::list<BTreeData *> old_node_keys;
171 BTreeNodeHeader new_node_header;
173 uchar *new_node = NewBlock (new_node_num);
174 ReadNodoHeader (new_node, &new_node_header);
175 new_node_header.level = node_header.level;
177 node_keys = ReadKeys (node, node_header);
178 new_node_keys = ReadKeys (new_node, new_node_header);
180 /* Agrego la clave en la lista que ya tengo de manera ordenada */
181 std::list<BTreeData *>::iterator it = node_keys.begin ();
182 std::list<BTreeData *>::iterator previt = node_keys.begin ();
184 while (it != node_keys.end ()) {
187 if (header.tree_type == TYPE_IDENTIFICACION) {
188 /* Verifico que la clave no existea ya en el arbol */
189 if ((*data) == (*datait)) {
190 throw new AddException ();
194 if ((*data) < (*datait))
195 /* Me pase, lo agrego aca! */
200 if (it != node_keys.end ())
201 node_keys.insert (it, data);
203 node_keys.push_back (data);
205 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
206 * y subir la clave del medio */
207 node_header.item_count = 0;
208 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
211 it = node_keys.begin ();
212 while (it != node_keys.end ()) {
215 total_size += datait->Size ();
217 /* Hack : Si me quedo con todas las claves, en el caso de ser
218 * del mismo tama#o se desbalancea. Hay que ver que efecto
219 * puede tener en el caso de claves de long. variable
221 if (it == node_keys.end ())
222 total_size -= datait->Size ();
225 it = node_keys.begin ();
227 while (used < total_size/2) {
228 BTreeData *d = (*it);
229 old_node_keys.push_back (d);
233 kout = (*it++)->GetKey (); // Esta se retorna al "padre" para que se la agregue
235 while (it != node_keys.end ()) {
236 BTreeData *d = (*it);
237 new_node_keys.push_back (d);
242 WriteKeys (node, node_header, old_node_keys);
243 WriteNodoHeader (node, &node_header);
244 WriteBlock (node, node_num);
245 WriteKeys (new_node, new_node_header, new_node_keys);
246 WriteNodoHeader (new_node, &new_node_header);
247 WriteBlock (new_node, new_node_num);
248 DeleteKeys (old_node_keys);
249 DeleteKeys (new_node_keys);
251 PrintNode (node_num);
252 PrintNode (new_node_num);
255 left_child = node_num;
256 right_child = new_node_num;
264 Clave* BTree::AddKeyOtherR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
267 std::list<BTreeData *> node_keys;
269 BTreeData *data = new BTreeLeafData (k->Clone ());
271 /* Leo el nodo raiz para empezar a agregar */
272 uchar *node = ReadBlock (node_num);
273 BTreeNodeHeader node_header;
274 ReadNodoHeader (node, &node_header);
276 node_keys = ReadKeys (node, node_header);
278 std::list<BTreeData *>::iterator it = node_keys.begin ();
279 std::list<BTreeData *>::iterator posterior;
280 std::list<BTreeData *>::iterator ultima;
282 /* Se supone que la primera es un hijo :) */
283 BTreeData *lchild = (*it++);
286 while (it != node_keys.end ()) {
287 if (header.tree_type == TYPE_IDENTIFICACION) {
288 /* Verifico que la clave no existea ya en el arbol */
289 if ((*data) == (*(*it))) {
290 throw new AddException ();
294 if ((*data) < (*(*it)))
300 if (it == posterior) {
301 k = AddKeyR (k, lchild->GetChild (), left_child, right_child);
303 k = AddKeyR (k, (*ultima)->GetChild (), left_child, right_child);
305 DeleteKeys (node_keys);
308 if (data) delete data;
314 data = new BTreeData (k->Clone (), right_child);
316 if (node_header.free_space > data->Size ()) {
318 node_keys = ReadKeys (node, node_header);
319 std::list<BTreeData *>::iterator it = node_keys.begin ();
321 while (it != node_keys.end ()) {
323 if (header.tree_type == TYPE_IDENTIFICACION) {
324 /* Verifico que la clave no existea ya en el arbol */
325 if ((*data) == (*datait)) {
326 throw new AddException ();
330 if ((*data) < (*datait))
331 /* Me pase, lo agrego aca! */
335 node_keys.insert (it, data);
336 WriteKeys (node, node_header, node_keys);
337 WriteNodoHeader (node, &node_header);
338 WriteBlock (node, node_num);
339 DeleteKeys (node_keys);
342 PrintNode (node_num);
344 /* Split : Creo e inicializo el nuevo nodo */
345 std::list<BTreeData *> new_node_keys;
346 std::list<BTreeData *> old_node_keys;
347 BTreeNodeHeader new_node_header;
349 uchar *new_node = NewBlock (new_node_num);
350 ReadNodoHeader (new_node, &new_node_header);
351 new_node_header.level = node_header.level;
353 node_keys = ReadKeys (node, node_header);
354 new_node_keys = ReadKeys (new_node, new_node_header);
356 /* Agrego la clave en la lista que ya tengo de manera ordenada */
357 std::list<BTreeData *>::iterator it = node_keys.begin ();
358 std::list<BTreeData *>::iterator previt = node_keys.begin ();
362 while (it != node_keys.end ()) {
365 if (header.tree_type == TYPE_IDENTIFICACION) {
366 /* Verifico que la clave no existea ya en el arbol */
367 if ((*data) == (*datait)) {
368 throw new AddException ();
372 if ((*data) < (*datait))
373 /* Me pase, lo agrego aca! */
378 if (it != node_keys.end ())
379 node_keys.insert (it, data);
381 node_keys.push_back (data);
383 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
384 * y subir la clave del medio */
385 node_header.item_count = 0;
386 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
389 it = node_keys.begin ();
390 while (it != node_keys.end ()) {
393 total_size += datait->Size ();
395 /* Hack : Si me quedo con todas las claves, en el caso de ser
396 * del mismo tama#o se desbalancea. Hay que ver que efecto
397 * puede tener en el caso de claves de long. variable
399 if (it == node_keys.end ())
400 total_size -= datait->Size ();
403 it = node_keys.begin ();
405 while (used < total_size/2) {
406 BTreeData *d = (*it);
407 old_node_keys.push_back (d);
411 kout = (*it)->GetKey (); // Esta se retorna al "padre" para que se la agregue
413 new_node_keys.push_back ( new BTreeChildData ((*it)->GetChild ()));
415 while (it != node_keys.end ()) {
416 BTreeData *d = (*it);
417 new_node_keys.push_back (d);
422 WriteKeys (node, node_header, old_node_keys);
423 WriteNodoHeader (node, &node_header);
424 WriteBlock (node, node_num);
425 WriteKeys (new_node, new_node_header, new_node_keys);
426 WriteNodoHeader (new_node, &new_node_header);
427 WriteBlock (new_node, new_node_num);
428 DeleteKeys (old_node_keys);
429 DeleteKeys (new_node_keys);
431 PrintNode (node_num);
432 PrintNode (new_node_num);
435 left_child = node_num;
436 right_child = new_node_num;
444 void BTree::DelKey (const Clave &k)
447 std::cout << "========= Borrando " << s << " =================\n";
448 BTreeData *b = new BTreeLeafData (k.Clone ());
453 void BTree::DelKeyR (BTreeData *k, uint node_num, uint padre)
455 std::list<BTreeData *> node_keys;
456 BTreeNodeHeader node_header;
459 node = ReadBlock (node_num);
460 ReadNodoHeader (node, &node_header);
461 node_keys = ReadKeys (node, node_header);
463 std::list<BTreeData *>::iterator it = node_keys.begin ();
464 std::list<BTreeData *>::iterator ultima;
465 std::list<BTreeData *>::iterator posterior;
468 if (node_header.level != 0) {
473 while (it != node_keys.end ()) {
474 if ((*k) == (*(*it))) {
475 /* La encontre!, retorno */
476 if (node_header.level == 0) {
477 DelKeyFromLeaf (k->GetKey (), node_num, padre);
480 if (it == posterior) {
481 left = lchild->GetChild ();
482 right = (*it)->GetChild ();
484 left = (*ultima)->GetChild ();
485 right = (*it)->GetChild ();
487 std::cout << "Eliminar de Nodo con hijos : " << left << " y " << right << std::endl;
488 DelKeyFromNode (k->GetKey (), node_num, padre, left, right);
490 DeleteKeys (node_keys);
501 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
502 * decir que no lo encontre
504 if (node_header.level == 0) {
505 std::cout << "*** Clave no encontrada ***\n";
509 /* TODO: Aca faltaria liberar memoria */
510 if (it == posterior) {
511 DelKeyR (k, lchild->GetChild (), node_num);
513 DelKeyR (k, (*ultima)->GetChild (), node_num);
517 void BTree::DelKeyFromLeaf (Clave *k, uint node_num, uint padre)
521 BTreeNodeHeader node_header;
522 std::list<BTreeData *> node_keys;
524 node = ReadBlock (node_num);
525 ReadNodoHeader (node, &node_header);
526 node_keys = ReadKeys (node, node_header);
528 data = new BTreeLeafData (k->Clone ());
530 std::list<BTreeData *>::iterator it;
531 it = node_keys.begin ();
532 while (it != node_keys.end ()) {
533 if ((*data) == (*(*it))) {
534 BTreeData *aborrar = (*it);
535 node_keys.erase (it);
544 WriteKeys (node, node_header, node_keys);
545 WriteNodoHeader (node, &node_header);
546 WriteBlock (node, node_num);
548 /* Veo si se cumple la condición de minimalidad */
549 uint min_free = (header.block_size-sizeof(BTreeNodeHeader))/2;
550 if ((node_header.free_space > min_free) && (node_num != 0)) {
551 /* Oops! Debo pedir prestada clave */
555 FindBrothers (node_num, padre, hi, hd);
557 if ((pedida = GetKey (hi, 1)) != NULL) {
558 std::string s = *pedida;
559 std::cout << "Clave Pedida : " << s << std::endl;
561 pedida = ReplaceKeyInFather (node_num, padre, pedida);
563 node_keys.insert (node_keys.begin (), new BTreeLeafData (pedida));
564 } else if ((pedida = GetKey (hd, 0)) != NULL) {
565 std::string s = *pedida;
566 std::cout << "Clave Pedida : " << s << std::endl;
568 pedida = ReplaceKeyInFather (node_num, padre, pedida);
570 node_keys.push_back (new BTreeLeafData (pedida));
572 std::cout << "NADIE ME PUEDE PRESTAR, FUNDIR NODOS\n";
576 std::cout << "Join con Hermano Izquierdo\n";
581 std::cout << "Join con Hermano Derecho\n";
587 JoinNodes (join1, join2, padre, tipoh);
589 DeleteKeys (node_keys);
594 WriteKeys (node, node_header, node_keys);
595 WriteNodoHeader (node, &node_header);
596 WriteBlock (node, node_num);
599 DeleteKeys (node_keys);
601 std::cout << "Borrado de una hoja listo\n";
604 void BTree::JoinNodes (uint node1, uint node2, uint padre, int tipohermano)
606 uchar *n1, *n2, *npadre;
607 BTreeNodeHeader nh1, nh2, nhp;
608 std::list<BTreeData *> nk1, nk2, nkpadre;
610 if (node1 == node2) {
611 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
614 if (node1 == padre) {
615 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
618 if (node2 == padre) {
619 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
628 n1 = ReadBlock (node1);
629 n2 = ReadBlock (node2);
630 npadre = ReadBlock (padre);
632 ReadNodoHeader (n1, &nh1);
633 ReadNodoHeader (n2, &nh2);
634 ReadNodoHeader (npadre, &nhp);
637 uint tmp = header.block_size - sizeof (BTreeNodeHeader);
638 uint l = tmp - nh1.free_space;
639 l += tmp - nh1.free_space;
642 std::cout << "Espacio ocupado despues de unir : " << l << " de " << tmp << std::endl;
644 nk1 = ReadKeys (n1, nh1);
645 nk2 = ReadKeys (n2, nh2);
646 nkpadre = ReadKeys (npadre, nhp);
648 /* Busco la clave del padre a juntar con los nodos */
649 std::list<BTreeData *>::iterator it = nkpadre.begin ();
650 std::list<BTreeData *>::iterator borrar_padre;
651 std::list<BTreeData *>::iterator sig;
652 std::list<BTreeData *>::iterator anterior = it;
655 BTreeData *lchild = (*it++);
657 if (lchild->GetChild () == node1) {
658 cpadre = (*it)->GetKey ();
661 while (it != nkpadre.end ()) {
662 if (tipohermano == 0) {
663 if ((*it)->GetChild () == node2)
666 if ((*it)->GetChild () == node1)
672 cpadre = (*it)->GetKey ();
675 if (it == nkpadre.end ()) {
676 std::cout << "PANIC : Me pase sin encontrar la clave!!\n";
682 std::list<BTreeData *> newkeys;
683 std::list<BTreeData *>::iterator i;
686 while (i != nk1.end ()) {
687 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
690 //if (tipohermano == 0)
691 newkeys.push_back ( new BTreeLeafData (cpadre->Clone ()));
693 while (i != nk2.end ()) {
694 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
698 std::cout << "Espacio ocupado por las nuevas claves : " << (newkeys.size()*4) << std::endl;
699 if ((newkeys.size()*4) > tmp) {
700 std::cout << "PANIC : El nodo fundido no entra !!!\n";
704 /* Para el padre, tener 2 items significa tener solo 1 clave, ya que
705 * el otro item es el LeftChild!
707 if ((padre == 0) && (nhp.item_count == 2)) {
708 /* Si junte 2 nodos, cuyo padre era la raiz, y esta tenia
709 * solo una clave, quiere decir que lo que me queda
710 * es de nuevo solo una raiz con todas las claves
713 WriteKeys (npadre, nhp, newkeys);
714 WriteNodoHeader (npadre, &nhp);
715 WriteBlock (npadre, padre);
717 deleted_nodes.push_back (node1);
718 deleted_nodes.push_back (node2);
720 WriteKeys (n1, nh1, newkeys);
721 WriteNodoHeader (n1, &nh1);
722 WriteBlock (n1, node1);
724 deleted_nodes.push_back (node2);
726 /* Actualizo punero al padre */
727 (*anterior)->SetChild (node1);
729 nkpadre.erase (borrar_padre);
730 WriteKeys (npadre, nhp, nkpadre);
731 WriteNodoHeader (npadre, &nhp);
732 WriteBlock (npadre, padre);
735 std::cout << " ----- Luego de Fundir -----\n";
738 std::cout << " ---------------------------\n";
742 DeleteKeys (nkpadre);
743 DeleteKeys (newkeys);
750 Clave *BTree::GetKey (uint node_num, char maxmin)
753 std::cout << "Nodo no me puede prestar ... es NULL\n";
758 BTreeNodeHeader node_header;
759 std::list<BTreeData *> node_keys;
761 node = ReadBlock (node_num);
762 ReadNodoHeader (node, &node_header);
763 node_keys = ReadKeys (node, node_header);
765 std::list<BTreeData *>::iterator it = node_keys.begin ();
767 if (node_header.level != 0) it++;
770 uint free = node_header.free_space; // + (*it)->Size ();
771 uint min_free = (header.block_size - sizeof (BTreeNodeHeader))/2;
772 if (free > min_free) {
773 std::cout << "No puedo prestar : Free = " << free << " Minimo = " << min_free << std::endl;
774 PrintNode (node_num);
775 WriteKeys (node, node_header, node_keys);
776 WriteNodoHeader (node, &node_header);
777 WriteBlock (node, node_num);
778 DeleteKeys (node_keys);
786 k = (*it)->GetKey ()->Clone ();
787 node_keys.erase (it);
789 it = node_keys.end ();
791 k = (*it)->GetKey ()->Clone ();
792 node_keys.erase (it);
795 WriteKeys (node, node_header, node_keys);
796 WriteNodoHeader (node, &node_header);
797 WriteBlock (node, node_num);
798 DeleteKeys (node_keys);
805 void BTree::FindBrothers (uint node_num, uint padre, uint &left, uint &right)
808 BTreeNodeHeader node_header;
809 std::list<BTreeData *> node_keys;
811 node = ReadBlock (padre);
812 ReadNodoHeader (node, &node_header);
813 node_keys = ReadKeys (node, node_header);
815 std::list<BTreeData *>::iterator it = node_keys.begin ();
816 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
817 std::list<BTreeData *>::iterator siguiente;
819 BTreeData *lchild = (*it++);
821 if (lchild->GetChild () == node_num) {
822 /* Solo tengo hermano derecho */
823 std::cout << "Hermano Izquierdo : NO TENGO" << std::endl;
825 std::cout << "Hermano Derecho : " << (*it)->GetChild () << std::endl;
826 right = (*it)->GetChild ();
830 while (it != node_keys.end ()) {
831 if ((*it)->GetChild () == node_num)
838 std::cout << "Hermano Izquierdo : " << (*anterior)->GetChild () << std::endl;
839 left = (*anterior)->GetChild ();
840 if (siguiente != node_keys.end ()) {
841 right = (*siguiente)->GetChild ();
842 std::cout << "Hermano Derecho : " << (*siguiente)->GetChild () << std::endl;
845 std::cout << "Hermano Derecho : NO TENGO" << std::endl;
849 Clave *BTree::ReplaceKeyInFather (uint node_num, uint padre, Clave *k)
852 BTreeNodeHeader node_header;
853 std::list<BTreeData *> node_keys;
855 node = ReadBlock (padre);
856 ReadNodoHeader (node, &node_header);
857 node_keys = ReadKeys (node, node_header);
859 std::list<BTreeData *>::iterator it = node_keys.begin ();
860 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
861 std::list<BTreeData *>::iterator siguiente;
863 BTreeData *lchild = (*it++);
865 if (lchild->GetChild () == node_num) {
866 Clave *ret = (*it)->GetKey ();
869 WriteKeys (node, node_header, node_keys);
870 WriteNodoHeader (node, &node_header);
871 WriteBlock (node, padre);
872 DeleteKeys (node_keys);
878 while (it != node_keys.end ()) {
879 if ((*it)->GetChild () == node_num)
885 Clave *ret = (*it)->GetKey ();
888 WriteKeys (node, node_header, node_keys);
889 WriteNodoHeader (node, &node_header);
890 WriteBlock (node, padre);
891 DeleteKeys (node_keys);
897 void BTree::DelKeyFromNode (Clave *k, uint node_num, uint padre, uint left, uint right)
901 BTreeNodeHeader node_header;
902 std::list<BTreeData *> node_keys;
904 node = ReadBlock (node_num);
905 ReadNodoHeader (node, &node_header);
906 node_keys = ReadKeys (node, node_header);
909 std::cout << "Busco para la derecha y luego todo a la izquierda\n";
911 BTreeNodeHeader node_hr;
912 std::list<BTreeData *> node_keyr;
914 /* Busco la clave inmediatamente superior en el arbol */
915 padre_hijo = node_num;
917 node_r = ReadBlock (right);
918 ReadNodoHeader (node_r, &node_hr);
919 if (node_hr.level != 0) {
921 node_keyr = ReadKeys (node_r, node_hr);
922 data_r = *(node_keyr.begin ());
924 right = data_r->GetChild ();
926 DeleteKeys (node_keyr);
929 } while (node_hr.level != 0);
931 std::cout << "Voy a reemplazar en el nodo " << right << std::endl;
933 /* Reemplazo la clave a borrar por la de la hoja */
934 node_keyr = ReadKeys (node_r, node_hr);
935 BTreeData *reemplazar = *(node_keyr.begin ());
937 std::string ss = *reemplazar;
938 std::cout << "Voy a reemplazar por : " << ss << std::endl;
940 BTreeData *data = new BTreeLeafData (k->Clone());
942 std::list<BTreeData *>::iterator it = node_keys.begin ();
943 while (it != node_keys.end ()) {
944 std::string ss1, ss2;
947 std::cout << ss1 << " == " << ss2 << std::endl;
948 if ((*data) == (*(*it))) {
953 if (it == node_keys.end ()) {
954 std::cout << "PANIC : No encontre la clave en el nodo!!!!\n";
955 std::string s = *data;
956 std::cout << s << std::endl;
957 PrintNode (node_num);
960 (*it)->SetKey (reemplazar->GetKey ());
961 reemplazar->SetKey (k->Clone ());
963 std::cout << "Tengo todo reemplazado ...\n";
965 /* Grabo los nodos */
966 WriteKeys (node, node_header, node_keys);
967 WriteNodoHeader (node, &node_header);
968 WriteBlock (node, node_num);
969 DeleteKeys (node_keys);
972 WriteKeys (node_r, node_hr, node_keyr);
973 WriteNodoHeader (node_r, &node_hr);
974 WriteBlock (node_r, right);
975 DeleteKeys (node_keyr);
978 std::cout << "Grabe todo en disco ...\n";
979 PrintNode (node_num);
981 /* Ahora debo eliminar la clave que puse en el nodo hoja */
982 std::cout << "Borro la clave desde la hoja!\n";
984 DelKeyFromLeaf (k, right, padre_hijo);
986 std::cout << "Listo, Listo!\n";
987 } else if (left != 0) {
988 std::cout << "PANIC : Deberia poder reemplazar en la derecha!!!!!\n";
991 std::cout << "PANIC : No tengo hijos para reemplazar!!!!\n";
996 void BTree::ReadNodoHeader (uchar *node, BTreeNodeHeader *header)
998 memcpy (header, node, sizeof (BTreeNodeHeader));
1001 void BTree::WriteNodoHeader (uchar *node, BTreeNodeHeader *header)
1003 memcpy (node, header, sizeof (BTreeNodeHeader));
1006 uchar *BTree::ReadBlock (uint num)
1008 /* Como el bloque 0 se usa para el header, el Nodo "num"
1009 * está en el bloque "num+1"
1013 uchar *out = new uchar[header.block_size];
1015 fseek (fp, num*header.block_size, SEEK_SET);
1016 fread (out, 1, header.block_size, fp);
1021 std::list<BTreeData *> BTree::ReadKeys (uchar *node, BTreeNodeHeader &node_header)
1023 std::list<BTreeData *> keys;
1024 node += sizeof (BTreeNodeHeader);
1025 uint count = node_header.item_count;
1027 if (node_header.item_count == 0) return keys;
1029 if (node_header.level != 0) {
1030 /* Si no es una hoja, lo primero que tengo es un BTreeChildData */
1031 BTreeChildData *d = new BTreeChildData (node);
1037 for (uint i=0; i<count; i++) {
1039 if (node_header.level == 0) {
1040 data = new BTreeLeafData (node, header.key_type);
1042 data = new BTreeData (node, header.key_type);
1044 node += data->Size ();
1045 keys.push_back (data);
1052 void BTree::AbrevKey (std::list<BTreeData *> &lst)
1054 /* Claves Fijas No se abrevian */
1055 if (header.key_type == KEY_FIXED) return;
1057 BTreeData *primera = NULL;
1058 std::list<BTreeData *>::iterator it = lst.begin ();
1060 while (it != lst.end ()) {
1061 if ((*it)->Abrev (primera) == false)
1067 void BTree::DeAbrevKey (std::list<BTreeData *> &lst)
1069 /* Claves Fijas No se abrevian */
1070 if (header.key_type == KEY_FIXED) return;
1072 BTreeData *primera = NULL;
1073 std::list<BTreeData *>::iterator it = lst.begin ();
1075 while (it != lst.end ()) {
1076 if ((*it)->DesAbrev (primera) == false)
1082 void BTree::WriteKeys (uchar *node, BTreeNodeHeader &node_header, std::list<BTreeData *> &keys)
1086 std::list<BTreeData *>::iterator it = keys.begin ();
1088 node += sizeof (BTreeNodeHeader);
1090 node_header.item_count = 0;
1091 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
1094 while (it != keys.end ()) {
1095 BTreeData *d = (*it);
1096 uchar *n = d->ToArray ();
1097 acumulado += d->Size ();
1098 //std::cout << "WriteKeys :: Acumulado = " << acumulado << std::endl;
1099 memcpy (node, n, d->Size ());
1102 node_header.free_space -= d->Size ();
1103 node_header.item_count++;
1110 void BTree::PrintNode (uint num)
1112 uchar *node = ReadBlock (num);
1113 BTreeNodeHeader node_header;
1114 ReadNodoHeader (node, &node_header);
1116 std::list<BTreeData *> node_keys = ReadKeys (node, node_header);
1117 std::list<BTreeData *>::iterator it = node_keys.begin ();
1119 std::cout << "Nodo : " << num << std::endl;
1120 std::cout << "Level : " << node_header.level << std::endl;
1121 std::cout << "Items : " << node_header.item_count << std::endl;
1122 std::cout << "Free : " << node_header.free_space << " (" << (header.block_size - sizeof (BTreeNodeHeader)) << ")" << std::endl;
1123 while (it != node_keys.end ()) {
1124 std::string s = *(*it);
1125 std::cout << s << " ";
1128 std::cout << std::endl;
1131 DeleteKeys (node_keys);
1134 uchar *BTree::NewBlock (uint &num)
1140 std::list<uint>::iterator it;
1141 it = deleted_nodes.begin ();
1143 if (it != deleted_nodes.end ()) {
1145 deleted_nodes.erase (it);
1147 fseek (fp, 0, SEEK_END);
1148 filelen = ftell (fp);
1150 num = filelen/header.block_size - 1;
1152 node = new uchar[header.block_size];
1153 ReadNodoHeader (node, &nh);
1155 nh.free_space = header.block_size - sizeof (BTreeNodeHeader);
1157 WriteNodoHeader (node, &nh);
1158 WriteBlock (node, num);
1163 BTreeFindResult *BTree::FindKey (const Clave &k)
1165 return FindKeyR (&k, 0);
1168 BTreeFindResult *BTree::FindKeyR (const Clave *k, uint node_num)
1170 std::list<BTreeData *> node_keys;
1171 BTreeNodeHeader node_header;
1173 /* Leo el nodo raiz para empezar a agregar */
1174 uchar *node = ReadBlock (node_num);
1175 ReadNodoHeader (node, &node_header);
1176 node_keys = ReadKeys (node, node_header);
1178 std::list<BTreeData *>::iterator it = node_keys.begin ();
1179 std::list<BTreeData *>::iterator posterior;
1180 std::list<BTreeData *>::iterator ultima;
1182 /* Se supone que la primera es un hijo :) */
1184 if (node_header.level != 0) {
1190 if (node_header.level == 0)
1191 data = new BTreeLeafData (k->Clone ());
1193 data = new BTreeData (k->Clone (), 0);
1195 while (it != node_keys.end ()) {
1196 if ((*data) == (*(*it))) {
1197 /* La encontre!, retorno */
1200 DeleteKeys (node_keys);
1201 BTreeFindResult *result = new BTreeFindResult ();
1202 result->node = node_num;
1203 result->header = node_header;
1208 if ((*data) < (*(*it)))
1216 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
1217 * decir que no lo encontré
1219 if (node_header.level == 0) {
1220 DeleteKeys (node_keys);
1225 /* TODO: Aca faltaria liberar memoria */
1226 BTreeFindResult *ret;
1227 if (it == posterior)
1228 ret = FindKeyR (k, lchild->GetChild ());
1230 ret = FindKeyR (k, (*ultima)->GetChild ());
1232 DeleteKeys (node_keys);
1237 void BTree::DeleteKeys (std::list<BTreeData *> &keys)
1239 std::list<BTreeData *>::iterator it = keys.begin ();
1241 while (it != keys.end ()) {
1242 BTreeData *d = (*it);
1248 int BTree::type () const
1250 return header.key_type;