-TARGETS=btree libbtree.a
+TARGETS=btree btree_variable libbtree.a
CXXFLAGS=-Wall -g
-BTREE_COMMON=btree.o clave_fija.o btree_data.o
+BTREE_COMMON=btree.o clave_fija.o btree_data.o clave_variable.o
all: $(TARGETS)
btree: main.o $(BTREE_COMMON)
g++ -o btree main.o $(BTREE_COMMON)
+btree_variable: main_variable.o $(BTREE_COMMON)
+ g++ -o btree_variable main_variable.o $(BTREE_COMMON)
+
libbtree.a: $(BTREE_COMMON)
$(AR) cru libbtree.a $(BTREE_COMMON)
#include "btree.h"
-BTree::BTree (const std::string &name, unsigned int block_size, bool create_new_file)
+BTree::BTree (const std::string &name, unsigned int block_size, int kt, bool create_new_file)
{
+ key_type = kt;
uchar *node;
BTreeNodeHeader nh;
/* TODO : Detectar si estoy en una hoja */
BTreeData *data;
if (node_header.level == 0) {
- data = new BTreeLeafData (node);
+ data = new BTreeLeafData (node, key_type);
} else {
- data = new BTreeData (node);
+ data = new BTreeData (node, key_type);
}
node += data->Size ();
keys.push_back (data);
#include "common.h"
#include "clave.h"
#include "clave_fija.h"
+#include "clave_variable.h"
#include "btree_data.h"
/* alias para codear menos :) */
*/
class BTree {
public:
- BTree (const std::string &filename, unsigned int block_size, bool create_new_file = false);
+ BTree (const std::string &filename, unsigned int block_size, int k_t = KEY_FIXED, bool create_new_file = false);
~BTree ();
+ /** Tipos de clave a usar */
+ enum {
+ KEY_FIXED,
+ KEY_VARIABLE
+ };
+
void AddKey (const Clave &k);
void DelKey (const Clave &k);
protected:
Clave* AddKeyR (const Clave *k, uint node_num, uint &left_child, uint &right_child);
+ Clave* AddKeyOtherR (const Clave *k, uint node_num, uint &left_child, uint &right_child);
+ Clave* AddKeyLeafR (const Clave *k, uint node_num, uint &left_child, uint &right_child);
void WriteFileHeader ();
std::string filename;
BTreeFileHeader header;
+ int key_type;
/** Apunta al archivo de datos, asi se abre solo 1 vez
*
#include "btree_data.h"
+#include "btree.h"
-BTreeData::BTreeData (uchar *node)
+BTreeData::BTreeData (uchar *node, int tree_type)
{
/* TODO : Aca deberia detectar el tipo de clave (necesito
* info desde el arbol
*/
- clave = new ClaveFija (node);
+ if (tree_type == BTree::KEY_FIXED)
+ clave = new ClaveFija (node);
+ else
+ clave = new ClaveVariable (node);
node += clave->Size ();
memcpy (&hijo, node, sizeof (uint));
return (*clave) == (*(data.clave));
}
+BTreeLeafData::BTreeLeafData (uchar *node, int key_type)
+{
+ if (key_type == BTree::KEY_FIXED)
+ clave = new ClaveFija (node);
+ else
+ clave = new ClaveVariable (node);
+}
+
BTreeLeafData::~BTreeLeafData ()
{
}
#include <stdlib.h>
#include "clave.h"
#include "clave_fija.h"
+#include "clave_variable.h"
/** Dato a guardar en los nodos */
class BTreeData {
public:
BTreeData () {}
- BTreeData (uchar *node);
+ BTreeData (uchar *node, int tree_type);
BTreeData (Clave *k, uint child);
virtual ~BTreeData ();
class BTreeLeafData:public BTreeData {
public:
BTreeLeafData (Clave *k) { clave = k; }
- BTreeLeafData (uchar *node) { clave = new ClaveFija (node); }
+ BTreeLeafData (uchar *node, int key_type);
virtual ~BTreeLeafData ();
virtual uint Size () const;
#include "common.h"
#include <string>
+/** Clave abstracta para manejo de Claves */
class Clave {
public:
virtual ~Clave () {}
+ /** Retorna el tamaño en bytes que ocupa la clave */
virtual uint Size () const = 0;
+ /** Retorna un array de bytes de Size() de longitud.
+ *
+ * El contenido del array es la clave en formato RAW
+ * para guardar en disco.
+ */
virtual uchar *ToArray () const = 0;
+ /** Retorna un clon de la clave actual */
virtual Clave *Clone () const = 0;
virtual bool operator < (const Clave &k) const = 0;
--- /dev/null
+
+#include <string>
+#include "clave_variable.h"
+#include <iostream>
+
+ClaveVariable::ClaveVariable (const std::string &s)
+{
+ data = s;
+}
+
+ClaveVariable::ClaveVariable (uchar *n)
+{
+ uint len;
+
+ memcpy (&len, n, sizeof (uint));
+ uchar *str = new uchar[len+1];
+ n += sizeof (uint);
+ memcpy (str, n, sizeof (uchar)*len);
+ str[len] = '\0';
+ data = std::string ((const char *)(str));
+ std::cout << "CREE : " << data << std::endl;
+ delete [] str;
+}
+
+uint ClaveVariable::Size () const
+{
+ return data.size ()+sizeof (uint);
+}
+
+uchar *ClaveVariable::ToArray () const
+{
+ uchar *out;
+ uint len = data.size ();
+ out = new uchar[Size ()];
+ memcpy (out, &len, sizeof (uint));
+ memcpy (out+sizeof(uint), data.c_str (), data.size ());
+ return out;
+}
+
+Clave *ClaveVariable::Clone () const
+{
+ ClaveVariable *k = new ClaveVariable (*this);
+ return k;
+}
+
+bool ClaveVariable::operator < (const Clave &c) const
+{
+ return data < ((ClaveVariable&)c).data;
+}
+
+bool ClaveVariable::operator == (const Clave &c) const
+{
+ return data == ((ClaveVariable&)c).data;
+}
+
--- /dev/null
+
+#ifndef _CLAVE_VARIABLE_H_
+#define _CLAVE_VARIABLE_H_
+
+#include "clave.h"
+#include <string>
+#include <sstream>
+
+/** Representa una clave de longitud variable.
+ *
+ * \TODO Usar abreviaciones
+ */
+class ClaveVariable : public Clave {
+ public :
+ ClaveVariable (uchar *n);
+ ClaveVariable (const std::string &s);
+ virtual ~ClaveVariable () {}
+
+ uint Size () const;
+ uchar *ToArray () const;
+ Clave *Clone () const;
+
+ virtual bool operator < (const Clave &c) const;
+ virtual bool operator == (const Clave &c) const;
+ virtual operator std::string () const {
+ std::string out;
+ std::stringstream ss;
+ ss << data;
+ ss >> out;
+ return out;
+ }
+ private:
+ std::string data;
+};
+
+#endif
+
--- /dev/null
+
+
+#include "btree.h"
+#include "clave_variable.h"
+
+int main (int argc, char *argv[])
+{
+ BTree tree ("test.idx", 128, BTree::KEY_VARIABLE);
+
+ if (argc != 2) {
+ printf ("Falta parametro cantidad de elementos a agregar\n");
+ return 1;
+ }
+
+ for (int i=0; i<=atoi(argv[1]); i++) {
+ std::stringstream ss;
+ std::string s;
+ ss << i;
+ ss >> s;
+ ClaveVariable c(s);
+
+ std::cout << "Agregando " << i << std::endl;
+ tree.AddKey (c);
+ }
+
+ for (int i=0; i<=atoi(argv[1]); i++) {
+ std::stringstream ss;
+ std::string s;
+ ss << i;
+ ss >> s;
+ ClaveVariable c(s);
+
+ if (tree.FindKey (c))
+ std::cout << i << " encontrada\n";
+ else
+ std::cout << i << " NO encontrada\n";
+ }
+
+ return 0;
+}
+