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;
25 /* Creo el primer bloque vacio */
26 node = new uchar[block_size];
27 ReadNodoHeader (node, &nh);
29 nh.free_space = block_size - sizeof (BTreeNodeHeader);
31 WriteNodoHeader (node, &nh);
37 BTree::BTree (const std::string &name)
39 /* Leo los bloques recuperables */
40 std::string del = filename + ".del";
42 fp = fopen (del.c_str (), "wb");
46 while (fread (&i, 1, sizeof (uint), fp)) {
47 deleted_nodes.push_back (i);
53 del = filename + ".blockdel";
55 fp = fopen (del.c_str (), "wb");
59 while (fread (&i, 1, sizeof (uint), fp)) {
60 deleted_block_data.push_back (i);
66 fp = fopen (name.c_str(), "rb+");
68 /* TODO : mandar una exception ? */
78 std::string del = filename + ".del";
80 fp = fopen (del.c_str (), "wb");
81 std::list<uint>::iterator it = deleted_nodes.begin ();
83 while (it != deleted_nodes.end ()) {
85 fwrite (&i, 1, sizeof (uint), fp);
89 del = filename + ".del";
91 fp = fopen (del.c_str (), "wb");
92 it = deleted_block_data.begin ();
94 while (it != deleted_block_data.end ()) {
96 fwrite (&i, 1, sizeof (uint), fp);
102 void BTree::ReadFileHeader ()
104 fseek (fp, 0L, SEEK_SET);
105 fread (&header, 1, sizeof (BTreeFileHeader), fp);
108 void BTree::WriteFileHeader ()
110 fseek (fp, 0L, SEEK_SET);
111 fwrite (&header, 1, sizeof (BTreeFileHeader), fp);
114 void BTree::WriteBlock (uchar *block, uint num)
117 fseek (fp, num*header.block_size, SEEK_SET);
118 fwrite (block, 1, header.block_size, fp);
121 void BTree::AddKey (const Clave &k)
127 in->SetBlockData ( GetNextBlockData () );
130 kout = AddKeyR (in->Clone (), 0, left, right);
131 } catch (Exception *e) {
138 unsigned short level;
139 /* Debo dejar la raiz en el nodo 0, por lo que paso el nodo
140 * que esta usando el hijo izquierdo a un nuevo nodo */
141 std::list<BTreeData *> node_keys;
142 BTreeNodeHeader node_header;
143 uchar *node = ReadBlock (left);
144 ReadNodoHeader (node, &node_header);
145 node_keys = ReadKeys (node, node_header);
146 level = node_header.level + 1;
148 uchar *new_node = NewBlock (left);
149 delete [] new_node; /* No me interesa, voy a usar lo leio antes */
151 WriteKeys (node, node_header, node_keys);
152 WriteNodoHeader (node, &node_header);
153 WriteBlock (node, left);
154 DeleteKeys (node_keys);
157 /* Leo y actualizo la Raiz */
158 node = ReadBlock (0);
159 ReadNodoHeader (node, &node_header);
160 node_keys = std::list<BTreeData *>();
162 node_keys.push_back (new BTreeChildData (left));
163 node_keys.push_back (new BTreeData (kout, right));
165 node_header.level = level;
166 node_header.item_count = 1;
168 WriteKeys (node, node_header, node_keys);
169 WriteNodoHeader (node, &node_header);
170 WriteBlock (node, 0);
172 DeleteKeys (node_keys);
177 Clave* BTree::AddKeyR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
179 uchar *node = ReadBlock (node_num);
180 BTreeNodeHeader node_header;
181 ReadNodoHeader (node, &node_header);
184 if (node_header.level == 0) {
186 return AddKeyLeafR (k, node_num, left_child, right_child);
187 } catch (Exception *e) {
193 return AddKeyOtherR (k, node_num, left_child, right_child);
194 } catch (Exception *e) {
199 Clave* BTree::AddKeyLeafR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
202 std::list<BTreeData *> node_keys;
204 BTreeData *data = new BTreeLeafData (k->Clone ());
206 /* Leo el nodo raiz para empezar a agregar */
207 uchar *node = ReadBlock (node_num);
208 BTreeNodeHeader node_header;
209 ReadNodoHeader (node, &node_header);
211 if (node_header.free_space > data->Size ()) {
213 node_keys = ReadKeys (node, node_header);
214 std::list<BTreeData *>::iterator it = node_keys.begin ();
216 while (it != node_keys.end ()) {
218 if (header.tree_type == TYPE_IDENTIFICACION) {
219 /* Verifico que la clave no existea ya en el arbol */
220 if ((*data) == (*datait)) {
221 throw new AddException ();
226 if ((*data) < (*datait))
227 /* Me pase, lo agrego aca! */
231 node_keys.insert (it, data);
232 WriteKeys (node, node_header, node_keys);
233 WriteNodoHeader (node, &node_header);
234 WriteBlock (node, node_num);
235 DeleteKeys (node_keys);
238 PrintNode (node_num);
240 /* Split : Creo e inicializo el nuevo nodo */
241 std::list<BTreeData *> new_node_keys;
242 std::list<BTreeData *> old_node_keys;
243 BTreeNodeHeader new_node_header;
245 uchar *new_node = NewBlock (new_node_num);
246 ReadNodoHeader (new_node, &new_node_header);
247 new_node_header.level = node_header.level;
249 node_keys = ReadKeys (node, node_header);
250 new_node_keys = ReadKeys (new_node, new_node_header);
252 /* Agrego la clave en la lista que ya tengo de manera ordenada */
253 std::list<BTreeData *>::iterator it = node_keys.begin ();
254 std::list<BTreeData *>::iterator previt = node_keys.begin ();
256 while (it != node_keys.end ()) {
259 if (header.tree_type == TYPE_IDENTIFICACION) {
260 /* Verifico que la clave no existea ya en el arbol */
261 if ((*data) == (*datait)) {
262 throw new AddException ();
266 if ((*data) < (*datait))
267 /* Me pase, lo agrego aca! */
272 if (it != node_keys.end ())
273 node_keys.insert (it, data);
275 node_keys.push_back (data);
277 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
278 * y subir la clave del medio */
279 node_header.item_count = 0;
280 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
283 it = node_keys.begin ();
284 while (it != node_keys.end ()) {
287 total_size += datait->Size ();
289 /* Hack : Si me quedo con todas las claves, en el caso de ser
290 * del mismo tama#o se desbalancea. Hay que ver que efecto
291 * puede tener en el caso de claves de long. variable
293 if (it == node_keys.end ())
294 total_size -= datait->Size ();
297 it = node_keys.begin ();
299 while (used < total_size/2) {
300 BTreeData *d = (*it);
301 old_node_keys.push_back (d);
305 kout = (*it++)->GetKey (); // Esta se retorna al "padre" para que se la agregue
307 while (it != node_keys.end ()) {
308 BTreeData *d = (*it);
309 new_node_keys.push_back (d);
314 WriteKeys (node, node_header, old_node_keys);
315 WriteNodoHeader (node, &node_header);
316 WriteBlock (node, node_num);
317 WriteKeys (new_node, new_node_header, new_node_keys);
318 WriteNodoHeader (new_node, &new_node_header);
319 WriteBlock (new_node, new_node_num);
320 DeleteKeys (old_node_keys);
321 DeleteKeys (new_node_keys);
323 PrintNode (node_num);
324 PrintNode (new_node_num);
327 left_child = node_num;
328 right_child = new_node_num;
336 Clave* BTree::AddKeyOtherR (const Clave *k, uint node_num, uint &left_child, uint &right_child)
339 std::list<BTreeData *> node_keys;
341 BTreeData *data = new BTreeLeafData (k->Clone ());
343 /* Leo el nodo raiz para empezar a agregar */
344 uchar *node = ReadBlock (node_num);
345 BTreeNodeHeader node_header;
346 ReadNodoHeader (node, &node_header);
348 node_keys = ReadKeys (node, node_header);
350 std::list<BTreeData *>::iterator it = node_keys.begin ();
351 std::list<BTreeData *>::iterator posterior;
352 std::list<BTreeData *>::iterator ultima;
354 /* Se supone que la primera es un hijo :) */
355 BTreeData *lchild = (*it++);
358 while (it != node_keys.end ()) {
359 if (header.tree_type == TYPE_IDENTIFICACION) {
360 /* Verifico que la clave no existea ya en el arbol */
361 if ((*data) == (*(*it))) {
362 throw new AddException ();
366 if ((*data) < (*(*it)))
372 if (it == posterior) {
373 k = AddKeyR (k, lchild->GetChild (), left_child, right_child);
375 k = AddKeyR (k, (*ultima)->GetChild (), left_child, right_child);
377 DeleteKeys (node_keys);
380 if (data) delete data;
386 data = new BTreeData (k->Clone (), right_child);
388 if (node_header.free_space > data->Size ()) {
390 node_keys = ReadKeys (node, node_header);
391 std::list<BTreeData *>::iterator it = node_keys.begin ();
393 while (it != node_keys.end ()) {
395 if (header.tree_type == TYPE_IDENTIFICACION) {
396 /* Verifico que la clave no existea ya en el arbol */
397 if ((*data) == (*datait)) {
398 throw new AddException ();
402 if ((*data) < (*datait))
403 /* Me pase, lo agrego aca! */
407 node_keys.insert (it, data);
408 WriteKeys (node, node_header, node_keys);
409 WriteNodoHeader (node, &node_header);
410 WriteBlock (node, node_num);
411 DeleteKeys (node_keys);
414 PrintNode (node_num);
416 /* Split : Creo e inicializo el nuevo nodo */
417 std::list<BTreeData *> new_node_keys;
418 std::list<BTreeData *> old_node_keys;
419 BTreeNodeHeader new_node_header;
421 uchar *new_node = NewBlock (new_node_num);
422 ReadNodoHeader (new_node, &new_node_header);
423 new_node_header.level = node_header.level;
425 node_keys = ReadKeys (node, node_header);
426 new_node_keys = ReadKeys (new_node, new_node_header);
428 /* Agrego la clave en la lista que ya tengo de manera ordenada */
429 std::list<BTreeData *>::iterator it = node_keys.begin ();
430 std::list<BTreeData *>::iterator previt = node_keys.begin ();
434 while (it != node_keys.end ()) {
437 if (header.tree_type == TYPE_IDENTIFICACION) {
438 /* Verifico que la clave no existea ya en el arbol */
439 if ((*data) == (*datait)) {
440 throw new AddException ();
444 if ((*data) < (*datait))
445 /* Me pase, lo agrego aca! */
450 if (it != node_keys.end ())
451 node_keys.insert (it, data);
453 node_keys.push_back (data);
455 /* Tengo que guardar claves hasta ocupar nodo size/2 en cada nodo
456 * y subir la clave del medio */
457 node_header.item_count = 0;
458 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
461 it = node_keys.begin ();
462 while (it != node_keys.end ()) {
465 total_size += datait->Size ();
467 /* Hack : Si me quedo con todas las claves, en el caso de ser
468 * del mismo tama#o se desbalancea. Hay que ver que efecto
469 * puede tener en el caso de claves de long. variable
471 if (it == node_keys.end ())
472 total_size -= datait->Size ();
475 it = node_keys.begin ();
477 while (used < total_size/2) {
478 BTreeData *d = (*it);
479 old_node_keys.push_back (d);
483 kout = (*it)->GetKey (); // Esta se retorna al "padre" para que se la agregue
485 new_node_keys.push_back ( new BTreeChildData ((*it)->GetChild ()));
487 while (it != node_keys.end ()) {
488 BTreeData *d = (*it);
489 new_node_keys.push_back (d);
494 WriteKeys (node, node_header, old_node_keys);
495 WriteNodoHeader (node, &node_header);
496 WriteBlock (node, node_num);
497 WriteKeys (new_node, new_node_header, new_node_keys);
498 WriteNodoHeader (new_node, &new_node_header);
499 WriteBlock (new_node, new_node_num);
500 DeleteKeys (old_node_keys);
501 DeleteKeys (new_node_keys);
503 PrintNode (node_num);
504 PrintNode (new_node_num);
507 left_child = node_num;
508 right_child = new_node_num;
516 void BTree::DelKey (const Clave &k)
519 std::cout << "========= Borrando " << s << " =================\n";
520 BTreeData *b = new BTreeLeafData (k.Clone ());
525 void BTree::DelKeyR (BTreeData *k, uint node_num, uint padre)
527 std::list<BTreeData *> node_keys;
528 BTreeNodeHeader node_header;
531 node = ReadBlock (node_num);
532 ReadNodoHeader (node, &node_header);
533 node_keys = ReadKeys (node, node_header);
535 std::list<BTreeData *>::iterator it = node_keys.begin ();
536 std::list<BTreeData *>::iterator ultima;
537 std::list<BTreeData *>::iterator posterior;
540 if (node_header.level != 0) {
545 while (it != node_keys.end ()) {
546 if ((*k) == (*(*it))) {
547 /* La encontre!, retorno */
548 if (node_header.level == 0) {
549 DelKeyFromLeaf (k->GetKey (), node_num, padre);
552 if (it == posterior) {
553 left = lchild->GetChild ();
554 right = (*it)->GetChild ();
556 left = (*ultima)->GetChild ();
557 right = (*it)->GetChild ();
559 std::cout << "Eliminar de Nodo con hijos : " << left << " y " << right << std::endl;
560 DelKeyFromNode (k->GetKey (), node_num, padre, left, right);
562 DeleteKeys (node_keys);
573 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
574 * decir que no lo encontre
576 if (node_header.level == 0) {
577 std::cout << "*** Clave no encontrada ***\n";
581 /* TODO: Aca faltaria liberar memoria */
582 if (it == posterior) {
583 DelKeyR (k, lchild->GetChild (), node_num);
585 DelKeyR (k, (*ultima)->GetChild (), node_num);
589 void BTree::DelKeyFromLeaf (Clave *k, uint node_num, uint padre)
593 BTreeNodeHeader node_header;
594 std::list<BTreeData *> node_keys;
596 node = ReadBlock (node_num);
597 ReadNodoHeader (node, &node_header);
598 node_keys = ReadKeys (node, node_header);
600 data = new BTreeLeafData (k->Clone ());
602 std::list<BTreeData *>::iterator it;
603 it = node_keys.begin ();
604 while (it != node_keys.end ()) {
605 if ((*data) == (*(*it))) {
606 BTreeData *aborrar = (*it);
607 node_keys.erase (it);
608 deleted_block_data.push_back (aborrar->GetKey ()->GetBlockData ());
617 WriteKeys (node, node_header, node_keys);
618 WriteNodoHeader (node, &node_header);
619 WriteBlock (node, node_num);
621 /* Veo si se cumple la condición de minimalidad */
622 uint min_free = (header.block_size-sizeof(BTreeNodeHeader))/2;
623 if ((node_header.free_space > min_free) && (node_num != 0)) {
624 /* Oops! Debo pedir prestada clave */
628 FindBrothers (node_num, padre, hi, hd);
630 if ((pedida = GetKey (hi, 1)) != NULL) {
631 std::string s = *pedida;
632 std::cout << "Clave Pedida : " << s << std::endl;
634 pedida = ReplaceKeyInFather (node_num, padre, pedida);
636 node_keys.insert (node_keys.begin (), new BTreeLeafData (pedida));
637 } else if ((pedida = GetKey (hd, 0)) != NULL) {
638 std::string s = *pedida;
639 std::cout << "Clave Pedida : " << s << std::endl;
641 pedida = ReplaceKeyInFather (node_num, padre, pedida);
643 node_keys.push_back (new BTreeLeafData (pedida));
645 std::cout << "NADIE ME PUEDE PRESTAR, FUNDIR NODOS\n";
649 std::cout << "Join con Hermano Izquierdo\n";
654 std::cout << "Join con Hermano Derecho\n";
660 JoinNodes (join1, join2, padre, tipoh);
662 DeleteKeys (node_keys);
667 WriteKeys (node, node_header, node_keys);
668 WriteNodoHeader (node, &node_header);
669 WriteBlock (node, node_num);
672 DeleteKeys (node_keys);
674 std::cout << "Borrado de una hoja listo\n";
677 void BTree::JoinNodes (uint node1, uint node2, uint padre, int tipohermano)
679 uchar *n1, *n2, *npadre;
680 BTreeNodeHeader nh1, nh2, nhp;
681 std::list<BTreeData *> nk1, nk2, nkpadre;
683 if (node1 == node2) {
684 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
687 if (node1 == padre) {
688 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
691 if (node2 == padre) {
692 std::cout << "PANIC : No puedo juntar el mismo nodo con si mismo!!\n";
701 n1 = ReadBlock (node1);
702 n2 = ReadBlock (node2);
703 npadre = ReadBlock (padre);
705 ReadNodoHeader (n1, &nh1);
706 ReadNodoHeader (n2, &nh2);
707 ReadNodoHeader (npadre, &nhp);
710 uint tmp = header.block_size - sizeof (BTreeNodeHeader);
711 uint l = tmp - nh1.free_space;
712 l += tmp - nh1.free_space;
715 std::cout << "Espacio ocupado despues de unir : " << l << " de " << tmp << std::endl;
717 nk1 = ReadKeys (n1, nh1);
718 nk2 = ReadKeys (n2, nh2);
719 nkpadre = ReadKeys (npadre, nhp);
721 /* Busco la clave del padre a juntar con los nodos */
722 std::list<BTreeData *>::iterator it = nkpadre.begin ();
723 std::list<BTreeData *>::iterator borrar_padre;
724 std::list<BTreeData *>::iterator sig;
725 std::list<BTreeData *>::iterator anterior = it;
728 BTreeData *lchild = (*it++);
730 if (lchild->GetChild () == node1) {
731 cpadre = (*it)->GetKey ();
734 while (it != nkpadre.end ()) {
735 if (tipohermano == 0) {
736 if ((*it)->GetChild () == node2)
739 if ((*it)->GetChild () == node1)
745 cpadre = (*it)->GetKey ();
748 if (it == nkpadre.end ()) {
749 std::cout << "PANIC : Me pase sin encontrar la clave!!\n";
755 std::list<BTreeData *> newkeys;
756 std::list<BTreeData *>::iterator i;
759 while (i != nk1.end ()) {
760 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
763 //if (tipohermano == 0)
764 newkeys.push_back ( new BTreeLeafData (cpadre->Clone ()));
766 while (i != nk2.end ()) {
767 newkeys.push_back ( new BTreeLeafData ((*i)->GetKey ()->Clone ()));
771 std::cout << "Espacio ocupado por las nuevas claves : " << (newkeys.size()*4) << std::endl;
772 if ((newkeys.size()*4) > tmp) {
773 std::cout << "PANIC : El nodo fundido no entra !!!\n";
777 /* Para el padre, tener 2 items significa tener solo 1 clave, ya que
778 * el otro item es el LeftChild!
780 if ((padre == 0) && (nhp.item_count == 2)) {
781 /* Si junte 2 nodos, cuyo padre era la raiz, y esta tenia
782 * solo una clave, quiere decir que lo que me queda
783 * es de nuevo solo una raiz con todas las claves
786 WriteKeys (npadre, nhp, newkeys);
787 WriteNodoHeader (npadre, &nhp);
788 WriteBlock (npadre, padre);
790 deleted_nodes.push_back (node1);
791 deleted_nodes.push_back (node2);
793 WriteKeys (n1, nh1, newkeys);
794 WriteNodoHeader (n1, &nh1);
795 WriteBlock (n1, node1);
797 deleted_nodes.push_back (node2);
799 /* Actualizo punero al padre */
800 (*anterior)->SetChild (node1);
802 nkpadre.erase (borrar_padre);
803 WriteKeys (npadre, nhp, nkpadre);
804 WriteNodoHeader (npadre, &nhp);
805 WriteBlock (npadre, padre);
808 std::cout << " ----- Luego de Fundir -----\n";
811 std::cout << " ---------------------------\n";
815 DeleteKeys (nkpadre);
816 DeleteKeys (newkeys);
823 Clave *BTree::GetKey (uint node_num, char maxmin)
826 std::cout << "Nodo no me puede prestar ... es NULL\n";
831 BTreeNodeHeader node_header;
832 std::list<BTreeData *> node_keys;
834 node = ReadBlock (node_num);
835 ReadNodoHeader (node, &node_header);
836 node_keys = ReadKeys (node, node_header);
838 std::list<BTreeData *>::iterator it = node_keys.begin ();
840 if (node_header.level != 0) it++;
843 uint free = node_header.free_space; // + (*it)->Size ();
844 uint min_free = (header.block_size - sizeof (BTreeNodeHeader))/2;
845 if (free > min_free) {
846 std::cout << "No puedo prestar : Free = " << free << " Minimo = " << min_free << std::endl;
847 PrintNode (node_num);
848 WriteKeys (node, node_header, node_keys);
849 WriteNodoHeader (node, &node_header);
850 WriteBlock (node, node_num);
851 DeleteKeys (node_keys);
859 k = (*it)->GetKey ()->Clone ();
860 node_keys.erase (it);
862 it = node_keys.end ();
864 k = (*it)->GetKey ()->Clone ();
865 node_keys.erase (it);
868 WriteKeys (node, node_header, node_keys);
869 WriteNodoHeader (node, &node_header);
870 WriteBlock (node, node_num);
871 DeleteKeys (node_keys);
878 void BTree::FindBrothers (uint node_num, uint padre, uint &left, uint &right)
881 BTreeNodeHeader node_header;
882 std::list<BTreeData *> node_keys;
884 node = ReadBlock (padre);
885 ReadNodoHeader (node, &node_header);
886 node_keys = ReadKeys (node, node_header);
888 std::list<BTreeData *>::iterator it = node_keys.begin ();
889 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
890 std::list<BTreeData *>::iterator siguiente;
892 BTreeData *lchild = (*it++);
894 if (lchild->GetChild () == node_num) {
895 /* Solo tengo hermano derecho */
896 std::cout << "Hermano Izquierdo : NO TENGO" << std::endl;
898 std::cout << "Hermano Derecho : " << (*it)->GetChild () << std::endl;
899 right = (*it)->GetChild ();
903 while (it != node_keys.end ()) {
904 if ((*it)->GetChild () == node_num)
911 std::cout << "Hermano Izquierdo : " << (*anterior)->GetChild () << std::endl;
912 left = (*anterior)->GetChild ();
913 if (siguiente != node_keys.end ()) {
914 right = (*siguiente)->GetChild ();
915 std::cout << "Hermano Derecho : " << (*siguiente)->GetChild () << std::endl;
918 std::cout << "Hermano Derecho : NO TENGO" << std::endl;
922 Clave *BTree::ReplaceKeyInFather (uint node_num, uint padre, Clave *k)
925 BTreeNodeHeader node_header;
926 std::list<BTreeData *> node_keys;
928 node = ReadBlock (padre);
929 ReadNodoHeader (node, &node_header);
930 node_keys = ReadKeys (node, node_header);
932 std::list<BTreeData *>::iterator it = node_keys.begin ();
933 std::list<BTreeData *>::iterator anterior = node_keys.begin ();
934 std::list<BTreeData *>::iterator siguiente;
936 BTreeData *lchild = (*it++);
938 if (lchild->GetChild () == node_num) {
939 Clave *ret = (*it)->GetKey ();
942 WriteKeys (node, node_header, node_keys);
943 WriteNodoHeader (node, &node_header);
944 WriteBlock (node, padre);
945 DeleteKeys (node_keys);
951 while (it != node_keys.end ()) {
952 if ((*it)->GetChild () == node_num)
958 Clave *ret = (*it)->GetKey ();
961 WriteKeys (node, node_header, node_keys);
962 WriteNodoHeader (node, &node_header);
963 WriteBlock (node, padre);
964 DeleteKeys (node_keys);
970 void BTree::DelKeyFromNode (Clave *k, uint node_num, uint padre, uint left, uint right)
974 BTreeNodeHeader node_header;
975 std::list<BTreeData *> node_keys;
977 node = ReadBlock (node_num);
978 ReadNodoHeader (node, &node_header);
979 node_keys = ReadKeys (node, node_header);
982 std::cout << "Busco para la derecha y luego todo a la izquierda\n";
984 BTreeNodeHeader node_hr;
985 std::list<BTreeData *> node_keyr;
987 /* Busco la clave inmediatamente superior en el arbol */
988 padre_hijo = node_num;
990 node_r = ReadBlock (right);
991 ReadNodoHeader (node_r, &node_hr);
992 if (node_hr.level != 0) {
994 node_keyr = ReadKeys (node_r, node_hr);
995 data_r = *(node_keyr.begin ());
997 right = data_r->GetChild ();
999 DeleteKeys (node_keyr);
1002 } while (node_hr.level != 0);
1004 std::cout << "Voy a reemplazar en el nodo " << right << std::endl;
1006 /* Reemplazo la clave a borrar por la de la hoja */
1007 node_keyr = ReadKeys (node_r, node_hr);
1008 BTreeData *reemplazar = *(node_keyr.begin ());
1010 std::string ss = *reemplazar;
1011 std::cout << "Voy a reemplazar por : " << ss << std::endl;
1013 BTreeData *data = new BTreeLeafData (k->Clone());
1015 std::list<BTreeData *>::iterator it = node_keys.begin ();
1016 while (it != node_keys.end ()) {
1017 std::string ss1, ss2;
1020 std::cout << ss1 << " == " << ss2 << std::endl;
1021 if ((*data) == (*(*it))) {
1026 if (it == node_keys.end ()) {
1027 std::cout << "PANIC : No encontre la clave en el nodo!!!!\n";
1028 std::string s = *data;
1029 std::cout << s << std::endl;
1030 PrintNode (node_num);
1033 (*it)->SetKey (reemplazar->GetKey ());
1034 reemplazar->SetKey (k->Clone ());
1036 std::cout << "Tengo todo reemplazado ...\n";
1038 /* Grabo los nodos */
1039 WriteKeys (node, node_header, node_keys);
1040 WriteNodoHeader (node, &node_header);
1041 WriteBlock (node, node_num);
1042 DeleteKeys (node_keys);
1045 WriteKeys (node_r, node_hr, node_keyr);
1046 WriteNodoHeader (node_r, &node_hr);
1047 WriteBlock (node_r, right);
1048 DeleteKeys (node_keyr);
1051 std::cout << "Grabe todo en disco ...\n";
1052 PrintNode (node_num);
1054 /* Ahora debo eliminar la clave que puse en el nodo hoja */
1055 std::cout << "Borro la clave desde la hoja!\n";
1057 DelKeyFromLeaf (k, right, padre_hijo);
1059 std::cout << "Listo, Listo!\n";
1060 } else if (left != 0) {
1061 std::cout << "PANIC : Deberia poder reemplazar en la derecha!!!!!\n";
1064 std::cout << "PANIC : No tengo hijos para reemplazar!!!!\n";
1069 void BTree::ReadNodoHeader (uchar *node, BTreeNodeHeader *header)
1071 memcpy (header, node, sizeof (BTreeNodeHeader));
1074 void BTree::WriteNodoHeader (uchar *node, BTreeNodeHeader *header)
1076 memcpy (node, header, sizeof (BTreeNodeHeader));
1079 uchar *BTree::ReadBlock (uint num)
1081 /* Como el bloque 0 se usa para el header, el Nodo "num"
1082 * está en el bloque "num+1"
1086 uchar *out = new uchar[header.block_size];
1088 fseek (fp, num*header.block_size, SEEK_SET);
1089 fread (out, 1, header.block_size, fp);
1094 std::list<BTreeData *> BTree::ReadKeys (uchar *node, BTreeNodeHeader &node_header)
1096 std::list<BTreeData *> keys;
1097 node += sizeof (BTreeNodeHeader);
1098 uint count = node_header.item_count;
1100 if (node_header.item_count == 0) return keys;
1102 if (node_header.level != 0) {
1103 /* Si no es una hoja, lo primero que tengo es un BTreeChildData */
1104 BTreeChildData *d = new BTreeChildData (node);
1110 for (uint i=0; i<count; i++) {
1112 if (node_header.level == 0) {
1113 data = new BTreeLeafData (node, header.key_type);
1115 data = new BTreeData (node, header.key_type);
1117 node += data->Size ();
1118 keys.push_back (data);
1125 void BTree::AbrevKey (std::list<BTreeData *> &lst)
1127 /* Claves Fijas No se abrevian */
1128 if (header.key_type == KEY_FIXED) return;
1130 BTreeData *primera = NULL;
1131 std::list<BTreeData *>::iterator it = lst.begin ();
1133 while (it != lst.end ()) {
1134 if ((*it)->Abrev (primera) == false)
1140 void BTree::DeAbrevKey (std::list<BTreeData *> &lst)
1142 /* Claves Fijas No se abrevian */
1143 if (header.key_type == KEY_FIXED) return;
1145 BTreeData *primera = NULL;
1146 std::list<BTreeData *>::iterator it = lst.begin ();
1148 while (it != lst.end ()) {
1149 if ((*it)->DesAbrev (primera) == false)
1155 void BTree::WriteKeys (uchar *node, BTreeNodeHeader &node_header, std::list<BTreeData *> &keys)
1159 std::list<BTreeData *>::iterator it = keys.begin ();
1161 node += sizeof (BTreeNodeHeader);
1163 node_header.item_count = 0;
1164 node_header.free_space = header.block_size - sizeof (BTreeNodeHeader);
1167 while (it != keys.end ()) {
1168 BTreeData *d = (*it);
1169 uchar *n = d->ToArray ();
1170 acumulado += d->Size ();
1171 //std::cout << "WriteKeys :: Acumulado = " << acumulado << std::endl;
1172 memcpy (node, n, d->Size ());
1175 node_header.free_space -= d->Size ();
1176 node_header.item_count++;
1183 void BTree::PrintNode (uint num)
1185 uchar *node = ReadBlock (num);
1186 BTreeNodeHeader node_header;
1187 ReadNodoHeader (node, &node_header);
1189 std::list<BTreeData *> node_keys = ReadKeys (node, node_header);
1190 std::list<BTreeData *>::iterator it = node_keys.begin ();
1192 std::cout << "Nodo : " << num << std::endl;
1193 std::cout << "Level : " << node_header.level << std::endl;
1194 std::cout << "Items : " << node_header.item_count << std::endl;
1195 std::cout << "Free : " << node_header.free_space << " (" << (header.block_size - sizeof (BTreeNodeHeader)) << ")" << std::endl;
1196 while (it != node_keys.end ()) {
1197 std::string s = *(*it);
1198 std::cout << s << " ";
1201 std::cout << std::endl;
1204 DeleteKeys (node_keys);
1207 uchar *BTree::NewBlock (uint &num)
1213 std::list<uint>::iterator it;
1215 if (deleted_nodes.size ()) {
1216 it = deleted_nodes.begin ();
1218 deleted_nodes.erase (it);
1220 fseek (fp, 0, SEEK_END);
1221 filelen = ftell (fp);
1223 num = filelen/header.block_size - 1;
1225 node = new uchar[header.block_size];
1226 ReadNodoHeader (node, &nh);
1228 nh.free_space = header.block_size - sizeof (BTreeNodeHeader);
1230 WriteNodoHeader (node, &nh);
1231 WriteBlock (node, num);
1236 BTreeFindResult *BTree::FindKey (const Clave &k)
1238 return FindKeyR (&k, 0);
1241 BTreeFindResult *BTree::FindKeyR (const Clave *k, uint node_num)
1243 std::list<BTreeData *> node_keys;
1244 BTreeNodeHeader node_header;
1246 /* Leo el nodo raiz para empezar a agregar */
1247 uchar *node = ReadBlock (node_num);
1248 ReadNodoHeader (node, &node_header);
1249 node_keys = ReadKeys (node, node_header);
1251 std::list<BTreeData *>::iterator it = node_keys.begin ();
1252 std::list<BTreeData *>::iterator posterior;
1253 std::list<BTreeData *>::iterator ultima;
1255 /* Se supone que la primera es un hijo :) */
1257 if (node_header.level != 0) {
1263 if (node_header.level == 0)
1264 data = new BTreeLeafData (k->Clone ());
1266 data = new BTreeData (k->Clone (), 0);
1268 while (it != node_keys.end ()) {
1269 if ((*data) == (*(*it))) {
1270 /* La encontre!, retorno */
1273 DeleteKeys (node_keys);
1274 BTreeFindResult *result = new BTreeFindResult ();
1275 result->node = node_num;
1276 result->header = node_header;
1281 if ((*data) < (*(*it)))
1289 /* Si llego aca y estoy en nivel 0 (una hoja) quiere
1290 * decir que no lo encontré
1292 if (node_header.level == 0) {
1293 DeleteKeys (node_keys);
1298 /* TODO: Aca faltaria liberar memoria */
1299 BTreeFindResult *ret;
1300 if (it == posterior)
1301 ret = FindKeyR (k, lchild->GetChild ());
1303 ret = FindKeyR (k, (*ultima)->GetChild ());
1305 DeleteKeys (node_keys);
1310 void BTree::DeleteKeys (std::list<BTreeData *> &keys)
1312 std::list<BTreeData *>::iterator it = keys.begin ();
1314 while (it != keys.end ()) {
1315 BTreeData *d = (*it);
1321 int BTree::type () const
1323 return header.key_type;
1326 uint BTree::GetNextBlockData ()
1329 if (deleted_block_data.size ()) {
1330 std::list<uint>::iterator it = deleted_block_data.begin ();
1332 deleted_block_data.erase (it);
1334 n = header.block_data_counter++;