4 BTree::BTree (const std::string &name, unsigned int block_size, int tt, int kt, bool create_new_file)
11 fp = fopen (name.c_str(), "wb+");
13 /* TODO : mandar una exception ? */
17 /* Nombre de archivo */
20 /* Inicializo el header */
21 header.block_size = block_size;
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 (tree_type == TYPE_UNIQUE) {
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 (tree_type == TYPE_UNIQUE) {
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 (tree_type == TYPE_UNIQUE) {
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 (tree_type == TYPE_UNIQUE) {
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 (tree_type == TYPE_UNIQUE) {
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 /* TODO: Recuperar nodo1 y nodo2 */
719 WriteKeys (n1, nh1, newkeys);
720 WriteNodoHeader (n1, &nh1);
721 WriteBlock (n1, node1);
723 /* TODO : Recuperar node2 */
724 /* Actualizo punero al padre */
725 (*anterior)->SetChild (node1);
727 nkpadre.erase (borrar_padre);
728 WriteKeys (npadre, nhp, nkpadre);
729 WriteNodoHeader (npadre, &nhp);
730 WriteBlock (npadre, padre);
733 std::cout << " ----- Luego de Fundir -----\n";
736 std::cout << " ---------------------------\n";
740 DeleteKeys (nkpadre);
741 DeleteKeys (newkeys);
748 Clave *BTree::GetKey (uint node_num, char maxmin)
751 std::cout << "Nodo no me puede prestar ... es NULL\n";
756 BTreeNodeHeader node_header;
757 std::list<BTreeData *> node_keys;
759 node = ReadBlock (node_num);
760 ReadNodoHeader (node, &node_header);
761 node_keys = ReadKeys (node, node_header);
763 std::list<BTreeData *>::iterator it = node_keys.begin ();
765 if (node_header.level != 0) it++;
768 uint free = node_header.free_space; // + (*it)->Size ();
769 uint min_free = (header.block_size - sizeof (BTreeNodeHeader))/2;
770 if (free > min_free) {
771 std::cout << "No puedo prestar : Free = " << free << " Minimo = " << min_free << std::endl;
772 PrintNode (node_num);
773 WriteKeys (node, node_header, node_keys);
774 WriteNodoHeader (node, &node_header);
775 WriteBlock (node, node_num);
776 DeleteKeys (node_keys);
784 k = (*it)->GetKey ()->Clone ();
785 node_keys.erase (it);
787 it = node_keys.end ();
789 k = (*it)->GetKey ()->Clone ();
790 node_keys.erase (it);
793 WriteKeys (node, node_header, node_keys);
794 WriteNodoHeader (node, &node_header);
795 WriteBlock (node, node_num);
796 DeleteKeys (node_keys);
803 void BTree::FindBrothers (uint node_num, uint padre, uint &left, uint &right)
806 BTreeNodeHeader node_header;
807 std::list<BTreeData *> node_keys;
809 node = ReadBlock (padre);
810 ReadNodoHeader (node, &node_header);
811 node_keys = ReadKeys (node, node_header);
813 std::list<BTreeData *>::iterator it = node_keys.begin ();
814 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
815 std::list<BTreeData *>::iterator siguiente;
817 BTreeData *lchild = (*it++);
819 if (lchild->GetChild () == node_num) {
820 /* Solo tengo hermano derecho */
821 std::cout << "Hermano Izquierdo : NO TENGO" << std::endl;
823 std::cout << "Hermano Derecho : " << (*it)->GetChild () << std::endl;
824 right = (*it)->GetChild ();
828 while (it != node_keys.end ()) {
829 if ((*it)->GetChild () == node_num)
836 std::cout << "Hermano Izquierdo : " << (*anterior)->GetChild () << std::endl;
837 left = (*anterior)->GetChild ();
838 if (siguiente != node_keys.end ()) {
839 right = (*siguiente)->GetChild ();
840 std::cout << "Hermano Derecho : " << (*siguiente)->GetChild () << std::endl;
843 std::cout << "Hermano Derecho : NO TENGO" << std::endl;
847 Clave *BTree::ReplaceKeyInFather (uint node_num, uint padre, Clave *k)
850 BTreeNodeHeader node_header;
851 std::list<BTreeData *> node_keys;
853 node = ReadBlock (padre);
854 ReadNodoHeader (node, &node_header);
855 node_keys = ReadKeys (node, node_header);
857 std::list<BTreeData *>::iterator it = node_keys.begin ();
858 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
859 std::list<BTreeData *>::iterator siguiente;
861 BTreeData *lchild = (*it++);
863 if (lchild->GetChild () == node_num) {
864 Clave *ret = (*it)->GetKey ();
867 WriteKeys (node, node_header, node_keys);
868 WriteNodoHeader (node, &node_header);
869 WriteBlock (node, padre);
870 DeleteKeys (node_keys);
876 while (it != node_keys.end ()) {
877 if ((*it)->GetChild () == node_num)
883 Clave *ret = (*it)->GetKey ();
886 WriteKeys (node, node_header, node_keys);
887 WriteNodoHeader (node, &node_header);
888 WriteBlock (node, padre);
889 DeleteKeys (node_keys);
895 void BTree::DelKeyFromNode (Clave *k, uint node_num, uint padre, uint left, uint right)
899 BTreeNodeHeader node_header;
900 std::list<BTreeData *> node_keys;
902 node = ReadBlock (node_num);
903 ReadNodoHeader (node, &node_header);
904 node_keys = ReadKeys (node, node_header);
907 std::cout << "Busco para la derecha y luego todo a la izquierda\n";
909 BTreeNodeHeader node_hr;
910 std::list<BTreeData *> node_keyr;
912 /* Busco la clave inmediatamente superior en el arbol */
913 padre_hijo = node_num;
915 node_r = ReadBlock (right);
916 ReadNodoHeader (node_r, &node_hr);
917 if (node_hr.level != 0) {
919 node_keyr = ReadKeys (node_r, node_hr);
920 data_r = *(node_keyr.begin ());
922 right = data_r->GetChild ();
924 DeleteKeys (node_keyr);
927 } while (node_hr.level != 0);
929 std::cout << "Voy a reemplazar en el nodo " << right << std::endl;
931 /* Reemplazo la clave a borrar por la de la hoja */
932 node_keyr = ReadKeys (node_r, node_hr);
933 BTreeData *reemplazar = *(node_keyr.begin ());
935 std::string ss = *reemplazar;
936 std::cout << "Voy a reemplazar por : " << ss << std::endl;
938 BTreeData *data = new BTreeLeafData (k->Clone());
940 std::list<BTreeData *>::iterator it = node_keys.begin ();
941 while (it != node_keys.end ()) {
942 std::string ss1, ss2;
945 std::cout << ss1 << " == " << ss2 << std::endl;
946 if ((*data) == (*(*it))) {
951 if (it == node_keys.end ()) {
952 std::cout << "PANIC : No encontre la clave en el nodo!!!!\n";
953 std::string s = *data;
954 std::cout << s << std::endl;
955 PrintNode (node_num);
958 (*it)->SetKey (reemplazar->GetKey ());
959 reemplazar->SetKey (k->Clone ());
961 std::cout << "Tengo todo reemplazado ...\n";
963 /* Grabo los nodos */
964 WriteKeys (node, node_header, node_keys);
965 WriteNodoHeader (node, &node_header);
966 WriteBlock (node, node_num);
967 DeleteKeys (node_keys);
970 WriteKeys (node_r, node_hr, node_keyr);
971 WriteNodoHeader (node_r, &node_hr);
972 WriteBlock (node_r, right);
973 DeleteKeys (node_keyr);
976 std::cout << "Grabe todo en disco ...\n";
977 PrintNode (node_num);
979 /* Ahora debo eliminar la clave que puse en el nodo hoja */
980 std::cout << "Borro la clave desde la hoja!\n";
982 DelKeyFromLeaf (k, right, padre_hijo);
984 std::cout << "Listo, Listo!\n";
985 } else if (left != 0) {
986 std::cout << "PANIC : Deberia poder reemplazar en la derecha!!!!!\n";
989 std::cout << "PANIC : No tengo hijos para reemplazar!!!!\n";
994 void BTree::ReadNodoHeader (uchar *node, BTreeNodeHeader *header)
996 memcpy (header, node, sizeof (BTreeNodeHeader));
999 void BTree::WriteNodoHeader (uchar *node, BTreeNodeHeader *header)
1001 memcpy (node, header, sizeof (BTreeNodeHeader));
1004 uchar *BTree::ReadBlock (uint num)
1006 /* Como el bloque 0 se usa para el header, el Nodo "num"
1007 * está en el bloque "num+1"
1011 uchar *out = new uchar[header.block_size];
1013 fseek (fp, num*header.block_size, SEEK_SET);
1014 fread (out, 1, header.block_size, fp);
1019 std::list<BTreeData *> BTree::ReadKeys (uchar *node, BTreeNodeHeader &node_header)
1021 std::list<BTreeData *> keys;
1022 node += sizeof (BTreeNodeHeader);
1023 uint count = node_header.item_count;
1025 if (node_header.item_count == 0) return keys;
1027 if (node_header.level != 0) {
1028 /* Si no es una hoja, lo primero que tengo es un BTreeChildData */
1029 BTreeChildData *d = new BTreeChildData (node);
1035 for (uint i=0; i<count; i++) {
1037 if (node_header.level == 0) {
1038 data = new BTreeLeafData (node, key_type);
1040 data = new BTreeData (node, key_type);
1042 node += data->Size ();
1043 keys.push_back (data);
1050 void BTree::AbrevKey (std::list<BTreeData *> &lst)
1052 /* Claves Fijas No se abrevian */
1053 if (key_type == KEY_FIXED) return;
1055 BTreeData *primera = NULL;
1056 std::list<BTreeData *>::iterator it = lst.begin ();
1058 while (it != lst.end ()) {
1059 if ((*it)->Abrev (primera) == false)
1065 void BTree::DeAbrevKey (std::list<BTreeData *> &lst)
1067 /* Claves Fijas No se abrevian */
1068 if (key_type == KEY_FIXED) return;
1070 BTreeData *primera = NULL;
1071 std::list<BTreeData *>::iterator it = lst.begin ();
1073 while (it != lst.end ()) {
1074 if ((*it)->DesAbrev (primera) == false)
1080 void BTree::WriteKeys (uchar *node, BTreeNodeHeader &node_header, std::list<BTreeData *> &keys)
1084 std::list<BTreeData *>::iterator it = keys.begin ();
1086 node += sizeof (BTreeNodeHeader);
1088 node_header.item_count = 0;
1089 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
1092 while (it != keys.end ()) {
1093 BTreeData *d = (*it);
1094 uchar *n = d->ToArray ();
1095 acumulado += d->Size ();
1096 //std::cout << "WriteKeys :: Acumulado = " << acumulado << std::endl;
1097 memcpy (node, n, d->Size ());
1100 node_header.free_space -= d->Size ();
1101 node_header.item_count++;
1108 void BTree::PrintNode (uint num)
1110 uchar *node = ReadBlock (num);
1111 BTreeNodeHeader node_header;
1112 ReadNodoHeader (node, &node_header);
1114 std::list<BTreeData *> node_keys = ReadKeys (node, node_header);
1115 std::list<BTreeData *>::iterator it = node_keys.begin ();
1117 std::cout << "Nodo : " << num << std::endl;
1118 std::cout << "Level : " << node_header.level << std::endl;
1119 std::cout << "Items : " << node_header.item_count << std::endl;
1120 std::cout << "Free : " << node_header.free_space << " (" << (header.block_size - sizeof (BTreeNodeHeader)) << ")" << std::endl;
1121 while (it != node_keys.end ()) {
1122 std::string s = *(*it);
1123 std::cout << s << " ";
1126 std::cout << std::endl;
1129 DeleteKeys (node_keys);
1132 uchar *BTree::NewBlock (uint &num)
1138 fseek (fp, 0, SEEK_END);
1139 filelen = ftell (fp);
1141 num = filelen/header.block_size - 1;
1143 node = new uchar[header.block_size];
1144 ReadNodoHeader (node, &nh);
1146 nh.free_space = header.block_size - sizeof (BTreeNodeHeader);
1148 WriteNodoHeader (node, &nh);
1149 WriteBlock (node, num);
1154 BTreeFindResult *BTree::FindKey (const Clave &k)
1156 return FindKeyR (&k, 0);
1159 BTreeFindResult *BTree::FindKeyR (const Clave *k, uint node_num)
1161 std::list<BTreeData *> node_keys;
1162 BTreeNodeHeader node_header;
1164 /* Leo el nodo raiz para empezar a agregar */
1165 uchar *node = ReadBlock (node_num);
1166 ReadNodoHeader (node, &node_header);
1167 node_keys = ReadKeys (node, node_header);
1169 std::list<BTreeData *>::iterator it = node_keys.begin ();
1170 std::list<BTreeData *>::iterator posterior;
1171 std::list<BTreeData *>::iterator ultima;
1173 /* Se supone que la primera es un hijo :) */
1175 if (node_header.level != 0) {
1181 if (node_header.level == 0)
1182 data = new BTreeLeafData (k->Clone ());
1184 data = new BTreeData (k->Clone (), 0);
1186 while (it != node_keys.end ()) {
1187 if ((*data) == (*(*it))) {
1188 /* La encontre!, retorno */
1191 DeleteKeys (node_keys);
1192 BTreeFindResult *result = new BTreeFindResult ();
1193 result->node = node_num;
1194 result->header = node_header;
1199 if ((*data) < (*(*it)))
1207 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
1208 * decir que no lo encontré
1210 if (node_header.level == 0) {
1211 DeleteKeys (node_keys);
1216 /* TODO: Aca faltaria liberar memoria */
1217 BTreeFindResult *ret;
1218 if (it == posterior)
1219 ret = FindKeyR (k, lchild->GetChild ());
1221 ret = FindKeyR (k, (*ultima)->GetChild ());
1223 DeleteKeys (node_keys);
1228 void BTree::DeleteKeys (std::list<BTreeData *> &keys)
1230 std::list<BTreeData *>::iterator it = keys.begin ();
1232 while (it != keys.end ()) {
1233 BTreeData *d = (*it);