0%

前言

我今天真的是被这个boost库搞到头炸,怎么在linux下安装boost库,及后续使用。一开始用sudo apt-get install libboost-dev倒是能解决代码中头文件引用不存在问题,但是编译不成功,总是会出现什么未定义引用错误,之后remove掉,重新下载源码编译还是会存在一些问题。

安装全过程

  1. 这里下载boost的源码包,我下载的是unix平台的boost源码包,Version 为1.73.0。

    这里有官网指导教程。

  2. 下载好,复制到桌面吧,之后解压,得到压缩包。

    1
    tar --bzip2 -xf boost_1_73_0.tar.bz2
  3. 切换到源码目录,cd boost_1_73_0,可以看到有一个bootstrap.sh文件

  4. 然后运行bootstrap.sh脚本并设置相关参数:

    1
    2
    3
    ./bootstrap.sh --with-libraries=all --with-toolset=gcc
    # --with-libraries指定编译哪些boost库,all把全部选上,以免出了啥子差错
    # --with-toolset指定编译时使用哪种编译器,Linux使用gcc,当然默认就有
  5. 设置完成以后,开始编译,编译命令./b2,编译过程有点慢,编译结束后大致涨这个模样。

  6. 接着就是安装boost,安装命令./b2 install --prefix=/usr

    --prefix=/usr用来指定boost的安装目录,不加此参数的话默认的头文件在/usr/local/include/boost目录下,库文件在/usr/local/lib/目录下。这里把安装目录指定为–prefix=/usr则boost会直接安装到系统头文件目录和库文件目录下,可以省略配置环境变量。

    我没有指定安装目录,直接``./b2 install`,结果还要配置环境变量烦。

    还要注意的一点,这个操作是往usr目录写入一些文件,没有提示需要root权限居然也执行成功了,但是在该出现的目录却没有应该要出现的文件,心态崩了,所以需要在root权限下执行,我又重新做了一遍。

  7. 最后运行一下ldconfig, 该命令通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

示例使用

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <boost/filesystem.hpp>
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

std::vector<std::string> dirs;//目录向量字符串形式
int INTERVAL = 10;//间隔

int main ()
{
for ( boost::filesystem::recursive_directory_iterator end, dir("./0");dir != end; ++dir )
{
// std::cout << *dir << "\n"; // full path
std::string s = dir->path().c_str();
dirs.push_back(s); // just last bit

}
std::srand(42);
int ndirs = dirs.size();
std::cout << "Directories found: " << ndirs << std::endl;

std::vector<std::string> files;

for (int i=0; i<10000000; i++)
{
int r = std::rand() % ndirs;
std::string* d = &dirs[r];
std::string n = *d + "/f" + std::to_string(i);
files.push_back(n);
}

int nfiles = files.size();
std::cout << "Files generated: " << nfiles << std::endl;

int start = (int)time(NULL);
int count = 0;
int lastcount = 0;

for (std::string fn : files)
{
count++;
int f = open(fn.c_str(), O_WRONLY | O_CREAT, 0777);
close(f);
int current = (int)time(NULL);
if (current - start >= INTERVAL)
{
start = current;
printf("%d:%d\n", count, (count-lastcount)/INTERVAL);
fflush(stdout);
lastcount = count;
}
}
return 0;
}

调试执行,需要在末尾后面指定 -lboost_filesystem,因为我的示例代码导入了#include <boost/filesystem.hpp>,相应的其他的也需要指定

1
2
3
4
5
mm@ubuntu:~/桌面/filt$ g++ create.cpp -o creat -lboost_filesystem
mm@ubuntu:~/桌面/filt$ ./creat
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
what(): boost::filesystem::directory_iterator::construct: No such file or directory: "./0"
已放弃 (核心已转储)

总结

我感觉我的折腾劲在一点点磨掉,我不断地搜索着我出现的问题,其实也就那些前人遇到问题,我不断地尝试,不断地复现,而新问题,我解决不了,还是搜索,求人。

LMS-Tree(Log-Structured Merge-Tree,日志结构合并树)

LSM-tree是由两个或两个以上存储数据的结构组成的。最简单的LSM-tree有两个部分,如下图所示。常驻内存部分,称为$C_0$树(或$C_0$),其可以设计为任何方便键值查找的数据结构,常驻硬盘部分,称为$C_1$树(或$C_1$)。C1进一步可延申为$C_2$,$C_3$等等。

img

数据结构名称解析

  1. 日志:磁盘可以看做是一个日志,就好像日记本一样。在向日志中存放永久性数据及其索引,每次都会添加在日志的末尾。

  2. 合并:

    image-20200703075918216

    内存中无法保存太多的数据,毕竟内存贵。$C_0$是有一个设定阈值的,当达到阈值后,就会merge到$C_1$中,毕竟磁盘中的$C_1$容量大,还便宜。$C_1$到$C_2$的合并也是如此

  3. 树:不多言。

LevelDB

详细介绍

从本周的周报开始,请详细描述你对FILT的理解。如架构、数据流、各函数的调用流程等,务必做到对代码深入理解,为FILT改进做准备。

FILT其实可以看作LevelDB的改进版本。LevelDB是一种持久键值存储容器,其仅仅存储了文件,key-value这种形式的文件。日常使用的文件管理器,还有文件夹这种东西,当然在Linux中也可以当作是一种文件。那么就产生了把文件夹(但可以当作文件)存储到LevelDB这种储存容器中这种想法。通过把文件夹路径Flat indexing,扁平化索引,设计成key-value形式存储到LSM-tree中。

那么问题来了:常规查找一个文件,LSM-tree中查找就可以解决,先从C0内存中查找,查找不到再到C1,C2中找。但是查找指定目录文件夹下有没有特定文件怎么做?这个指定目录可以方便找到,但包含在其中的文件怎么说?

重命名:比如把根目录root重命名为root1,很简单的想法就是把所有含有root及其以下展开的目录文件夹变更成root1.

查找某一文件所属文件夹?

其实应该考虑一下LSM-tree特性,它对写入操作比较擅长,而查找,这属于读操作。

难道有些功能其实可以不予理睬。只需要专注于提供某些特定接口。

那么FLIT做的是啥?是像LevelDB一样的数据库管理程序,还是像xfs一样的文件系统。应该是后者,但代码为什么是LevelDB代码,其中好多都是LevelDB源码?

故事梗概

裴谌、王敬伯、李芳三个人结为超脱世俗的好友。

隋炀帝大业年间,三个朋友一齐进白鹿山学道。他们认为用铜炼金用汞炼银的方术一定能得到,长生不老的仙药一定能求着。至于腾云驾雾,羽化成仙的功夫,只要苦修苦炼,也是早晚能成功的。

然而,他们经过十几年的修炼内功,采集仙药,历尽了辛苦艰难,手、脚都磨起了老茧,却仍然什么也没得到。

阅读全文 »

上次写文章还是很早以前了,中间断断续续的在写,但是断断续续的在删。老色批又来了。

本次关于某漫画网站的漫画的爬取。

动机

我在看一些视频网站,一些漫画网站,一些小说网站时,下面就有一些稀奇古怪的网站,你懂的。像我这样老色批就喜欢点进去看一看,上面就是这样的一个网站,估计以后就会改。

在该网站看漫画,前面几章是免费看的,看的心痒痒,但后面的几张就需要付费购买了。像我这样的穷屌丝,买是不可能买的,但又想看,只能花点时间白嫖,看能不能破解。

阅读全文 »

前言

人生没有回溯!我多想回溯啊。(祝你生日快乐)

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。

阅读全文 »

前言

堆,顾名思义,是长得像个草堆一样的数据结构。但在计算机存储里面,堆一般使用数组来表示。

按照堆的性质区分,可分为大顶堆,小顶堆。
大顶堆:所有的parent节点值都要大于其child节点。
小顶堆:所有的parent节点值都要小于其child节点。

阅读全文 »

故事梗概

这杜子春是南北朝时期,周朝至隋朝的人。他这个人呢,家里有点钱,整天无所事事,纵酒闲游,最后把家产都败光了。然后迫于生计,去投奔亲友,但亲友们都认为他是那种游手好闲之人,都不愿意收留他。这时的杜子春真的是到了人生谷底,饥寒交迫,孤苦无依。

说这时来了一个老人,拄着拐杖,来到杜子春面前,问他为何留宿街头,杜子春就把自己的经历告诉了他,埋怨亲友们对他无情无义,越说越激动,越说越愤慨。老人问他:几缗则丰用?杜子春答道,三五万则可以活矣。老人又说:未也?认为杜子春要的太少,不够,经过一番言价,最后杜子春答定:三百万足以。于是这老人就给了杜子春三百万。杜子春拿到了这么多钱,又开始了他的醉生梦死的生活,只用了一两年,钱财挥霍尽空。又如上次那般,穷途末路,在街头长叹起来,感慨人生。

阅读全文 »

👨的头好疼啊。

于是乎去吃了一个苹果,苹果很老,上面还坏了一点,但是很甜。我想起那句话,叫虫喜欢吃的苹果越甜。

人如苹果,越老的苹果故事越多。越被虫盯上的苹果就是越有本领。
我又回想起今天再路上的一只猫,被压死的猫。这只猫在被呼啸而过的汽车碾过的时候,它是不是还在挣扎,可是我挣扎的动吗?我除了有一点意识外,身体已经不受支配了,我在不断的抽搐,嘴角冒出一点鲜血,我看着后面的汽车相继在我身边驶过,我庆幸的是他们没有在我不能动弹的身体上驶过,我悲伤的是没有一个人来帮我,让我离开马路中间。我想起在被压倒之前,我可以飞快的奔跑,也能从容的上树,但我现在动弹不了,而后又有一辆车在我身上驶过,他应该是无意的,我本就不该躺在马路中间,我没了意识。再看时,我已经一动不动了,我知道我变成了一摊腐肉。

图及其表示方式

图由两个部分组成,一是点node,二是边edge。
图的表示方法由邻接表法和邻接矩阵法。当然还有其他的方式。
如下所示,有一无向图,其邻接表和邻接矩阵示意图为:

阅读全文 »