Commit c0ab20b7 authored by David Auer's avatar David Auer
Browse files

Adapt random slicing for GekkoFS

Add serialization and deserialization
Remove unneeded code and dependencies
Fix compilation warnings
Add sanity checks
Use unordered_map from std instead of std::tr1
Allow non-consecutive disk IDs
parent ff48d7e6
Loading
Loading
Loading
Loading
+1 −35
Original line number Diff line number Diff line
@@ -11,12 +11,9 @@

#define __STDC_LIMIT_MACROS // required for limit macros
#include <stdint.h>
#include <xercesc/dom/DOMElement.hpp>
#include <list>
#include <string>

#include "helper.h"

namespace VDRIVE {

/**
@@ -34,7 +31,7 @@ public:
     *
     * @param data An XML-Element containing the description of a disk.
     */
    Disk(xercesc::DOMElement* data);
    // Disk(xercesc::DOMElement* data);

    /**
     * instantiates a new Disk with the given values.
@@ -118,15 +115,6 @@ public:
    void
    setData(void* data);

    /**
     * build an XML-Version of this object
     *
     * @param doc the document needed to create new XML Elements
     * @return a new Element containing the description of this object.
     */
    virtual xercesc::DOMElement*
    toXML(xercesc::DOMDocument* doc);

    /**
     * Get the Root-Type of XML-Elements representing this class.
     *
@@ -157,28 +145,6 @@ public:
    static std::list<Disk*>*
    loadDiskList(std::string filename);

#ifndef no_sqlite
    /**
     * Using this method it is possible to store a list of disks in a sqlite db
     * file.
     *
     * @param disks The disks to be stored
     * @param filename The name of the file the disks shall be stored in.
     */
    static void
    storeDiskListDBFile(std::list<Disk*>* disks, std::string filename);

    /**
     * Using this method it is possible to read a list of disks out of a sqlite
     * db file.
     *
     * @param filename The name of the file containing the disks.
     *
     * @return A list with the disks readen out of the file.
     */
    static std::list<Disk*>*
    loadDiskListDBFile(std::string filename);
#endif
private:
    /**
     * ID of the disk. Has to be unique all over this library.
+41 −29
Original line number Diff line number Diff line
@@ -10,16 +10,17 @@
#define _DISTRANDSLICE_H


#include <tr1/unordered_map> //FIXME?
#include <unordered_map>
#include <vector>
#define __STDC_LIMIT_MACROS // required for UINT64_MAX macro
#include <stdint.h>
#include "Distributor.h"
#include "flat_segment_tree.hpp"
#include <global/random_slicing/Disk.hpp>
#include <flat_segment_tree/flat_segment_tree.hpp>


#define DEBUG
#ifdef DEBUG
#define DUMP_COPIES
// #   define DUMP_COPIES
// #   define DUMP_DISKS
// #   define DUMP_PARTITIONS
// #   define DUMP_FREE_SPACE_COLLECTION
@@ -39,7 +40,7 @@ namespace VDRIVE {
 *
 *
 */
class DistRandSlice : public Distributor {
class DistRandSlice {
public:
    // constants declaring the min and max values for the
    // virtual allocation space.
@@ -53,12 +54,12 @@ public:
     *
     * @param data An XML-Element containing the description of a DistRandSlice.
     */
    DistRandSlice(xercesc::DOMElement* data);
    // DistRandSlice(xercesc::DOMElement* data);

    /**
     * generate a new, uninitialized Rand Slice Implementation.
     */
    DistRandSlice(int argc, char** argv);
    DistRandSlice(bool use_even_odd_collection, bool use_sorted_assimilation);

    /**
     * copy constructor
@@ -91,12 +92,6 @@ public:
    virtual void
    setDisks(std::list<Disk*>* disks);

    /**
     * @see Distributor::toXML
     */
    virtual xercesc::DOMElement*
    toXML(xercesc::DOMDocument* doc) const;

