- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我要分析的数据很多-每个文件大约5gigs。每个文件具有以下格式:
xxxxx yyyyy
if (data_file != "")
{
clock_start = clock();
data_file_mapped.open(data_file);
data_multimap = (std::multimap<double, unsigned int> *)data_file_mapped.data();
if (data_multimap != NULL)
{
std::multimap<double, unsigned int>::iterator it = data_multimap->find(keys_to_find[4]);
if (it != data_multimap->end())
{
std::cout << "Element found.";
for (std::multimap<double, unsigned int>::iterator it = data_multimap->lower_bound(keys_to_find[4]); it != data_multimap->upper_bound(keys_to_find[5]); ++it)
{
std::cout << it->second;
}
std::cout << "\n";
clock_end = clock();
std::cout << "Time taken to read in the file: " << (clock_end - clock_start)/CLOCKS_PER_SEC << "\n";
}
else
std::cerr << "Element not found at all" << "\n";
}
else
std::cerr << "Nope - no data received."<< "\n";
}
find
方法时。我也尝试了
upper_bound
,
lower_bound
和其他方法,仍然遇到了段错误。
gdb
给我的:
Program received signal SIGSEGV, Segmentation fault.
_M_lower_bound (this=<optimized out>, __k=<optimized out>, __y=<optimized out>, __x=0xa31202030303833) at /usr/include/c++/4.9.2/bits/stl_tree.h:1261
1261 if (!_M_impl._M_key_compare(_S_key(__x), __k))
$ du -hsc 201501271755.e.ras
4.9G 201501271755.e.ras
4.9G total
$ head 201501271755.e.ras
0.013800 0
0.013800 1
0.013800 10
0.013800 11
0.013800 12
0.013800 13
0.013800 14
0.013800 15
0.013800 16
0.013800 17
sort -g -m
将各种文件组合到此主文件中。有关文件格式的更多信息,请参见:
http://www.fzenke.net/auryn/doku.php?id=manual:ras
最佳答案
您正在尝试您不太了解的事情:)没问题。
多个映射不会在内存中顺序排列。 (它们是基于节点的容器,但我离题了)。实际上,即使是这样,布局与文本输入的布局匹配的机会也很小。
基本上有两种方法可以使这项工作:
multimap
,但使用自定义分配器(以便所有分配都在映射的内存区域中完成)。从高级C++的 Angular 来看,这是“最聪明的”,/ but /您将需要更改为文件的二进制格式。iterator_facade
),可以用来实现更高级别的操作(
lower_bound
,
upper_bound
和
equal_range
)。
insert
,
remove
),则这种内存表示形式将对性能造成极大的损害。
namespace shared {
namespace bc = boost::container;
template <typename T> using allocator = bip::allocator<T, bip::managed_mapped_file::segment_manager>;
template <typename K, typename V>
using multi_map = bc::flat_multimap<
K, V, std::less<K>,
allocator<typename bc::flat_multimap<K, V>::value_type> >;
}
flatmap
(实际上是flat_multimap
),因为它可能更多map
(或hash_map
),而不是平坦的变体形式。 managed_mapped_file
段(这样您就可以保持持久性)。该演示演示了如何稀疏地预分配10G,但只有实际分配的空间才在磁盘上使用。您同样可以使用managed_shared_memory
。shared::multi_map<double, unsigned>
解析为mapped_file_source
。该实现是完全通用的。 iterator
类,start_of_line()
,end_of_line()
,lower_bound()
,upper_bound()
,equal_range()
或其他任何一种,因为它们已经是multi_map
接口(interface)中的标准设置,因此我们只需要编写main
:#define NDEBUG
#undef DEBUG
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iomanip>
namespace bip = boost::interprocess;
namespace qi = boost::spirit::qi;
namespace shared {
namespace bc = boost::container;
template <typename T> using allocator = bip::allocator<T, bip::managed_mapped_file::segment_manager>;
template <typename K, typename V>
using multi_map = bc::flat_multimap<
K, V, std::less<K>,
allocator<typename bc::flat_multimap<K, V>::value_type> >;
}
#include <iostream>
bip::managed_mapped_file msm(bip::open_or_create, "lookup.bin", 10ul<<30);
template <typename K, typename V>
shared::multi_map<K,V>& get_or_load(const char* fname) {
using Map = shared::multi_map<K, V>;
Map* lookup = msm.find_or_construct<Map>("lookup")(msm.get_segment_manager());
if (lookup->empty()) {
// only read input file if not already loaded
boost::iostreams::mapped_file_source input(fname);
auto f(input.data()), l(f + input.size());
bool ok = qi::phrase_parse(f, l,
(qi::auto_ >> qi::auto_) % qi::eol >> *qi::eol,
qi::blank, *lookup);
if (!ok || (f!=l))
throw std::runtime_error("Error during parsing at position #" + std::to_string(f - input.data()));
}
return *lookup;
}
int main() {
// parse text file into shared memory binary representation
auto const& lookup = get_or_load<double, unsigned int>("input.txt");
auto const e = lookup.end();
for(auto&& line : lookup)
{
std::cout << line.first << "\t" << line.second << "\n";
auto er = lookup.equal_range(line.first);
if (er.first != e) std::cout << " lower: " << er.first->first << "\t" << er.first->second << "\n";
if (er.second != e) std::cout << " upper: " << er.second->first << "\t" << er.second->second << "\n";
}
}
const char*
区域上映射的简单容器; boost::iterator_facade
生成一个迭代器,该迭代器在取消引用时解析文本; boost::string_ref
-避免了动态分配来复制字符串。 if (!qi::phrase_parse(
b, _data.end,
qi::auto_ >> qi::auto_ >> qi::eoi,
qi::space,
_data.key, _data.value))
Key
和Value
类型:text_multi_lookup<double, unsigned int> tml(map.data(), map.data() + map.size());
lower_bound
,upper_bound
和equal_range
成员函数,这些函数利用了底层连续存储的优势。即使“行” iterator
不是随机访问,而是双向的,我们仍然可以跳转到此类迭代器范围的mid_point
,因为我们可以将start_of_line
从任何const char*
放入基础映射区域。这使得二进制搜索有效。 iterator
时解析行。如果相同的行被多次取消引用,则这可能无效。
O(log n)
二进制搜索),同时始终完全绕过初始查找而是通过映射文件来加载时间(无访问权限意味着不需要加载任何内容)。
#define NDEBUG
#undef DEBUG
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/utility/string_ref.hpp>
#include <boost/optional.hpp>
#include <boost/spirit/include/qi.hpp>
#include <thread>
#include <iomanip>
namespace io = boost::iostreams;
namespace qi = boost::spirit::qi;
template <typename Key, typename Value>
struct text_multi_lookup {
text_multi_lookup(char const* begin, char const* end)
: _map_begin(begin),
_map_end(end)
{
}
private:
friend struct iterator;
enum : char { nl = '\n' };
using rawit = char const*;
rawit _map_begin, _map_end;
rawit start_of_line(rawit it) const {
while (it > _map_begin) if (*--it == nl) return it+1;
assert(it == _map_begin);
return it;
}
rawit end_of_line(rawit it) const {
while (it < _map_end) if (*it++ == nl) return it;
assert(it == _map_end);
return it;
}
public:
struct value_type final {
rawit beg, end;
Key key;
Value value;
boost::string_ref str() const { return { beg, size_t(end-beg) }; }
};
struct iterator : boost::iterator_facade<iterator, boost::string_ref, boost::bidirectional_traversal_tag, value_type> {
iterator(text_multi_lookup const& d, rawit it) : _region(&d), _data { it, nullptr, Key{}, Value{} } {
assert(_data.beg == _region->start_of_line(_data.beg));
}
private:
friend text_multi_lookup;
text_multi_lookup const* _region;
value_type mutable _data;
void ensure_parsed() const {
if (!_data.end)
{
assert(_data.beg == _region->start_of_line(_data.beg));
auto b = _data.beg;
_data.end = _region->end_of_line(_data.beg);
if (!qi::phrase_parse(
b, _data.end,
qi::auto_ >> qi::auto_ >> qi::eoi,
qi::space,
_data.key, _data.value))
{
std::cerr << "Problem in: " << std::string(_data.beg, _data.end)
<< "at: " << std::setw(_data.end-_data.beg) << std::right << std::string(_data.beg,_data.end);
assert(false);
}
}
}
static iterator mid_point(iterator const& a, iterator const& b) {
assert(a._region == b._region);
return { *a._region, a._region->start_of_line(a._data.beg + (b._data.beg -a._data.beg)/2) };
}
public:
value_type const& dereference() const {
ensure_parsed();
return _data;
}
bool equal(iterator const& o) const {
return (_region == o._region) && (_data.beg == o._data.beg);
}
void increment() {
_data = { _region->end_of_line(_data.beg), nullptr, Key{}, Value{} };
assert(_data.beg == _region->start_of_line(_data.beg));
}
};
using const_iterator = iterator;
const_iterator begin() const { return { *this, _map_begin }; }
const_iterator end() const { return { *this, _map_end }; }
const_iterator cbegin() const { return { *this, _map_begin }; }
const_iterator cend() const { return { *this, _map_end }; }
template <typename CompatibleKey>
const_iterator lower_bound(CompatibleKey const& key) const {
auto f(begin()), l(end());
while (f!=l) {
auto m = iterator::mid_point(f,l);
if (m->key < key) {
f = m;
++f;
}
else {
l = m;
}
}
return f;
}
template <typename CompatibleKey>
const_iterator upper_bound(CompatibleKey const& key) const {
return upper_bound(key, begin());
}
private:
template <typename CompatibleKey>
const_iterator upper_bound(CompatibleKey const& key, const_iterator f) const {
auto l(end());
while (f!=l) {
auto m = iterator::mid_point(f,l);
if (key < m->key) {
l = m;
}
else {
f = m;
++f;
}
}
return f;
}
public:
template <typename CompatibleKey>
std::pair<const_iterator, const_iterator> equal_range(CompatibleKey const& key) const {
auto lb = lower_bound(key);
return { lb, upper_bound(key, lb) };
}
};
#include <iostream>
int main() {
io::mapped_file_source map("input.txt");
text_multi_lookup<double, unsigned int> tml(map.data(), map.data() + map.size());
auto const e = tml.end();
for(auto&& line : tml)
{
std::cout << line.str();
auto er = tml.equal_range(line.key);
if (er.first != e) std::cout << " lower: " << er.first->str();
if (er.second != e) std::cout << " upper: " << er.second->str();
}
}
main
中:
http://paste.ubuntu.com/9946135/
关于c++ - 使用带有std::multimap的boost::iostreams::mapped_file_source,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28217301/
在 C++ 中包含头文件时,和...有什么区别 在 <> 标志中包含 .h 部分与不包括 .h 部分? #include 与 #include 将标题名称用双引号括起来还是用 符号括起来? #inc
最近我在阅读 Accelerated C++ 并从练习答案中发现了这个有趣的代码。这是完整的代码, #include "stdafx.h" #include "4_4.h" #include usi
我正在开发一个需要能够在标准 C++ 编译器和准标准编译器上编译的实用程序。代码可以而且将会被扔到几乎任何现有的 C++ 编译器上。 我正在寻找一种可靠且可移植地确定目标编译器是否支持带或不带 .h
如果有一个文件 foo.cpp,那么它通常有一个关联的头文件 foo.h,其中包含 foo.cpp 中定义的函数的所有声明。这样,所有其他使用 foo.cpp 中的函数的文件都可以只包含 foo.h
iostream 和 iostream.h 有什么区别? 最佳答案 iostream.h 已被提供它的编译器弃用,iostream 是 C++ 标准的一部分。 为了明确说明,当前 C++ 标准 (IN
我知道关于 之间的区别的问题和 之前有人问过。阅读这些答案后,我发现了以下差异 当然iostream.h已弃用,新的符合标准的编译器不支持它 iostream.h不包含 std 中的所有内容命名
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Difference between iostream and iostream.h 我的教授说了以下内容:
我需要构建一些我在办公室电脑上得到的旧代码,它有 gcc 4.4.5安装。我编辑了代码(删除 .h 或添加类似 的内容)以使它们保持最新,以便它们可以由 gcc 4.4.5 编译.但是,在看似成功编
我在学习C++的时候遇到了一个问题,在编译的时候遇到了错误。 详情如下: 最佳答案 您似乎没有在 MinGW 中安装 C++ 支持。如果您使用手动安装路径,请下载 gcc-c++ dev、dll 和
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: What is the difference between #include and #include
对于我当前的任务,我需要能够读/写(主要是基于文件的)比特流。虽然如果用标准 C/C++ 编码,这或多或少是一项微不足道的任务,但我喜欢通过重载和使用更通用的方法重写代码标准的 STL iostrea
这个问题在这里已经有了答案: Difference between iostream and iostream.h (3 个答案) 关闭 9 年前。 有什么区别 #include 和 #inclu
我正在尝试为 linux/MacOS 转换一个用 C++14 编写的应用程序。它使用 boost::filesystem,但不用于某些 iostream 操作。例如: boost::filesyste
示例: namespace boostio = boost::iostreams; boostio::stream memStream(arr); while (!memStream.eof())
我编写了以下简单的 C++ 程序: #include using namespace std; int main() { cout ^~~~~~~~~~ 1 error
我想在我的代码中将流公开为它们的标准等价物,以消除用户对 boost::iostreams 的依赖性.如果有必要,当然想有效地执行此操作而无需创建拷贝。我考虑过只设置 std::istream的缓冲区
#include in header files and #include only in cpp files 被认为是最佳实践。我正在尝试将大量 #include 从 header 移动到现有
#include #include #include #include using namespace std; int main() { int ival; while(ci
假设我得到一个 stringbuf,其中包含一些必须删除的特定字符序列的内容: std::stringbuf string_buff; std::iostream io_stream (&string
我有一个包含如下记录的文件 123 Tag 现在是所有好人都来帮忙的时候了 总是有一个数字和一些标签,后面跟着一系列单词。我想将数字提取为整数,将标记提取为字符串,将句子提取为字符串。我已经使用 ge
我是一名优秀的程序员,十分优秀!