【问题标题】:STXXL Dealing with stringsSTXXL 处理字符串
【发布时间】:2015-05-11 08:42:46
【问题描述】:

我正在处理大型数据集。请问您如何将字符串存储在我想与 stxxl 一起使用的类中?我已经阅读了几个讨论,到处都说字符串不是 POD 类型,因此它不能存储在 stxxl::vector 中,但我不确定,因为我试过了,我检查了数据,一切似乎都很好。我还在这里看到了一种方法https://github.com/Project-OSRM/osrm-backend/blob/725b93a961625a7b04d54806d7e0f80252a6bcd0/extractor/extraction_containers.hpp,他们使用 stxxl::vector,所以也许库已经更新以支持 std::string?

class HighWay
{
private:
    uint64_t id; 
    string name;
    int speed;
    string attributes; //additional attributes of way
    string edges; //written uint64_t from,uint64_t to, int distance  written as string
    string nodes; //vector<uint64_t> written as string
public:
    HighWay() = default;
    void setId(uint64_t _id) {
        id = boost::lexical_cast<string>(_id);
    }
void setName(string _name) {
    name = _name;
}
void setSpeed(int _speed) {
    speed = _speed;
}
void setAttributes(string _attributes) {
    attributes = _attributes;
}
void setEdges(string _edges) {
    edges = _edges;
}

void setNodes(vector<uint64_t>refs) {
    stringstream s;
    uint64_t i = 0;
    for (; i < refs.size()-1;i++) {
        s << boost::lexical_cast<uint64_t>(refs[i]) << " ";
    }
    s << boost::lexical_cast<uint64_t>(refs[i]);

    nodes = s.str();
}

uint64_t getId() {
    return id;
}
string getName() {
    return name;
}
int getSpeed() {
    return speed;
}
string getAttributes() {
    return attributes;
}
string getEdges() {
    return edges;
}

std::vector<int64_t> getNodes() {
    stringstream s(nodes);
    uint64_t node;
    std::vector<int64_t> result;
    while (s >> node) {
        result.push_back(static_cast<int64_t>(node));
    }

    return result;
}
};

我还创建了将字符串存储为 POD 的代码,将字符串存储在 char 的向量中,并在映射中存储数组中的下限和上限索引。但是这种方法导致应用程序中使用了许多 std::maps。

//class to store in map
struct TypeName{
    uint64_t start;
    uint64_t end;
};

std::istream& operator >> (std::istream& i, TypeName& entry)
{
    i >> entry.start;
    i >> entry.end;
    return i;
}
std::ostream& operator << (std::ostream& i, const TypeName& entry)
{
    i << entry.start << " ";
    i << entry.end;
    return i;
}

struct PoiCategories{
   uint64_t start;
   uint64_t end;
};

std::istream& operator >> (std::istream& i,PoiCategories& entry)
{
    i >> entry.start;
    i >> entry.end;
    return i;
}

std::ostream& operator << (std::ostream& i, const PoiCategories& entry)
{
    i << entry.start << " ";
    i << entry.end;
    return i;
}

 //object i want to store
struct Poi {
    Poi() = default;
    uint64_t id;
    char type;
    uint64_t id_in_pois; //id in vector pois

void addCategories(
    vector<int> &kats, //categories to insert
    stxxl::vector<uint64_t> &categories, //vector to store category
    std::unordered_map <uint64_t, PoiCategories> &idPoi_categories //index to vector categories to retrieve all categories for Poi
    )
{
    size_t  start = categories.size();
    for (auto & kat : kats) {
        categories.push_back(kat);
    }
    size_t end = categories.size() - 1;
    idPoi_categories.insert(make_pair(id, PoiCategories{start, end }));


}

vector<int> getCategories(
    stxxl::vector<uint64_t> &categories,
    std::unordered_map <uint64_t, PoiKategorie> &idPoi_categories
    )
{
    std::vector<int> result;
    PoiCategories bounds = idPoi_categories.find(id)->second;
    for (size_t i = bounds.start; i <= bounds.end; i++) {
        result.push_back(categories[i]);
    }

    return result;
}

};

我的应用程序中的问题是我存储了一些字符串数据,主要是街道和 POI 的名称。也许我使用了错误的库。如果是这样,您能否推荐一种在预处理时存储数据的更好方法?

【问题讨论】:

    标签: c++ string c++11 bigdata stxxl


    【解决方案1】:

    确实是被禁止了,但是违反 no-POD 规则的症状通常是不可预知的。只要字符串都适合内存,它可能看起来可以正常工作,但在这种情况下,您无论如何都不需要 STXXL。

    【讨论】:

    • 我明白了,有没有更好的方法来解决这个问题? Stxxl 库不再喜欢我的问题的可行解决方案。例如,您对此数据库有任何经验吗? ssdb.io他们说它类似于redis,所以也许它可以用于预处理或者有没有更好的方法我不知道?我的问题是我需要临时存储数据以进行预处理,然后再将最终数据插入数据库,并且它的数据集比已安装的 RAM 可以处理的更大。
    • 没有这些经验。当我遇到这样的问题时,我非常积极地优化问题以使其适合 RAM。这包括将我不需要编辑的所有字符串加载到单个内存块中,并将char const* const 存储到该块中。此外,我将我的算法分成多个通道,每个通道都适合内存。
    • 是的,我也在使用多次传递来获得我需要的东西,实际上我需要读取整个文件两次。问题是,如果我将预处理数据的一部分存储在数据库中,那么对如此大的数据集进行更新操作会耗费大量时间。因此,由于速度的原因,即使是预处理文件,我也必须将其保存在内存中,以便我可以添加后来发现的其他数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多