    /**
     * @see Distributor::getDisks
     */
@@ -143,6 +138,18 @@ public:
        return std::string("RandSlice");
    }

    /**
     * Deserialize from file.
     */
    void
    from_file(std::string filename);

    /**
     * Serialize to file.
     */
    void
    to_file(std::string filename);

private:
    void
    cleanup(void);
@@ -155,17 +162,16 @@ private:

    void
    redistribute(
            std::tr1::unordered_map<uint64_t, uint64_t>& old_partitions,
            std::unordered_map<uint64_t, uint64_t>& old_partitions,
            const std::list<std::pair<uint64_t, uint64_t>>& new_partitions);

    void
    collect_free_space(
            std::tr1::unordered_map<uint64_t, uint64_t>& old_partitions,
    collect_free_space(std::unordered_map<uint64_t, uint64_t>& old_partitions,
                       std::list<std::pair<uint64_t, uint64_t>>& free_space);

    void
    collect_free_space_even_odd(
            std::tr1::unordered_map<uint64_t, uint64_t>& old_partitions,
            std::unordered_map<uint64_t, uint64_t>& old_partitions,
            std::list<std::pair<uint64_t, uint64_t>>& free_space);

    void
@@ -186,7 +192,7 @@ private:
    dump_free_space(const std::list<std::pair<uint64_t, uint64_t>>& l) const;
    void
    verify_partitions(void);
    std::vector<uint64_t>
    std::unordered_map<uint64_t, uint64_t>
    compute_interval_sizes(void);
#endif

@@ -203,7 +209,7 @@ private:
    /**
     * the disks as given to setDisks (or setConfiguration)
     */
    std::tr1::unordered_map<uint64_t, Disk*>* m_disks;
    std::unordered_map<uint64_t, Disk*>* m_disks;

    /**
     * number of Disks contained by this Distributor.
@@ -213,7 +219,7 @@ private:
    /**
     * partition info: id -> capacity
     */
    std::tr1::unordered_map<uint64_t, uint64_t>* m_partitions;
    std::unordered_map<uint64_t, uint64_t>* m_partitions;

    /**
     * number of partitions
@@ -241,6 +247,12 @@ private:
     * sort free intervals decreasingly when assimilating free space
     */
    bool m_use_sorted_assimilation;


    /**
     * Init value for tree creation, needed for deserialization only.
     */
    uint64_t m_tree_init_value;
};
} // namespace VDRIVE
#endif /* _DISTRANDSLICE_H */
+1 −289
Original line number Diff line number Diff line
@@ -6,22 +6,14 @@
 * Created on 20. Januar 2010, 10:39
 */

#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <string>
#include <sstream>
#include <iostream>
#include <sqlite3.h>
#include <cstdio>

#include "Disk.h"
#include "helper.h"
#include <global/random_slicing/Disk.hpp>

using namespace VDRIVE;
using namespace xercesc;
using namespace std;

Disk::Disk(int64_t id, int64_t capacity, void* data) {
@@ -36,32 +28,6 @@ Disk::Disk(const Disk& orig) {
    this->data = orig.data;
}

Disk::Disk(xercesc::DOMElement* data) {
    std::istringstream isst;
    XMLCh* xmlString;
    char* sysString;

    xmlString = XMLString::transcode("id");
    sysString = XMLString::transcode(data->getAttribute(xmlString));
    isst.str(sysString);
    isst >> this->id;
    isst.str("");
    isst.clear();
    XMLString::release(&sysString);
    XMLString::release(&xmlString);

    xmlString = XMLString::transcode("capacity");
    sysString = XMLString::transcode(data->getAttribute(xmlString));
    isst.str(sysString);
    isst >> this->capacity;
    isst.str("");
    isst.clear();
    XMLString::release(&sysString);
    XMLString::release(&xmlString);

    // TODO private_data
}

Disk::~Disk() {}

void*
@@ -93,257 +59,3 @@ void
Disk::setCapacity(int64_t capacity) {
    this->capacity = capacity;
}

xercesc::DOMElement*
Disk::toXML(xercesc::DOMDocument* doc) {
    xercesc::DOMElement* result;
    std::stringstream out;
    XMLCh *xmlString, *xmlString2;

    xmlString = XMLString::transcode(Disk::getXMLRootType().c_str());
    result = doc->createElement(xmlString);
    XMLString::release(&xmlString);

    out << this->id;
    xmlString = XMLString::transcode(out.str().c_str());
    xmlString2 = XMLString::transcode("id");
    result->setAttribute(xmlString2, xmlString);
    XMLString::release(&xmlString);
    XMLString::release(&xmlString2);
    out.str("");
    out.clear();

    out << this->capacity;
    xmlString = XMLString::transcode(out.str().c_str());
    xmlString2 = XMLString::transcode("capacity");
    result->setAttribute(xmlString2, xmlString);
    XMLString::release(&xmlString);
    XMLString::release(&xmlString2);
    out.str("");
    out.clear();

    // TODO: Do anything with privateData

    return result;
}

#ifndef no_sqlite

void
Disk::storeDiskListDBFile(std::list<Disk*>* disks, std::string filename) {
    sqlite3* db;
    std::stringstream out;

    db = createDB(filename);

    execQuery(db, string("insert into meta values('filetype', 'disklist')"));
    execQuery(db, string("insert into meta values('table', 'disklist')"));

    execQuery(db, string("create table disklist_meta (key text, value text)"));
    execQuery(db, string("insert into meta values('tabletype', 'disklist')"));
    out << "insert into disklist_meta values ('count', " << disks->size()
        << ")";
    execQuery(db, string(out.str()));
    out.str("");

    execQuery(db,
              string("create table disklist (id integer, capacity integer)"));
    for(std::list<Disk*>::iterator it = disks->begin(); it != disks->end();
        it++) {
        out << "insert into disklist values (" << (*it)->getId() << ", "
            << (*it)->getCapacity() << ")";
        execQuery(db, string(out.str()));
        out.str("");
    }

    sqlite3_close(db);
}

std::list<Disk*>*
Disk::loadDiskListDBFile(std::string filename) {
    sqlite3* db;
    sqlite3_stmt* query;
    int error;
    std::list<Disk*>* result = new std::list<Disk*>();

    db = loadDB(filename);

    error = sqlite3_prepare(db, "select id,capacity from disklist", -1, &query,
                            0);
    if(error) {
        fprintf(stderr, "Could not read disklist: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        sqlite3_finalize(query);
        throw "Could not read disklist";
    }

    error = sqlite3_step(query);
    while(error == SQLITE_ROW) {
        Disk* d = new Disk(sqlite3_column_int64(query, 0),
                           sqlite3_column_int64(query, 1), 0);
        result->push_back(d);
        error = sqlite3_step(query);
    }

    if(error != SQLITE_DONE) {
        fprintf(stderr, "Error executing query: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        sqlite3_finalize(query);
        throw "Error executing query";
    }

    sqlite3_finalize(query);

    return result;
}
#endif

void
Disk::storeDiskList(std::list<Disk*>* disks, std::string filename) {
    XMLCh* xmlString;
    try {
        XMLPlatformUtils::Initialize();
    } catch(const XMLException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                                  << "  Exception message:" << sysString
                                  << XERCES_STD_QUALIFIER endl;
        XMLString::release(&sysString);
        abort();
    }

    try {
        xmlString = XMLString::transcode("Core");
        DOMImplementation* impl =
                DOMImplementationRegistry::getDOMImplementation(xmlString);
        XMLString::release(&xmlString);
        xmlString = XMLString::transcode("disklist");
        DOMDocument* doc = impl->createDocument(0, xmlString, 0);
        XMLString::release(&xmlString);
        DOMElement* rootElem = doc->getDocumentElement();
        for(std::list<Disk*>::iterator it = disks->begin(); it != disks->end();
            it++) {
            Disk* disk = *it;
            DOMElement* xml = disk->toXML(doc);
            rootElem->appendChild(xml);
        }
        DOMLSSerializer* theSerializer =
                ((DOMImplementationLS*) impl)->createLSSerializer();
        DOMLSOutput* theOutput =
                ((DOMImplementationLS*) impl)->createLSOutput();
        xmlString = XMLString::transcode(filename.c_str());
        LocalFileFormatTarget* myFormTarget =
                new LocalFileFormatTarget(xmlString);
        XMLString::release(&xmlString);
        theOutput->setByteStream(myFormTarget);
        theSerializer->write(doc, theOutput);
        delete theSerializer;
        delete theOutput;
        delete myFormTarget;
        delete doc;
        // delete xml;
    } catch(const XMLException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                                  << "  Exception message:" << sysString
                                  << XERCES_STD_QUALIFIER endl;
        XMLString::release(&sysString);
        XMLPlatformUtils::Terminate();
        abort();
    } catch(const DOMException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr
                << "DOMError during Xerces-c Initialization.\n"
                << "  Exception message:" << sysString
                << XERCES_STD_QUALIFIER endl;
        XMLString::release(&sysString);
        XMLPlatformUtils::Terminate();
        abort();
    }

    try {
        XMLPlatformUtils::Terminate();
    } catch(const XMLException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                                  << "  Exception message:" << sysString
                                  << XERCES_STD_QUALIFIER endl;
        XMLString::release(&sysString);
        XMLPlatformUtils::Terminate();
        abort();
    }
}

std::list<Disk*>*
Disk::loadDiskList(std::string filename) {
    xercesc::DOMNode* n;
    XMLCh* xmlString;
    std::list<Disk*>* disks = 0;
    char* sysString;

    try {
        XMLPlatformUtils::Initialize();
    } catch(const XMLException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                                  << "  Exception message:" << sysString
                                  << XERCES_STD_QUALIFIER endl;
        XMLString::release(&sysString);
        return 0;
    }

    try {
        disks = new std::list<Disk*>();
        xmlString = XMLString::transcode("Core");
        DOMImplementation* impl =
                DOMImplementationRegistry::getDOMImplementation(xmlString);
        XMLString::release(&xmlString);
        DOMLSParser* parser =
                ((DOMImplementationLS*) impl)
                        ->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS,
                                         0);
        DOMDocument* doc = 0;
        DOMElement *rootElem, *diskElem;
        parser->resetDocumentPool();
        xmlString = XMLString::transcode(filename.c_str());
        doc = parser->parseURI(xmlString);
        XMLString::release(&xmlString);
        rootElem = doc->getDocumentElement();
        n = rootElem->getFirstChild();
        while(n != 0) {
            if(n->getNodeType() == DOMNode::ELEMENT_NODE) {
                diskElem = (xercesc::DOMElement*) n;
                sysString = XMLString::transcode(diskElem->getTagName());
                if(strcmp(Disk::getXMLRootType().c_str(), sysString) == 0) {
                    Disk* disk = new Disk(diskElem);
                    disks->push_back(disk);
                }
                XMLString::release(&sysString);
            }
            n = n->getNextSibling();
        }
        delete parser;
    } catch(const XMLException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                                  << "  Exception message:" << sysString
                                  << XERCES_STD_QUALIFIER endl;
        if(disks != 0) {
            delete disks;
        }
        XMLString::release(&sysString);
        XMLPlatformUtils::Terminate();
        return 0;
    }

    try {
        XMLPlatformUtils::Terminate();
    } catch(const XMLException& toCatch) {
        char* sysString = XMLString::transcode(toCatch.getMessage());
        XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n"
                                  << "  Exception message:" << sysString
                                  << XERCES_STD_QUALIFIER endl;
        XMLString::release(&sysString);
    }
    return disks;
}
+146 −64

File changed.

Preview size limit exceeded, changes collapsed.