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;
22 header.block_data_counter = 0;
23 strcpy (header.magic, "DILUMA");
24 header.magic[6] = '\0';
27 /* Creo el primer bloque vacio */
28 node = new uchar[block_size];
29 ReadNodoHeader (node, &nh);
31 nh.free_space = block_size - sizeof (BTreeNodeHeader);
33 WriteNodoHeader (node, &nh);
39 BTree::BTree (const std::string &name)
41 /* Leo los bloques recuperables */
42 std::string del = filename + ".del";
44 fp = fopen (del.c_str (), "wb");
48 while (fread (&i, 1, sizeof (uint), fp)) {
49 deleted_nodes.push_back (i);
55 del = filename + ".blockdel";
57 fp = fopen (del.c_str (), "wb");
61 while (fread (&i, 1, sizeof (uint), fp)) {
62 deleted_block_data.push_back (i);
68 fp = fopen (name.c_str(), "rb+");
70 /* TODO : mandar una exception ? */
80 std::string del = filename + ".del";
82 fp = fopen (del.c_str (), "wb");
83 std::list<uint>::iterator it = deleted_nodes.begin ();
85 while (it != deleted_nodes.end ()) {
87 fwrite (&i, 1, sizeof (uint), fp);
91 del = filename + ".del";
93 fp = fopen (del.c_str (), "wb");
94 it = deleted_block_data.begin ();
96 while (it != deleted_block_data.end ()) {
98 fwrite (&i, 1, sizeof (uint), fp);
104 void BTree::ReadFileHeader ()
106 fseek (fp, 0L, SEEK_SET);
107 fread (&header, 1, sizeof (BTreeFileHeader), fp);
110 void BTree::WriteFileHeader ()
112 fseek (fp, 0L, SEEK_SET);
113 fwrite (&header, 1, sizeof (BTreeFileHeader), fp);
116 void BTree::WriteBlock (uchar *block, uint num)
119 fseek (fp, num*header.block_size, SEEK_SET);
120 fwrite (block, 1, header.block_size, fp);
123 void BTree::AddKey (const Clave &k)
129 in->SetBlockData ( GetNextBlockData () );
132 kout = AddKeyR (in->Clone (), 0, left, right);
133 } catch (Exception *e) {
140 unsigned short level;
141 /* Debo dejar la raiz en el nodo 0, por lo que paso el nodo
142 * que esta usando el hijo izquierdo a un nuevo nodo */
143 std::list<BTreeData *> node_keys;
144 BTreeNodeHeader node_header;
145 uchar *node = ReadBlock (left);
146 ReadNodoHeader (node, &node_header);
147 node_keys = ReadKeys (node, node_header);
148 level = node_header.level + 1;
150 uchar *new_node = NewBlock (left);
151 delete [] new_node; /* No me interesa, voy a usar lo leio antes */
153 WriteKeys (node, node_header, node_keys);
154 WriteNodoHeader (node, &node_header);
155 WriteBlock (node, left);
156 DeleteKeys (node_keys);
159 /* Leo y actualizo la Raiz */
160 node = ReadBlock (0);
161 ReadNodoHeader (node, &node_header);
162 node_keys = std::list<BTreeData *>();
164 node_keys.push_back (new BTreeChildData (left));
165 node_keys.push_back (new BTreeData (kout, right));
167 node_header.level = level;
168 node_header.item_count = 1;
170 WriteKeys (node, node_header, node_keys);
171 WriteNodoHeader (node, &node_header);
172 WriteBlock (node, 0);
174 DeleteKeys (node_keys);
179 Clave* BTree::AddKeyR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
181 uchar *node = ReadBlock (node_num);
182 BTreeNodeHeader node_header;
183 ReadNodoHeader (node, &node_header);
186 if (node_header.level == 0) {
188 return AddKeyLeafR (k, node_num, left_child, right_child);
189 } catch (Exception *e) {
195 return AddKeyOtherR (k, node_num, left_child, right_child);
196 } catch (Exception *e) {
201 Clave* BTree::AddKeyLeafR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
204 std::list<BTreeData *> node_keys;
206 BTreeData *data = new BTreeLeafData (k->Clone ());
208 /* Leo el nodo raiz para empezar a agregar */
209 uchar *node = ReadBlock (node_num);
210 BTreeNodeHeader node_header;
211 ReadNodoHeader (node, &node_header);
213 if (node_header.free_space > data->Size ()) {
215 node_keys = ReadKeys (node, node_header);
216 std::list<BTreeData *>::iterator it = node_keys.begin ();
218 while (it != node_keys.end ()) {
220 if (header.tree_type == TYPE_IDENTIFICACION) {
221 /* Verifico que la clave no existea ya en el arbol */
222 if ((*data) == (*datait)) {
223 throw new AddException ();
228 if ((*data) < (*datait))
229 /* Me pase, lo agrego aca! */
233 node_keys.insert (it, data);
234 WriteKeys (node, node_header, node_keys);
235 WriteNodoHeader (node, &node_header);
236 WriteBlock (node, node_num);
237 DeleteKeys (node_keys);
240 PrintNode (node_num);
242 /* Split : Creo e inicializo el nuevo nodo */
243 std::list<BTreeData *> new_node_keys;
244 std::list<BTreeData *> old_node_keys;
245 BTreeNodeHeader new_node_header;
247 uchar *new_node = NewBlock (new_node_num);
248 ReadNodoHeader (new_node, &new_node_header);
249 new_node_header.level = node_header.level;
251 node_keys = ReadKeys (node, node_header);
252 new_node_keys = ReadKeys (new_node, new_node_header);
254 /* Agrego la clave en la lista que ya tengo de manera ordenada */
255 std::list<BTreeData *>::iterator it = node_keys.begin ();
256 std::list<BTreeData *>::iterator previt = node_keys.begin ();
258 while (it != node_keys.end ()) {
261 if (header.tree_type == TYPE_IDENTIFICACION) {
262 /* Verifico que la clave no existea ya en el arbol */
263 if ((*data) == (*datait)) {
264 throw new AddException ();
268 if ((*data) < (*datait))
269 /* Me pase, lo agrego aca! */
274 if (it != node_keys.end ())
275 node_keys.insert (it, data);
277 node_keys.push_back (data);
279 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
280 * y subir la clave del medio */
281 node_header.item_count = 0;
282 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
285 it = node_keys.begin ();
286 while (it != node_keys.end ()) {
289 total_size += datait->Size ();
291 /* Hack : Si me quedo con todas las claves, en el caso de ser
292 * del mismo tama#o se desbalancea. Hay que ver que efecto
293 * puede tener en el caso de claves de long. variable
295 if (it == node_keys.end ())
296 total_size -= datait->Size ();
299 it = node_keys.begin ();
301 while (used < total_size/2) {
302 BTreeData *d = (*it);
303 old_node_keys.push_back (d);
307 kout = (*it++)->GetKey (); // Esta se retorna al "padre" para que se la agregue
309 while (it != node_keys.end ()) {
310 BTreeData *d = (*it);
311 new_node_keys.push_back (d);
316 WriteKeys (node, node_header, old_node_keys);
317 WriteNodoHeader (node, &node_header);
318 WriteBlock (node, node_num);
319 WriteKeys (new_node, new_node_header, new_node_keys);
320 WriteNodoHeader (new_node, &new_node_header);
321 WriteBlock (new_node, new_node_num);
322 DeleteKeys (old_node_keys);
323 DeleteKeys (new_node_keys);
325 PrintNode (node_num);
326 PrintNode (new_node_num);
329 left_child = node_num;
330 right_child = new_node_num;
338 Clave* BTree::AddKeyOtherR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
341 std::list<BTreeData *> node_keys;
343 BTreeData *data = new BTreeLeafData (k->Clone ());
345 /* Leo el nodo raiz para empezar a agregar */
346 uchar *node = ReadBlock (node_num);
347 BTreeNodeHeader node_header;
348 ReadNodoHeader (node, &node_header);
350 node_keys = ReadKeys (node, node_header);
352 std::list<BTreeData *>::iterator it = node_keys.begin ();
353 std::list<BTreeData *>::iterator posterior;
354 std::list<BTreeData *>::iterator ultima;
356 /* Se supone que la primera es un hijo :) */
357 BTreeData *lchild = (*it++);
360 while (it != node_keys.end ()) {
361 if (header.tree_type == TYPE_IDENTIFICACION) {
362 /* Verifico que la clave no existea ya en el arbol */
363 if ((*data) == (*(*it))) {
364 throw new AddException ();
368 if ((*data) < (*(*it)))
374 if (it == posterior) {
375 k = AddKeyR (k, lchild->GetChild (), left_child, right_child);
377 k = AddKeyR (k, (*ultima)->GetChild (), left_child, right_child);
379 DeleteKeys (node_keys);
382 if (data) delete data;
388 data = new BTreeData (k->Clone (), right_child);
390 if (node_header.free_space > data->Size ()) {
392 node_keys = ReadKeys (node, node_header);
393 std::list<BTreeData *>::iterator it = node_keys.begin ();
395 while (it != node_keys.end ()) {
397 if (header.tree_type == TYPE_IDENTIFICACION) {
398 /* Verifico que la clave no existea ya en el arbol */
399 if ((*data) == (*datait)) {
400 throw new AddException ();
404 if ((*data) < (*datait))
405 /* Me pase, lo agrego aca! */
409 node_keys.insert (it, data);
410 WriteKeys (node, node_header, node_keys);
411 WriteNodoHeader (node, &node_header);
412 WriteBlock (node, node_num);
413 DeleteKeys (node_keys);
416 PrintNode (node_num);
418 /* Split : Creo e inicializo el nuevo nodo */
419 std::list<BTreeData *> new_node_keys;
420 std::list<BTreeData *> old_node_keys;
421 BTreeNodeHeader new_node_header;
423 uchar *new_node = NewBlock (new_node_num);
424 ReadNodoHeader (new_node, &new_node_header);
425 new_node_header.level = node_header.level;
427 node_keys = ReadKeys (node, node_header);
428 new_node_keys = ReadKeys (new_node, new_node_header);
430 /* Agrego la clave en la lista que ya tengo de manera ordenada */
431 std::list<BTreeData *>::iterator it = node_keys.begin ();
432 std::list<BTreeData *>::iterator previt = node_keys.begin ();
436 while (it != node_keys.end ()) {
439 if (header.tree_type == TYPE_IDENTIFICACION) {
440 /* Verifico que la clave no existea ya en el arbol */
441 if ((*data) == (*datait)) {
442 throw new AddException ();
446 if ((*data) < (*datait))
447 /* Me pase, lo agrego aca! */
452 if (it != node_keys.end ())
453 node_keys.insert (it, data);
455 node_keys.push_back (data);
457 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
458 * y subir la clave del medio */
459 node_header.item_count = 0;
460 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
463 it = node_keys.begin ();
464 while (it != node_keys.end ()) {
467 total_size += datait->Size ();
469 /* Hack : Si me quedo con todas las claves, en el caso de ser
470 * del mismo tama#o se desbalancea. Hay que ver que efecto
471 * puede tener en el caso de claves de long. variable
473 if (it == node_keys.end ())
474 total_size -= datait->Size ();
477 it = node_keys.begin ();
479 while (used < total_size/2) {
480 BTreeData *d = (*it);
481 old_node_keys.push_back (d);
485 kout = (*it)->GetKey (); // Esta se retorna al "padre" para que se la agregue
487 new_node_keys.push_back ( new BTreeChildData ((*it)->GetChild ()));
489 while (it != node_keys.end ()) {
490 BTreeData *d = (*it);
491 new_node_keys.push_back (d);
496 WriteKeys (node, node_header, old_node_keys);
497 WriteNodoHeader (node, &node_header);
498 WriteBlock (node, node_num);
499 WriteKeys (new_node, new_node_header, new_node_keys);
500 WriteNodoHeader (new_node, &new_node_header);
501 WriteBlock (new_node, new_node_num);
502 DeleteKeys (old_node_keys);
503 DeleteKeys (new_node_keys);
505 PrintNode (node_num);
506 PrintNode (new_node_num);
509 left_child = node_num;
510 right_child = new_node_num;
518 void BTree::DelKey (const Clave &k)
521 std::cout << "========= Borrando " << s << " =================\n";
522 BTreeData *b = new BTreeLeafData (k.Clone ());
527 void BTree::DelKeyR (BTreeData *k, uint node_num, uint padre)
529 std::list<BTreeData *> node_keys;
530 BTreeNodeHeader node_header;
533 node = ReadBlock (node_num);
534 ReadNodoHeader (node, &node_header);
535 node_keys = ReadKeys (node, node_header);
537 std::list<BTreeData *>::iterator it = node_keys.begin ();
538 std::list<BTreeData *>::iterator ultima;
539 std::list<BTreeData *>::iterator posterior;
542 if (node_header.level != 0) {
547 while (it != node_keys.end ()) {
548 if ((*k) == (*(*it))) {
549 /* La encontre!, retorno */
550 if (node_header.level == 0) {
551 DelKeyFromLeaf (k->GetKey (), node_num, padre);
554 if (it == posterior) {
555 left = lchild->GetChild ();
556 right = (*it)->GetChild ();
558 left = (*ultima)->GetChild ();
559 right = (*it)->GetChild ();
561 std::cout << "Eliminar de Nodo con hijos : " << left << " y " << right << std::endl;
562 DelKeyFromNode (k->GetKey (), node_num, padre, left, right);
564 DeleteKeys (node_keys);
575 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
576 * decir que no lo encontre
578 if (node_header.level == 0) {
579 std::cout << "*** Clave no encontrada ***\n";
583 /* TODO: Aca faltaria liberar memoria */
584 if (it == posterior) {
585 DelKeyR (k, lchild->GetChild (), node_num);
587 DelKeyR (k, (*ultima)->GetChild (), node_num);
591 void BTree::DelKeyFromLeaf (Clave *k, uint node_num, uint padre)
595 BTreeNodeHeader node_header;
596 std::list<BTreeData *> node_keys;
598 node = ReadBlock (node_num);
599 ReadNodoHeader (node, &node_header);
600 node_keys = ReadKeys (node, node_header);
602 data = new BTreeLeafData (k->Clone ());
604 std::list<BTreeData *>::iterator it;
605 it = node_keys.begin ();
606 while (it != node_keys.end ()) {
607 if ((*data) == (*(*it))) {
608 BTreeData *aborrar = (*it);
609 node_keys.erase (it);
610 deleted_block_data.push_back (aborrar->GetKey ()->GetBlockData ());
619 WriteKeys (node, node_header, node_keys);
620 WriteNodoHeader (node, &node_header);
621 WriteBlock (node, node_num);
623 /* Veo si se cumple la condición de minimalidad */
624 uint min_free = (header.block_size-sizeof(BTreeNodeHeader))/2;
625 if ((node_header.free_space > min_free) && (node_num != 0)) {
626 /* Oops! Debo pedir prestada clave */
630 FindBrothers (node_num, padre, hi, hd);
632 if ((pedida = GetKey (hi, 1)) != NULL) {
633 std::string s = *pedida;
634 std::cout << "Clave Pedida : " << s << std::endl;
636 pedida = ReplaceKeyInFather (node_num, padre, pedida);
638 node_keys.insert (node_keys.begin (), new BTreeLeafData (pedida));
639 } else if ((pedida = GetKey (hd, 0)) != NULL) {
640 std::string s = *pedida;
641 std::cout << "Clave Pedida : " << s << std::endl;
643 pedida = ReplaceKeyInFather (node_num, padre, pedida);
645 node_keys.push_back (new BTreeLeafData (pedida));
647 std::cout << "NADIE ME PUEDE PRESTAR, FUNDIR NODOS\n";
651 std::cout << "Join con Hermano Izquierdo\n";
656 std::cout << "Join con Hermano Derecho\n";
662 JoinNodes (join1, join2, padre, tipoh);
664 DeleteKeys (node_keys);
669 WriteKeys (node, node_header, node_keys);
670 WriteNodoHeader (node, &node_header);
671 WriteBlock (node, node_num);
674 DeleteKeys (node_keys);
676 std::cout << "Borrado de una hoja listo\n";
679 void BTree::JoinNodes (uint node1, uint node2, uint padre, int tipohermano)
681 uchar *n1, *n2, *npadre;
682 BTreeNodeHeader nh1, nh2, nhp;
683 std::list<BTreeData *> nk1, nk2, nkpadre;
685 if (node1 == node2) {
686 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
689 if (node1 == padre) {
690 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
693 if (node2 == padre) {
694 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
703 n1 = ReadBlock (node1);
704 n2 = ReadBlock (node2);
705 npadre = ReadBlock (padre);
707 ReadNodoHeader (n1, &nh1);
708 ReadNodoHeader (n2, &nh2);
709 ReadNodoHeader (npadre, &nhp);
712 uint tmp = header.block_size - sizeof (BTreeNodeHeader);
713 uint l = tmp - nh1.free_space;
714 l += tmp - nh1.free_space;
717 std::cout << "Espacio ocupado despues de unir : " << l << " de " << tmp << std::endl;
719 nk1 = ReadKeys (n1, nh1);
720 nk2 = ReadKeys (n2, nh2);
721 nkpadre = ReadKeys (npadre, nhp);
723 /* Busco la clave del padre a juntar con los nodos */
724 std::list<BTreeData *>::iterator it = nkpadre.begin ();
725 std::list<BTreeData *>::iterator borrar_padre;
726 std::list<BTreeData *>::iterator sig;
727 std::list<BTreeData *>::iterator anterior = it;
730 BTreeData *lchild = (*it++);
732 if (lchild->GetChild () == node1) {
733 cpadre = (*it)->GetKey ();
736 while (it != nkpadre.end ()) {
737 if (tipohermano == 0) {
738 if ((*it)->GetChild () == node2)
741 if ((*it)->GetChild () == node1)
747 cpadre = (*it)->GetKey ();
750 if (it == nkpadre.end ()) {
751 std::cout << "PANIC : Me pase sin encontrar la clave!!\n";
757 std::list<BTreeData *> newkeys;
758 std::list<BTreeData *>::iterator i;
761 while (i != nk1.end ()) {
762 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
765 //if (tipohermano == 0)
766 newkeys.push_back ( new BTreeLeafData (cpadre->Clone ()));
768 while (i != nk2.end ()) {
769 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
773 std::cout << "Espacio ocupado por las nuevas claves : " << (newkeys.size()*4) << std::endl;
774 if ((newkeys.size()*4) > tmp) {
775 std::cout << "PANIC : El nodo fundido no entra !!!\n";
779 /* Para el padre, tener 2 items significa tener solo 1 clave, ya que
780 * el otro item es el LeftChild!
782 if ((padre == 0) && (nhp.item_count == 2)) {
783 /* Si junte 2 nodos, cuyo padre era la raiz, y esta tenia
784 * solo una clave, quiere decir que lo que me queda
785 * es de nuevo solo una raiz con todas las claves
788 WriteKeys (npadre, nhp, newkeys);
789 WriteNodoHeader (npadre, &nhp);
790 WriteBlock (npadre, padre);
792 deleted_nodes.push_back (node1);
793 deleted_nodes.push_back (node2);
795 WriteKeys (n1, nh1, newkeys);
796 WriteNodoHeader (n1, &nh1);
797 WriteBlock (n1, node1);
799 deleted_nodes.push_back (node2);
801 /* Actualizo punero al padre */
802 (*anterior)->SetChild (node1);
804 nkpadre.erase (borrar_padre);
805 WriteKeys (npadre, nhp, nkpadre);
806 WriteNodoHeader (npadre, &nhp);
807 WriteBlock (npadre, padre);
810 std::cout << " ----- Luego de Fundir -----\n";
813 std::cout << " ---------------------------\n";
817 DeleteKeys (nkpadre);
818 DeleteKeys (newkeys);
825 Clave *BTree::GetKey (uint node_num, char maxmin)
828 std::cout << "Nodo no me puede prestar ... es NULL\n";
833 BTreeNodeHeader node_header;
834 std::list<BTreeData *> node_keys;
836 node = ReadBlock (node_num);
837 ReadNodoHeader (node, &node_header);
838 node_keys = ReadKeys (node, node_header);
840 std::list<BTreeData *>::iterator it = node_keys.begin ();
842 if (node_header.level != 0) it++;
845 uint free = node_header.free_space; // + (*it)->Size ();
846 uint min_free = (header.block_size - sizeof (BTreeNodeHeader))/2;
847 if (free > min_free) {
848 std::cout << "No puedo prestar : Free = " << free << " Minimo = " << min_free << std::endl;
849 PrintNode (node_num);
850 WriteKeys (node, node_header, node_keys);
851 WriteNodoHeader (node, &node_header);
852 WriteBlock (node, node_num);
853 DeleteKeys (node_keys);
861 k = (*it)->GetKey ()->Clone ();
862 node_keys.erase (it);
864 it = node_keys.end ();
866 k = (*it)->GetKey ()->Clone ();
867 node_keys.erase (it);
870 WriteKeys (node, node_header, node_keys);
871 WriteNodoHeader (node, &node_header);
872 WriteBlock (node, node_num);
873 DeleteKeys (node_keys);
880 void BTree::FindBrothers (uint node_num, uint padre, uint &left, uint &right)
883 BTreeNodeHeader node_header;
884 std::list<BTreeData *> node_keys;
886 node = ReadBlock (padre);
887 ReadNodoHeader (node, &node_header);
888 node_keys = ReadKeys (node, node_header);
890 std::list<BTreeData *>::iterator it = node_keys.begin ();
891 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
892 std::list<BTreeData *>::iterator siguiente;
894 BTreeData *lchild = (*it++);
896 if (lchild->GetChild () == node_num) {
897 /* Solo tengo hermano derecho */
898 std::cout << "Hermano Izquierdo : NO TENGO" << std::endl;
900 std::cout << "Hermano Derecho : " << (*it)->GetChild () << std::endl;
901 right = (*it)->GetChild ();
905 while (it != node_keys.end ()) {
906 if ((*it)->GetChild () == node_num)
913 std::cout << "Hermano Izquierdo : " << (*anterior)->GetChild () << std::endl;
914 left = (*anterior)->GetChild ();
915 if (siguiente != node_keys.end ()) {
916 right = (*siguiente)->GetChild ();
917 std::cout << "Hermano Derecho : " << (*siguiente)->GetChild () << std::endl;
920 std::cout << "Hermano Derecho : NO TENGO" << std::endl;
924 Clave *BTree::ReplaceKeyInFather (uint node_num, uint padre, Clave *k)
927 BTreeNodeHeader node_header;
928 std::list<BTreeData *> node_keys;
930 node = ReadBlock (padre);
931 ReadNodoHeader (node, &node_header);
932 node_keys = ReadKeys (node, node_header);
934 std::list<BTreeData *>::iterator it = node_keys.begin ();
935 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
936 std::list<BTreeData *>::iterator siguiente;
938 BTreeData *lchild = (*it++);
940 if (lchild->GetChild () == node_num) {
941 Clave *ret = (*it)->GetKey ();
944 WriteKeys (node, node_header, node_keys);
945 WriteNodoHeader (node, &node_header);
946 WriteBlock (node, padre);
947 DeleteKeys (node_keys);
953 while (it != node_keys.end ()) {
954 if ((*it)->GetChild () == node_num)
960 Clave *ret = (*it)->GetKey ();
963 WriteKeys (node, node_header, node_keys);
964 WriteNodoHeader (node, &node_header);
965 WriteBlock (node, padre);
966 DeleteKeys (node_keys);
972 void BTree::DelKeyFromNode (Clave *k, uint node_num, uint padre, uint left, uint right)
976 BTreeNodeHeader node_header;
977 std::list<BTreeData *> node_keys;
979 node = ReadBlock (node_num);
980 ReadNodoHeader (node, &node_header);
981 node_keys = ReadKeys (node, node_header);
984 std::cout << "Busco para la derecha y luego todo a la izquierda\n";
986 BTreeNodeHeader node_hr;
987 std::list<BTreeData *> node_keyr;
989 /* Busco la clave inmediatamente superior en el arbol */
990 padre_hijo = node_num;
992 node_r = ReadBlock (right);
993 ReadNodoHeader (node_r, &node_hr);
994 if (node_hr.level != 0) {
996 node_keyr = ReadKeys (node_r, node_hr);
997 data_r = *(node_keyr.begin ());
999 right = data_r->GetChild ();
1001 DeleteKeys (node_keyr);
1004 } while (node_hr.level != 0);
1006 std::cout << "Voy a reemplazar en el nodo " << right << std::endl;
1008 /* Reemplazo la clave a borrar por la de la hoja */
1009 node_keyr = ReadKeys (node_r, node_hr);
1010 BTreeData *reemplazar = *(node_keyr.begin ());
1012 std::string ss = *reemplazar;
1013 std::cout << "Voy a reemplazar por : " << ss << std::endl;
1015 BTreeData *data = new BTreeLeafData (k->Clone());
1017 std::list<BTreeData *>::iterator it = node_keys.begin ();
1018 while (it != node_keys.end ()) {
1019 std::string ss1, ss2;
1022 std::cout << ss1 << " == " << ss2 << std::endl;
1023 if ((*data) == (*(*it))) {
1028 if (it == node_keys.end ()) {
1029 std::cout << "PANIC : No encontre la clave en el nodo!!!!\n";
1030 std::string s = *data;
1031 std::cout << s << std::endl;
1032 PrintNode (node_num);
1035 (*it)->SetKey (reemplazar->GetKey ());
1036 reemplazar->SetKey (k->Clone ());
1038 std::cout << "Tengo todo reemplazado ...\n";
1040 /* Grabo los nodos */
1041 WriteKeys (node, node_header, node_keys);
1042 WriteNodoHeader (node, &node_header);
1043 WriteBlock (node, node_num);
1044 DeleteKeys (node_keys);
1047 WriteKeys (node_r, node_hr, node_keyr);
1048 WriteNodoHeader (node_r, &node_hr);
1049 WriteBlock (node_r, right);
1050 DeleteKeys (node_keyr);
1053 std::cout << "Grabe todo en disco ...\n";
1054 PrintNode (node_num);
1056 /* Ahora debo eliminar la clave que puse en el nodo hoja */
1057 std::cout << "Borro la clave desde la hoja!\n";
1059 DelKeyFromLeaf (k, right, padre_hijo);
1061 std::cout << "Listo, Listo!\n";
1062 } else if (left != 0) {
1063 std::cout << "PANIC : Deberia poder reemplazar en la derecha!!!!!\n";
1066 std::cout << "PANIC : No tengo hijos para reemplazar!!!!\n";
1071 void BTree::ReadNodoHeader (uchar *node, BTreeNodeHeader *header)
1073 memcpy (header, node, sizeof (BTreeNodeHeader));
1076 void BTree::WriteNodoHeader (uchar *node, BTreeNodeHeader *header)
1078 memcpy (node, header, sizeof (BTreeNodeHeader));
1081 uchar *BTree::ReadBlock (uint num)
1083 /* Como el bloque 0 se usa para el header, el Nodo "num"
1084 * está en el bloque "num+1"
1088 uchar *out = new uchar[header.block_size];
1090 fseek (fp, num*header.block_size, SEEK_SET);
1091 fread (out, 1, header.block_size, fp);
1096 std::list<BTreeData *> BTree::ReadKeys (uchar *node, BTreeNodeHeader &node_header)
1098 std::list<BTreeData *> keys;
1099 node += sizeof (BTreeNodeHeader);
1100 uint count = node_header.item_count;
1102 if (node_header.item_count == 0) return keys;
1104 if (node_header.level != 0) {
1105 /* Si no es una hoja, lo primero que tengo es un BTreeChildData */
1106 BTreeChildData *d = new BTreeChildData (node);
1112 for (uint i=0; i<count; i++) {
1114 if (node_header.level == 0) {
1115 data = new BTreeLeafData (node, header.key_type);
1117 data = new BTreeData (node, header.key_type);
1119 node += data->Size ();
1120 keys.push_back (data);
1127 void BTree::AbrevKey (std::list<BTreeData *> &lst)
1129 /* Claves Fijas No se abrevian */
1130 if (header.key_type == KEY_FIXED) return;
1132 BTreeData *primera = NULL;
1133 std::list<BTreeData *>::iterator it = lst.begin ();
1135 while (it != lst.end ()) {
1136 if ((*it)->Abrev (primera) == false)
1142 void BTree::DeAbrevKey (std::list<BTreeData *> &lst)
1144 /* Claves Fijas No se abrevian */
1145 if (header.key_type == KEY_FIXED) return;
1147 BTreeData *primera = NULL;
1148 std::list<BTreeData *>::iterator it = lst.begin ();
1150 while (it != lst.end ()) {
1151 if ((*it)->DesAbrev (primera) == false)
1157 void BTree::WriteKeys (uchar *node, BTreeNodeHeader &node_header, std::list<BTreeData *> &keys)
1161 std::list<BTreeData *>::iterator it = keys.begin ();
1163 node += sizeof (BTreeNodeHeader);
1165 node_header.item_count = 0;
1166 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
1169 while (it != keys.end ()) {
1170 BTreeData *d = (*it);
1171 uchar *n = d->ToArray ();
1172 acumulado += d->Size ();
1173 //std::cout << "WriteKeys :: Acumulado = " << acumulado << std::endl;
1174 memcpy (node, n, d->Size ());
1177 node_header.free_space -= d->Size ();
1178 node_header.item_count++;
1185 void BTree::PrintNode (uint num)
1187 uchar *node = ReadBlock (num);
1188 BTreeNodeHeader node_header;
1189 ReadNodoHeader (node, &node_header);
1191 std::list<BTreeData *> node_keys = ReadKeys (node, node_header);
1192 std::list<BTreeData *>::iterator it = node_keys.begin ();
1194 std::cout << "Nodo : " << num << std::endl;
1195 std::cout << "Level : " << node_header.level << std::endl;
1196 std::cout << "Items : " << node_header.item_count << std::endl;
1197 std::cout << "Free : " << node_header.free_space << " (" << (header.block_size - sizeof (BTreeNodeHeader)) << ")" << std::endl;
1198 while (it != node_keys.end ()) {
1199 std::string s = *(*it);
1200 std::cout << s << " ";
1203 std::cout << std::endl;
1206 DeleteKeys (node_keys);
1209 uchar *BTree::NewBlock (uint &num)
1215 std::list<uint>::iterator it;
1217 if (deleted_nodes.size ()) {
1218 it = deleted_nodes.begin ();
1220 deleted_nodes.erase (it);
1222 fseek (fp, 0, SEEK_END);
1223 filelen = ftell (fp);
1225 num = filelen/header.block_size - 1;
1227 node = new uchar[header.block_size];
1228 ReadNodoHeader (node, &nh);
1230 nh.free_space = header.block_size - sizeof (BTreeNodeHeader);
1232 WriteNodoHeader (node, &nh);
1233 WriteBlock (node, num);
1238 BTreeFindResult *BTree::FindKey (const Clave &k)
1240 return FindKeyR (&k, 0);
1243 BTreeFindResult *BTree::FindKeyR (const Clave *k, uint node_num)
1245 std::list<BTreeData *> node_keys;
1246 BTreeNodeHeader node_header;
1248 /* Leo el nodo raiz para empezar a agregar */
1249 uchar *node = ReadBlock (node_num);
1250 ReadNodoHeader (node, &node_header);
1251 node_keys = ReadKeys (node, node_header);
1253 std::list<BTreeData *>::iterator it = node_keys.begin ();
1254 std::list<BTreeData *>::iterator posterior;
1255 std::list<BTreeData *>::iterator ultima;
1257 /* Se supone que la primera es un hijo :) */
1259 if (node_header.level != 0) {
1265 if (node_header.level == 0)
1266 data = new BTreeLeafData (k->Clone ());
1268 data = new BTreeData (k->Clone (), 0);
1270 while (it != node_keys.end ()) {
1271 if ((*data) == (*(*it))) {
1272 /* La encontre!, retorno */
1275 DeleteKeys (node_keys);
1276 BTreeFindResult *result = new BTreeFindResult ();
1277 result->node = node_num;
1278 result->header = node_header;
1283 if ((*data) < (*(*it)))
1291 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
1292 * decir que no lo encontré
1294 if (node_header.level == 0) {
1295 DeleteKeys (node_keys);
1300 /* TODO: Aca faltaria liberar memoria */
1301 BTreeFindResult *ret;
1302 if (it == posterior)
1303 ret = FindKeyR (k, lchild->GetChild ());
1305 ret = FindKeyR (k, (*ultima)->GetChild ());
1307 DeleteKeys (node_keys);
1312 void BTree::DeleteKeys (std::list<BTreeData *> &keys)
1314 std::list<BTreeData *>::iterator it = keys.begin ();
1316 while (it != keys.end ()) {
1317 BTreeData *d = (*it);
1323 int BTree::type () const
1325 return header.key_type;
1328 uint BTree::GetNextBlockData ()
1331 if (deleted_block_data.size ()) {
1332 std::list<uint>::iterator it = deleted_block_data.begin ();
1334 deleted_block_data.erase (it);
1336 n = header.block_data_counter++;