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);
36 BTree::BTree (const std::string &name)
38 /* Leo los bloques recuperables */
39 std::string del = filename + ".del";
41 fp = fopen (del.c_str (), "wb");
45 while (fread (&i, 1, sizeof (uint), fp)) {
46 deleted_nodes.push_back (i);
52 fp = fopen (name.c_str(), "rb+");
54 /* TODO : mandar una exception ? */
64 std::string del = filename + ".del";
66 fp = fopen (del.c_str (), "wb");
67 std::list<uint>::iterator it = deleted_nodes.begin ();
69 while (it != deleted_nodes.end ()) {
71 fwrite (&i, 1, sizeof (uint), fp);
78 void BTree::ReadFileHeader ()
80 fseek (fp, 0L, SEEK_SET);
81 fread (&header, 1, sizeof (BTreeFileHeader), fp);
84 void BTree::WriteFileHeader ()
86 fseek (fp, 0L, SEEK_SET);
87 fwrite (&header, 1, sizeof (BTreeFileHeader), fp);
90 void BTree::WriteBlock (uchar *block, uint num)
93 fseek (fp, num*header.block_size, SEEK_SET);
94 fwrite (block, 1, header.block_size, fp);
97 void BTree::AddKey (const Clave &k)
103 kout = AddKeyR (k.Clone (), 0, left, right);
104 } catch (Exception *e) {
109 unsigned short level;
110 /* Debo dejar la raiz en el nodo 0, por lo que paso el nodo
111 * que esta usando el hijo izquierdo a un nuevo nodo */
112 std::list<BTreeData *> node_keys;
113 BTreeNodeHeader node_header;
114 uchar *node = ReadBlock (left);
115 ReadNodoHeader (node, &node_header);
116 node_keys = ReadKeys (node, node_header);
117 level = node_header.level + 1;
119 uchar *new_node = NewBlock (left);
120 delete [] new_node; /* No me interesa, voy a usar lo leio antes */
122 WriteKeys (node, node_header, node_keys);
123 WriteNodoHeader (node, &node_header);
124 WriteBlock (node, left);
125 DeleteKeys (node_keys);
128 /* Leo y actualizo la Raiz */
129 node = ReadBlock (0);
130 ReadNodoHeader (node, &node_header);
131 node_keys = std::list<BTreeData *>();
133 node_keys.push_back (new BTreeChildData (left));
134 node_keys.push_back (new BTreeData (kout, right));
136 node_header.level = level;
137 node_header.item_count = 1;
139 WriteKeys (node, node_header, node_keys);
140 WriteNodoHeader (node, &node_header);
141 WriteBlock (node, 0);
143 DeleteKeys (node_keys);
148 Clave* BTree::AddKeyR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
150 uchar *node = ReadBlock (node_num);
151 BTreeNodeHeader node_header;
152 ReadNodoHeader (node, &node_header);
155 if (node_header.level == 0) {
157 return AddKeyLeafR (k, node_num, left_child, right_child);
158 } catch (Exception *e) {
164 return AddKeyOtherR (k, node_num, left_child, right_child);
165 } catch (Exception *e) {
170 Clave* BTree::AddKeyLeafR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
173 std::list<BTreeData *> node_keys;
175 BTreeData *data = new BTreeLeafData (k->Clone ());
177 /* Leo el nodo raiz para empezar a agregar */
178 uchar *node = ReadBlock (node_num);
179 BTreeNodeHeader node_header;
180 ReadNodoHeader (node, &node_header);
182 if (node_header.free_space > data->Size ()) {
184 node_keys = ReadKeys (node, node_header);
185 std::list<BTreeData *>::iterator it = node_keys.begin ();
187 while (it != node_keys.end ()) {
189 if (header.tree_type == TYPE_IDENTIFICACION) {
190 /* Verifico que la clave no existea ya en el arbol */
191 if ((*data) == (*datait)) {
192 throw new AddException ();
197 if ((*data) < (*datait))
198 /* Me pase, lo agrego aca! */
202 node_keys.insert (it, data);
203 WriteKeys (node, node_header, node_keys);
204 WriteNodoHeader (node, &node_header);
205 WriteBlock (node, node_num);
206 DeleteKeys (node_keys);
209 PrintNode (node_num);
211 /* Split : Creo e inicializo el nuevo nodo */
212 std::list<BTreeData *> new_node_keys;
213 std::list<BTreeData *> old_node_keys;
214 BTreeNodeHeader new_node_header;
216 uchar *new_node = NewBlock (new_node_num);
217 ReadNodoHeader (new_node, &new_node_header);
218 new_node_header.level = node_header.level;
220 node_keys = ReadKeys (node, node_header);
221 new_node_keys = ReadKeys (new_node, new_node_header);
223 /* Agrego la clave en la lista que ya tengo de manera ordenada */
224 std::list<BTreeData *>::iterator it = node_keys.begin ();
225 std::list<BTreeData *>::iterator previt = node_keys.begin ();
227 while (it != node_keys.end ()) {
230 if (header.tree_type == TYPE_IDENTIFICACION) {
231 /* Verifico que la clave no existea ya en el arbol */
232 if ((*data) == (*datait)) {
233 throw new AddException ();
237 if ((*data) < (*datait))
238 /* Me pase, lo agrego aca! */
243 if (it != node_keys.end ())
244 node_keys.insert (it, data);
246 node_keys.push_back (data);
248 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
249 * y subir la clave del medio */
250 node_header.item_count = 0;
251 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
254 it = node_keys.begin ();
255 while (it != node_keys.end ()) {
258 total_size += datait->Size ();
260 /* Hack : Si me quedo con todas las claves, en el caso de ser
261 * del mismo tama#o se desbalancea. Hay que ver que efecto
262 * puede tener en el caso de claves de long. variable
264 if (it == node_keys.end ())
265 total_size -= datait->Size ();
268 it = node_keys.begin ();
270 while (used < total_size/2) {
271 BTreeData *d = (*it);
272 old_node_keys.push_back (d);
276 kout = (*it++)->GetKey (); // Esta se retorna al "padre" para que se la agregue
278 while (it != node_keys.end ()) {
279 BTreeData *d = (*it);
280 new_node_keys.push_back (d);
285 WriteKeys (node, node_header, old_node_keys);
286 WriteNodoHeader (node, &node_header);
287 WriteBlock (node, node_num);
288 WriteKeys (new_node, new_node_header, new_node_keys);
289 WriteNodoHeader (new_node, &new_node_header);
290 WriteBlock (new_node, new_node_num);
291 DeleteKeys (old_node_keys);
292 DeleteKeys (new_node_keys);
294 PrintNode (node_num);
295 PrintNode (new_node_num);
298 left_child = node_num;
299 right_child = new_node_num;
307 Clave* BTree::AddKeyOtherR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
310 std::list<BTreeData *> node_keys;
312 BTreeData *data = new BTreeLeafData (k->Clone ());
314 /* Leo el nodo raiz para empezar a agregar */
315 uchar *node = ReadBlock (node_num);
316 BTreeNodeHeader node_header;
317 ReadNodoHeader (node, &node_header);
319 node_keys = ReadKeys (node, node_header);
321 std::list<BTreeData *>::iterator it = node_keys.begin ();
322 std::list<BTreeData *>::iterator posterior;
323 std::list<BTreeData *>::iterator ultima;
325 /* Se supone que la primera es un hijo :) */
326 BTreeData *lchild = (*it++);
329 while (it != node_keys.end ()) {
330 if (header.tree_type == TYPE_IDENTIFICACION) {
331 /* Verifico que la clave no existea ya en el arbol */
332 if ((*data) == (*(*it))) {
333 throw new AddException ();
337 if ((*data) < (*(*it)))
343 if (it == posterior) {
344 k = AddKeyR (k, lchild->GetChild (), left_child, right_child);
346 k = AddKeyR (k, (*ultima)->GetChild (), left_child, right_child);
348 DeleteKeys (node_keys);
351 if (data) delete data;
357 data = new BTreeData (k->Clone (), right_child);
359 if (node_header.free_space > data->Size ()) {
361 node_keys = ReadKeys (node, node_header);
362 std::list<BTreeData *>::iterator it = node_keys.begin ();
364 while (it != node_keys.end ()) {
366 if (header.tree_type == TYPE_IDENTIFICACION) {
367 /* Verifico que la clave no existea ya en el arbol */
368 if ((*data) == (*datait)) {
369 throw new AddException ();
373 if ((*data) < (*datait))
374 /* Me pase, lo agrego aca! */
378 node_keys.insert (it, data);
379 WriteKeys (node, node_header, node_keys);
380 WriteNodoHeader (node, &node_header);
381 WriteBlock (node, node_num);
382 DeleteKeys (node_keys);
385 PrintNode (node_num);
387 /* Split : Creo e inicializo el nuevo nodo */
388 std::list<BTreeData *> new_node_keys;
389 std::list<BTreeData *> old_node_keys;
390 BTreeNodeHeader new_node_header;
392 uchar *new_node = NewBlock (new_node_num);
393 ReadNodoHeader (new_node, &new_node_header);
394 new_node_header.level = node_header.level;
396 node_keys = ReadKeys (node, node_header);
397 new_node_keys = ReadKeys (new_node, new_node_header);
399 /* Agrego la clave en la lista que ya tengo de manera ordenada */
400 std::list<BTreeData *>::iterator it = node_keys.begin ();
401 std::list<BTreeData *>::iterator previt = node_keys.begin ();
405 while (it != node_keys.end ()) {
408 if (header.tree_type == TYPE_IDENTIFICACION) {
409 /* Verifico que la clave no existea ya en el arbol */
410 if ((*data) == (*datait)) {
411 throw new AddException ();
415 if ((*data) < (*datait))
416 /* Me pase, lo agrego aca! */
421 if (it != node_keys.end ())
422 node_keys.insert (it, data);
424 node_keys.push_back (data);
426 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
427 * y subir la clave del medio */
428 node_header.item_count = 0;
429 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
432 it = node_keys.begin ();
433 while (it != node_keys.end ()) {
436 total_size += datait->Size ();
438 /* Hack : Si me quedo con todas las claves, en el caso de ser
439 * del mismo tama#o se desbalancea. Hay que ver que efecto
440 * puede tener en el caso de claves de long. variable
442 if (it == node_keys.end ())
443 total_size -= datait->Size ();
446 it = node_keys.begin ();
448 while (used < total_size/2) {
449 BTreeData *d = (*it);
450 old_node_keys.push_back (d);
454 kout = (*it)->GetKey (); // Esta se retorna al "padre" para que se la agregue
456 new_node_keys.push_back ( new BTreeChildData ((*it)->GetChild ()));
458 while (it != node_keys.end ()) {
459 BTreeData *d = (*it);
460 new_node_keys.push_back (d);
465 WriteKeys (node, node_header, old_node_keys);
466 WriteNodoHeader (node, &node_header);
467 WriteBlock (node, node_num);
468 WriteKeys (new_node, new_node_header, new_node_keys);
469 WriteNodoHeader (new_node, &new_node_header);
470 WriteBlock (new_node, new_node_num);
471 DeleteKeys (old_node_keys);
472 DeleteKeys (new_node_keys);
474 PrintNode (node_num);
475 PrintNode (new_node_num);
478 left_child = node_num;
479 right_child = new_node_num;
487 void BTree::DelKey (const Clave &k)
490 std::cout << "========= Borrando " << s << " =================\n";
491 BTreeData *b = new BTreeLeafData (k.Clone ());
496 void BTree::DelKeyR (BTreeData *k, uint node_num, uint padre)
498 std::list<BTreeData *> node_keys;
499 BTreeNodeHeader node_header;
502 node = ReadBlock (node_num);
503 ReadNodoHeader (node, &node_header);
504 node_keys = ReadKeys (node, node_header);
506 std::list<BTreeData *>::iterator it = node_keys.begin ();
507 std::list<BTreeData *>::iterator ultima;
508 std::list<BTreeData *>::iterator posterior;
511 if (node_header.level != 0) {
516 while (it != node_keys.end ()) {
517 if ((*k) == (*(*it))) {
518 /* La encontre!, retorno */
519 if (node_header.level == 0) {
520 DelKeyFromLeaf (k->GetKey (), node_num, padre);
523 if (it == posterior) {
524 left = lchild->GetChild ();
525 right = (*it)->GetChild ();
527 left = (*ultima)->GetChild ();
528 right = (*it)->GetChild ();
530 std::cout << "Eliminar de Nodo con hijos : " << left << " y " << right << std::endl;
531 DelKeyFromNode (k->GetKey (), node_num, padre, left, right);
533 DeleteKeys (node_keys);
544 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
545 * decir que no lo encontre
547 if (node_header.level == 0) {
548 std::cout << "*** Clave no encontrada ***\n";
552 /* TODO: Aca faltaria liberar memoria */
553 if (it == posterior) {
554 DelKeyR (k, lchild->GetChild (), node_num);
556 DelKeyR (k, (*ultima)->GetChild (), node_num);
560 void BTree::DelKeyFromLeaf (Clave *k, uint node_num, uint padre)
564 BTreeNodeHeader node_header;
565 std::list<BTreeData *> node_keys;
567 node = ReadBlock (node_num);
568 ReadNodoHeader (node, &node_header);
569 node_keys = ReadKeys (node, node_header);
571 data = new BTreeLeafData (k->Clone ());
573 std::list<BTreeData *>::iterator it;
574 it = node_keys.begin ();
575 while (it != node_keys.end ()) {
576 if ((*data) == (*(*it))) {
577 BTreeData *aborrar = (*it);
578 node_keys.erase (it);
587 WriteKeys (node, node_header, node_keys);
588 WriteNodoHeader (node, &node_header);
589 WriteBlock (node, node_num);
591 /* Veo si se cumple la condición de minimalidad */
592 uint min_free = (header.block_size-sizeof(BTreeNodeHeader))/2;
593 if ((node_header.free_space > min_free) && (node_num != 0)) {
594 /* Oops! Debo pedir prestada clave */
598 FindBrothers (node_num, padre, hi, hd);
600 if ((pedida = GetKey (hi, 1)) != NULL) {
601 std::string s = *pedida;
602 std::cout << "Clave Pedida : " << s << std::endl;
604 pedida = ReplaceKeyInFather (node_num, padre, pedida);
606 node_keys.insert (node_keys.begin (), new BTreeLeafData (pedida));
607 } else if ((pedida = GetKey (hd, 0)) != NULL) {
608 std::string s = *pedida;
609 std::cout << "Clave Pedida : " << s << std::endl;
611 pedida = ReplaceKeyInFather (node_num, padre, pedida);
613 node_keys.push_back (new BTreeLeafData (pedida));
615 std::cout << "NADIE ME PUEDE PRESTAR, FUNDIR NODOS\n";
619 std::cout << "Join con Hermano Izquierdo\n";
624 std::cout << "Join con Hermano Derecho\n";
630 JoinNodes (join1, join2, padre, tipoh);
632 DeleteKeys (node_keys);
637 WriteKeys (node, node_header, node_keys);
638 WriteNodoHeader (node, &node_header);
639 WriteBlock (node, node_num);
642 DeleteKeys (node_keys);
644 std::cout << "Borrado de una hoja listo\n";
647 void BTree::JoinNodes (uint node1, uint node2, uint padre, int tipohermano)
649 uchar *n1, *n2, *npadre;
650 BTreeNodeHeader nh1, nh2, nhp;
651 std::list<BTreeData *> nk1, nk2, nkpadre;
653 if (node1 == node2) {
654 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
657 if (node1 == padre) {
658 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
661 if (node2 == padre) {
662 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
671 n1 = ReadBlock (node1);
672 n2 = ReadBlock (node2);
673 npadre = ReadBlock (padre);
675 ReadNodoHeader (n1, &nh1);
676 ReadNodoHeader (n2, &nh2);
677 ReadNodoHeader (npadre, &nhp);
680 uint tmp = header.block_size - sizeof (BTreeNodeHeader);
681 uint l = tmp - nh1.free_space;
682 l += tmp - nh1.free_space;
685 std::cout << "Espacio ocupado despues de unir : " << l << " de " << tmp << std::endl;
687 nk1 = ReadKeys (n1, nh1);
688 nk2 = ReadKeys (n2, nh2);
689 nkpadre = ReadKeys (npadre, nhp);
691 /* Busco la clave del padre a juntar con los nodos */
692 std::list<BTreeData *>::iterator it = nkpadre.begin ();
693 std::list<BTreeData *>::iterator borrar_padre;
694 std::list<BTreeData *>::iterator sig;
695 std::list<BTreeData *>::iterator anterior = it;
698 BTreeData *lchild = (*it++);
700 if (lchild->GetChild () == node1) {
701 cpadre = (*it)->GetKey ();
704 while (it != nkpadre.end ()) {
705 if (tipohermano == 0) {
706 if ((*it)->GetChild () == node2)
709 if ((*it)->GetChild () == node1)
715 cpadre = (*it)->GetKey ();
718 if (it == nkpadre.end ()) {
719 std::cout << "PANIC : Me pase sin encontrar la clave!!\n";
725 std::list<BTreeData *> newkeys;
726 std::list<BTreeData *>::iterator i;
729 while (i != nk1.end ()) {
730 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
733 //if (tipohermano == 0)
734 newkeys.push_back ( new BTreeLeafData (cpadre->Clone ()));
736 while (i != nk2.end ()) {
737 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
741 std::cout << "Espacio ocupado por las nuevas claves : " << (newkeys.size()*4) << std::endl;
742 if ((newkeys.size()*4) > tmp) {
743 std::cout << "PANIC : El nodo fundido no entra !!!\n";
747 /* Para el padre, tener 2 items significa tener solo 1 clave, ya que
748 * el otro item es el LeftChild!
750 if ((padre == 0) && (nhp.item_count == 2)) {
751 /* Si junte 2 nodos, cuyo padre era la raiz, y esta tenia
752 * solo una clave, quiere decir que lo que me queda
753 * es de nuevo solo una raiz con todas las claves
756 WriteKeys (npadre, nhp, newkeys);
757 WriteNodoHeader (npadre, &nhp);
758 WriteBlock (npadre, padre);
760 deleted_nodes.push_back (node1);
761 deleted_nodes.push_back (node2);
763 WriteKeys (n1, nh1, newkeys);
764 WriteNodoHeader (n1, &nh1);
765 WriteBlock (n1, node1);
767 deleted_nodes.push_back (node2);
769 /* Actualizo punero al padre */
770 (*anterior)->SetChild (node1);
772 nkpadre.erase (borrar_padre);
773 WriteKeys (npadre, nhp, nkpadre);
774 WriteNodoHeader (npadre, &nhp);
775 WriteBlock (npadre, padre);
778 std::cout << " ----- Luego de Fundir -----\n";
781 std::cout << " ---------------------------\n";
785 DeleteKeys (nkpadre);
786 DeleteKeys (newkeys);
793 Clave *BTree::GetKey (uint node_num, char maxmin)
796 std::cout << "Nodo no me puede prestar ... es NULL\n";
801 BTreeNodeHeader node_header;
802 std::list<BTreeData *> node_keys;
804 node = ReadBlock (node_num);
805 ReadNodoHeader (node, &node_header);
806 node_keys = ReadKeys (node, node_header);
808 std::list<BTreeData *>::iterator it = node_keys.begin ();
810 if (node_header.level != 0) it++;
813 uint free = node_header.free_space; // + (*it)->Size ();
814 uint min_free = (header.block_size - sizeof (BTreeNodeHeader))/2;
815 if (free > min_free) {
816 std::cout << "No puedo prestar : Free = " << free << " Minimo = " << min_free << std::endl;
817 PrintNode (node_num);
818 WriteKeys (node, node_header, node_keys);
819 WriteNodoHeader (node, &node_header);
820 WriteBlock (node, node_num);
821 DeleteKeys (node_keys);
829 k = (*it)->GetKey ()->Clone ();
830 node_keys.erase (it);
832 it = node_keys.end ();
834 k = (*it)->GetKey ()->Clone ();
835 node_keys.erase (it);
838 WriteKeys (node, node_header, node_keys);
839 WriteNodoHeader (node, &node_header);
840 WriteBlock (node, node_num);
841 DeleteKeys (node_keys);
848 void BTree::FindBrothers (uint node_num, uint padre, uint &left, uint &right)
851 BTreeNodeHeader node_header;
852 std::list<BTreeData *> node_keys;
854 node = ReadBlock (padre);
855 ReadNodoHeader (node, &node_header);
856 node_keys = ReadKeys (node, node_header);
858 std::list<BTreeData *>::iterator it = node_keys.begin ();
859 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
860 std::list<BTreeData *>::iterator siguiente;
862 BTreeData *lchild = (*it++);
864 if (lchild->GetChild () == node_num) {
865 /* Solo tengo hermano derecho */
866 std::cout << "Hermano Izquierdo : NO TENGO" << std::endl;
868 std::cout << "Hermano Derecho : " << (*it)->GetChild () << std::endl;
869 right = (*it)->GetChild ();
873 while (it != node_keys.end ()) {
874 if ((*it)->GetChild () == node_num)
881 std::cout << "Hermano Izquierdo : " << (*anterior)->GetChild () << std::endl;
882 left = (*anterior)->GetChild ();
883 if (siguiente != node_keys.end ()) {
884 right = (*siguiente)->GetChild ();
885 std::cout << "Hermano Derecho : " << (*siguiente)->GetChild () << std::endl;
888 std::cout << "Hermano Derecho : NO TENGO" << std::endl;
892 Clave *BTree::ReplaceKeyInFather (uint node_num, uint padre, Clave *k)
895 BTreeNodeHeader node_header;
896 std::list<BTreeData *> node_keys;
898 node = ReadBlock (padre);
899 ReadNodoHeader (node, &node_header);
900 node_keys = ReadKeys (node, node_header);
902 std::list<BTreeData *>::iterator it = node_keys.begin ();
903 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
904 std::list<BTreeData *>::iterator siguiente;
906 BTreeData *lchild = (*it++);
908 if (lchild->GetChild () == node_num) {
909 Clave *ret = (*it)->GetKey ();
912 WriteKeys (node, node_header, node_keys);
913 WriteNodoHeader (node, &node_header);
914 WriteBlock (node, padre);
915 DeleteKeys (node_keys);
921 while (it != node_keys.end ()) {
922 if ((*it)->GetChild () == node_num)
928 Clave *ret = (*it)->GetKey ();
931 WriteKeys (node, node_header, node_keys);
932 WriteNodoHeader (node, &node_header);
933 WriteBlock (node, padre);
934 DeleteKeys (node_keys);
940 void BTree::DelKeyFromNode (Clave *k, uint node_num, uint padre, uint left, uint right)
944 BTreeNodeHeader node_header;
945 std::list<BTreeData *> node_keys;
947 node = ReadBlock (node_num);
948 ReadNodoHeader (node, &node_header);
949 node_keys = ReadKeys (node, node_header);
952 std::cout << "Busco para la derecha y luego todo a la izquierda\n";
954 BTreeNodeHeader node_hr;
955 std::list<BTreeData *> node_keyr;
957 /* Busco la clave inmediatamente superior en el arbol */
958 padre_hijo = node_num;
960 node_r = ReadBlock (right);
961 ReadNodoHeader (node_r, &node_hr);
962 if (node_hr.level != 0) {
964 node_keyr = ReadKeys (node_r, node_hr);
965 data_r = *(node_keyr.begin ());
967 right = data_r->GetChild ();
969 DeleteKeys (node_keyr);
972 } while (node_hr.level != 0);
974 std::cout << "Voy a reemplazar en el nodo " << right << std::endl;
976 /* Reemplazo la clave a borrar por la de la hoja */
977 node_keyr = ReadKeys (node_r, node_hr);
978 BTreeData *reemplazar = *(node_keyr.begin ());
980 std::string ss = *reemplazar;
981 std::cout << "Voy a reemplazar por : " << ss << std::endl;
983 BTreeData *data = new BTreeLeafData (k->Clone());
985 std::list<BTreeData *>::iterator it = node_keys.begin ();
986 while (it != node_keys.end ()) {
987 std::string ss1, ss2;
990 std::cout << ss1 << " == " << ss2 << std::endl;
991 if ((*data) == (*(*it))) {
996 if (it == node_keys.end ()) {
997 std::cout << "PANIC : No encontre la clave en el nodo!!!!\n";
998 std::string s = *data;
999 std::cout << s << std::endl;
1000 PrintNode (node_num);
1003 (*it)->SetKey (reemplazar->GetKey ());
1004 reemplazar->SetKey (k->Clone ());
1006 std::cout << "Tengo todo reemplazado ...\n";
1008 /* Grabo los nodos */
1009 WriteKeys (node, node_header, node_keys);
1010 WriteNodoHeader (node, &node_header);
1011 WriteBlock (node, node_num);
1012 DeleteKeys (node_keys);
1015 WriteKeys (node_r, node_hr, node_keyr);
1016 WriteNodoHeader (node_r, &node_hr);
1017 WriteBlock (node_r, right);
1018 DeleteKeys (node_keyr);
1021 std::cout << "Grabe todo en disco ...\n";
1022 PrintNode (node_num);
1024 /* Ahora debo eliminar la clave que puse en el nodo hoja */
1025 std::cout << "Borro la clave desde la hoja!\n";
1027 DelKeyFromLeaf (k, right, padre_hijo);
1029 std::cout << "Listo, Listo!\n";
1030 } else if (left != 0) {
1031 std::cout << "PANIC : Deberia poder reemplazar en la derecha!!!!!\n";
1034 std::cout << "PANIC : No tengo hijos para reemplazar!!!!\n";
1039 void BTree::ReadNodoHeader (uchar *node, BTreeNodeHeader *header)
1041 memcpy (header, node, sizeof (BTreeNodeHeader));
1044 void BTree::WriteNodoHeader (uchar *node, BTreeNodeHeader *header)
1046 memcpy (node, header, sizeof (BTreeNodeHeader));
1049 uchar *BTree::ReadBlock (uint num)
1051 /* Como el bloque 0 se usa para el header, el Nodo "num"
1052 * está en el bloque "num+1"
1056 uchar *out = new uchar[header.block_size];
1058 fseek (fp, num*header.block_size, SEEK_SET);
1059 fread (out, 1, header.block_size, fp);
1064 std::list<BTreeData *> BTree::ReadKeys (uchar *node, BTreeNodeHeader &node_header)
1066 std::list<BTreeData *> keys;
1067 node += sizeof (BTreeNodeHeader);
1068 uint count = node_header.item_count;
1070 if (node_header.item_count == 0) return keys;
1072 if (node_header.level != 0) {
1073 /* Si no es una hoja, lo primero que tengo es un BTreeChildData */
1074 BTreeChildData *d = new BTreeChildData (node);
1080 for (uint i=0; i<count; i++) {
1082 if (node_header.level == 0) {
1083 data = new BTreeLeafData (node, header.key_type);
1085 data = new BTreeData (node, header.key_type);
1087 node += data->Size ();
1088 keys.push_back (data);
1095 void BTree::AbrevKey (std::list<BTreeData *> &lst)
1097 /* Claves Fijas No se abrevian */
1098 if (header.key_type == KEY_FIXED) return;
1100 BTreeData *primera = NULL;
1101 std::list<BTreeData *>::iterator it = lst.begin ();
1103 while (it != lst.end ()) {
1104 if ((*it)->Abrev (primera) == false)
1110 void BTree::DeAbrevKey (std::list<BTreeData *> &lst)
1112 /* Claves Fijas No se abrevian */
1113 if (header.key_type == KEY_FIXED) return;
1115 BTreeData *primera = NULL;
1116 std::list<BTreeData *>::iterator it = lst.begin ();
1118 while (it != lst.end ()) {
1119 if ((*it)->DesAbrev (primera) == false)
1125 void BTree::WriteKeys (uchar *node, BTreeNodeHeader &node_header, std::list<BTreeData *> &keys)
1129 std::list<BTreeData *>::iterator it = keys.begin ();
1131 node += sizeof (BTreeNodeHeader);
1133 node_header.item_count = 0;
1134 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
1137 while (it != keys.end ()) {
1138 BTreeData *d = (*it);
1139 uchar *n = d->ToArray ();
1140 acumulado += d->Size ();
1141 //std::cout << "WriteKeys :: Acumulado = " << acumulado << std::endl;
1142 memcpy (node, n, d->Size ());
1145 node_header.free_space -= d->Size ();
1146 node_header.item_count++;
1153 void BTree::PrintNode (uint num)
1155 uchar *node = ReadBlock (num);
1156 BTreeNodeHeader node_header;
1157 ReadNodoHeader (node, &node_header);
1159 std::list<BTreeData *> node_keys = ReadKeys (node, node_header);
1160 std::list<BTreeData *>::iterator it = node_keys.begin ();
1162 std::cout << "Nodo : " << num << std::endl;
1163 std::cout << "Level : " << node_header.level << std::endl;
1164 std::cout << "Items : " << node_header.item_count << std::endl;
1165 std::cout << "Free : " << node_header.free_space << " (" << (header.block_size - sizeof (BTreeNodeHeader)) << ")" << std::endl;
1166 while (it != node_keys.end ()) {
1167 std::string s = *(*it);
1168 std::cout << s << " ";
1171 std::cout << std::endl;
1174 DeleteKeys (node_keys);
1177 uchar *BTree::NewBlock (uint &num)
1183 std::list<uint>::iterator it;
1185 if (deleted_nodes.size ()) {
1186 it = deleted_nodes.begin ();
1188 deleted_nodes.erase (it);
1190 fseek (fp, 0, SEEK_END);
1191 filelen = ftell (fp);
1193 num = filelen/header.block_size - 1;
1195 node = new uchar[header.block_size];
1196 ReadNodoHeader (node, &nh);
1198 nh.free_space = header.block_size - sizeof (BTreeNodeHeader);
1200 WriteNodoHeader (node, &nh);
1201 WriteBlock (node, num);
1206 BTreeFindResult *BTree::FindKey (const Clave &k)
1208 return FindKeyR (&k, 0);
1211 BTreeFindResult *BTree::FindKeyR (const Clave *k, uint node_num)
1213 std::list<BTreeData *> node_keys;
1214 BTreeNodeHeader node_header;
1216 /* Leo el nodo raiz para empezar a agregar */
1217 uchar *node = ReadBlock (node_num);
1218 ReadNodoHeader (node, &node_header);
1219 node_keys = ReadKeys (node, node_header);
1221 std::list<BTreeData *>::iterator it = node_keys.begin ();
1222 std::list<BTreeData *>::iterator posterior;
1223 std::list<BTreeData *>::iterator ultima;
1225 /* Se supone que la primera es un hijo :) */
1227 if (node_header.level != 0) {
1233 if (node_header.level == 0)
1234 data = new BTreeLeafData (k->Clone ());
1236 data = new BTreeData (k->Clone (), 0);
1238 while (it != node_keys.end ()) {
1239 if ((*data) == (*(*it))) {
1240 /* La encontre!, retorno */
1243 DeleteKeys (node_keys);
1244 BTreeFindResult *result = new BTreeFindResult ();
1245 result->node = node_num;
1246 result->header = node_header;
1251 if ((*data) < (*(*it)))
1259 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
1260 * decir que no lo encontré
1262 if (node_header.level == 0) {
1263 DeleteKeys (node_keys);
1268 /* TODO: Aca faltaria liberar memoria */
1269 BTreeFindResult *ret;
1270 if (it == posterior)
1271 ret = FindKeyR (k, lchild->GetChild ());
1273 ret = FindKeyR (k, (*ultima)->GetChild ());
1275 DeleteKeys (node_keys);
1280 void BTree::DeleteKeys (std::list<BTreeData *> &keys)
1282 std::list<BTreeData *>::iterator it = keys.begin ();
1284 while (it != keys.end ()) {
1285 BTreeData *d = (*it);
1291 int BTree::type () const
1293 return header.key_type;