自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(102)
  • 收藏
  • 关注

原创 minio多版本

3、其中的xl.meta文件可以使用xl-meta工具解析,这里会记录详细的版本信息。2、在文件名1M目录下会有3个uuid为名的目录。1、界面上传3次1M文件,可以显示3个版本的。

2024-03-01 19:45:00 181

原创 badgerdb中的logfile

logfile是一种日志结构,用来记录日志,lsm tree是日志追加写的模式,在bagerdb中,vlog和sst在磁盘中的存放方式都是使用的logfile结构。

2023-08-24 22:06:30 161

原创 badger的写过程

当value的长度大于默认1M就先写vlog,再插入lsm tree,小于1M的就直接插入lsm tree,这种方式的写入主要是为了k,v分离,lsm tree里面不存大的value,在lsm tree合并压缩的时候就不需要读写大value,整体减少磁盘资源的消耗。memtable在内存上用的是一个跳表的数据结构,在磁盘上是一个以.mem结尾的文件,写memtable是先把entry写入文件,再修改跳表里面的内存。目录下的文件,用来保护目录只能被一个进程打开,避免多进程badger同时打开这个目录。

2023-08-24 21:42:52 190

原创 badgerdb 压缩合并

同一层的同一个table只能是一个压缩协程占用。第0层的table表和table之间的排列不是按照sst的范围来排的,只是按照写入的时间顺序来排,非0层table表之间按照sst的范围来排,非0层选择待压缩的table就直接从第0个开始,即写入时间最旧的,如果和下一个table表有交集就也需要加入,下一个table表的范围没有交集就退出。先按提交的时间把合并层的tbale表排序,提交时间早的优先被挑选到,挑选出来的table有最大和最小的key,在待合并的下一层找到和这个范围有交集的table表。

2023-08-24 20:10:03 211

原创 badgerdb里面的事务

创建一个事务的时候,要进行授时txn.readTs = db.orc.readTs(),这个时间是一个递增的序列,接下来主要来分析一下db.orc.readTs()这个函数,获得readTs后会等待readTs这个时间戳提交的事务彻底写入LSM tree后才返回,保证了不会。但如上图,如果事务 t2 在执行时,多次读某个记录 x 的状态,在事务 t1 未启动前,发现 x = 2,在事务 t1 提交后,发现 x = 3,这便出现了不一致。多个事务执行时,不能受并发的事务的影响,后面会详细的说隔离级别。

2023-08-17 07:50:07 998 1

原创 badger的mainfest文件解读

ReplayManifestFile函数在回放数据的时候,是在重新打开数据库,数据库目录存在MANIFEST就直接从MANIFEST来读取,即使上次在写MANIFEST-REWRITE的发生断电,内存中的lsm tree的sst表修改是在后的,不会执行,不影响数据可靠性,等下次重新写MANIFEST文件的时候,就会重新把上次的脏数据擦除。mainfest文件是记录lsm tree中的各层tables表的创建删除记录的一个日志文件,主要的作用是badger数据库重启后,重新恢复内存中的各层tables表。

2023-08-13 17:30:37 183

原创 FD_SET设置的文件描述符超过1024引发coredump

在开发过程中,遇到一个coredump的问题,最后排查到是FD_SET的文件描述符大于10232、开始执行这种问题就更坑人了,并不是只要超过1023就会必现,到1200就快复现了3、gdb调试这里还好,最起码gdb报的行数是在36,在FD_SET这行,在自己的开发环境就没这么好了3、内核里面 FD_SET的定义__NFDBITS是一个定值64 ,在64位机上__FDSET_LONGS 是一个定值(1024/64)在64位机上,fds_bits数组的长度就是(1024/64)当fd大于 1023的

2023-08-11 15:07:25 336

原创 go 语言管道

go 语言管道有缓存,无缓冲管道,读写clone测试package mainimport ( "fmt" "time")func main() { c := make(chan struct{}, 3) c <- struct{}{} fmt.Printf(" len(c) = %d\n", len(c)) fmt.Printf(" cap(c) = %d\n", cap(c)) c <- struct{}{} fmt.Printf(" len(c) = %

2021-06-27 11:19:26 301

原创 Go语言实现冒泡

Go语言实现冒泡冒泡排序,按从小到大排列,循环一次比较两个相邻两个数的大小,然后交换,循环一次即可找出最大的一个数并防在最后一位代码实现:

2020-10-18 18:15:42 407

原创 gobject创建一个新的实例(继承和重构)

概述在 GObject世界里,类是两个结构体的组合,一个是实例结构体,另一个是类结构体。GOBJECT的继承需要实现实例结构体的继承和类结构体的继承,Gobject对象的初始化可分为两个部分:类结构体初始化和实例结构体初始化。类结构体初始化函数只被调用一次,而实例结构体的初始化函数的调用次数等于对象实例化的次数。这意味着,所有对象共享的数据,可保存在类结构体中,而所有对象私有的数据,则保存在实例结构体中。宏定义解析G_DEFINE_TYPEG_DEFINE_TYPE(Man, man, G_TYPE_

2020-05-19 17:32:43 426

原创 glib学习

glib概述glibc 是gnu发布的libc库,也即c运行库,glib是gtk+的一套函数库,gobject是glib的精粹,glib是用C实现的.glib提供了动态数组、单/双向链表、哈希表、多叉树、平衡二叉树、字符串等常用容器,完全是面向对象设计的,实现得非常精致。代码分析1、打印hello word!直接上代码#include <stdio.h>#include <glib.h> intmain(int agrc, char **argv){ g_

2020-05-14 17:10:28 667

原创 指针和内存的关系

1、如何描述内存:(1)一段内存需要有一个地址和内存的大小才可以描述;(2)一个内存可以说是一个buffer,那么这个buffer就是一个指针,然后还需要一个buffer_size;(3)也可以用头指针和尾指针来描述,其实尾指针减去头也就是size;2、具体代码(1)要注意一个函数如何实现传内存的指针进去,如何修改这个指针的所指向的内容;(2)使用memcpy函数,将内...

2020-01-09 20:31:55 1141

原创 使用FAAD库对AAC格式的音频进行解码

1、AAC音频文件格式(1) AAC的音频文件格式有ADIF & ADTS: 我主要做的是ADTS,我们就分析ADTS格式,下面的图可以反映问题。 可以参考:https://www.jianshu.com/p/b5ca697535bd 但是这里的ADTS Frame帧中AAC ES的大小不是固定的,这就造成每一帧ADTS数据大小都...

2019-12-29 20:27:09 1508 2

转载 pthread_mutex_t 和 pthread_cond_t 配合使用的简要分析

1、需求有消费者A和生产者B线程,共享变量n,生存者对n++,消费者对n--,消费者线程A必须要等到n>0才可以执行下去,当然生产者B线程就执行n++,让消费者能执行下去。2、生产者和消费者模型中互斥锁和条件变量的使用流程图如下,其中蓝色代表消费者的执行流,红色是生产者的执行流。3、几个函数/* 初始化一个条件变量 */int pthread_cond_init ...

2019-11-21 11:43:08 296

原创 uboot启动第2阶段总结

uboot启动阶段就是start_armboot开始的init_fnc_t cpu_init 空的 board_init 初始化dm9000网卡,机器码和启动参数 interrupt_init 中断初始化,...

2019-10-14 21:43:57 121

原创 uboot的文件夹和文件目录的介绍

1、文件(1).gitignore,git工具的文件,git是一个版本管理工具(类似的还有svn),这个文件和git有关。(2)arm_config.mk,后缀是mk,是一个Makefile文件,将来在某个Makefile中去调用它。(3)三个Changlog文件,修改记录文件,该文件记录了这个uboot项目的版本变迁以及每个版本修改对的记录。(4)config.mk,这个和arm...

2019-09-26 20:40:19 1469

原创 poll函数

1、函数原型:int poll(struct pollfd fds[], nfds_t nfds, int timeout);2、函数的作用:和select函数基本相同,为了提高程序的运行效率,把阻塞原来阻塞的函数编程非阻塞。并可以设置如果超过时间未发生事件,则直接返回。3、参数:(1)fds,一个数组名,数组成员里面存的类型为struct pollfdstruct p...

2019-09-17 10:48:31 447

原创 select函数

1、select函数函数原型:int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout);(1)函数的作用:read和wr...

2019-09-17 09:10:29 486

原创 linux内核源码目录

(1)arch文件夹,arch是architecture的缩写,意思就是架构。arch里面有很多个不同的架构的CPU子目录,譬如ARM这种cpu的所有文件都在arm子文件目录下面(2)block,英文是块的意思,在linux中block表示块设备(以块(多个字节组成的整体,类似于扇区)为单位来整体访问),SD卡,iNand,Nand,硬盘等都是块设备,可简单的认为块设备就是存储设备。block...

2019-09-12 17:19:15 525

原创 linux多线程编程中使用信号量同步与互斥锁

一、什么是信号量线程的信号量与进程间通信中使用的信号量是一样的,它是一个特殊的变量。可以被增加和减少,但对其的关键操作访问必须保证原子操作。如果一个程序中有多个线程试图改变一个信号量的值,系统将保证所有的操作都依次进行。二、信号量的函数信号量的函数都是以sem_开头,线程中使用的基本信号量函数有4个,在头文件semaphore.h中。1、sem_init函数该函数用于创建信号量...

2019-09-09 17:55:56 304

原创 线程的引入

1、进程的劣势(1)进程间切换开销大(2)进程间通信特别麻烦而且效率低2、解决方案就是线程技术(1)线程技术保留了进程技术实现多任务的特性。(2)线程的改进就是在线程间切换和线程间通信上提升了效率。(3)一个简单的例子实现一个进程中多线程,实现同时读键盘和鼠标#include <stdio.h>#include <sys/stat.h>#i...

2019-09-07 10:17:55 208

原创 C++的ostream的用法,输出符符号重载

ostream是标准的输出流,我们经常使用cout直接输出,但是我们想过没有去直接用cout打印一个类下面的代码就直接对"<<"进行符号重载,可以直接打印一个类Point.h#ifndef _POINT_H_#define _POINT_H_#include <iostream>using namespace std;class Point{p...

2019-06-27 20:53:53 11749

原创 static在C++中的几种情况

1、存在于全局和局部的作用域中的静态变量1、被static修饰的全局变量,只能在本文件中使用,在其他文件不能使用。2、被static修饰的局部变量,只能在函数体中被调用,多次调用该函数时,也只能被初始化1次。#include <iostream>using namespace std;static int i = 0; //静态全局变量void displ...

2019-06-26 18:22:00 898

转载 C/C++中const的用法

C/C++中的const的使用方法1、修饰常量const int i = 4; //i是常量2、修饰指针 主要看const是在*前还是*后面,在*前是指针所指向的内容是常量,在*后面是指针是常量const int *p; //指针所指向的内容是常量int const *p; //指针所指向的内容是常量int * const P; ...

2019-05-03 12:55:03 121

原创 C++访问限定符public、project、private和继承

1、被private限定符修饰的成员,只能在类内进行访问(被类的成员函数进行访问)2、被public限定符修饰的成员,可以在类内和内外都可以进行访问3、被project限定符修饰的成员,可以在类内进行访问,在类外不能进行访问(和private相似)5、类可以进行继承,就会产生父类(基类),子类(派生类)下面看代码和注释Person.h#ifndef _PERSON_H_...

2019-04-16 15:01:54 1152

原创 uboot中mkconfig的详细解说

一、1、在uboot的主Makefile中2589和2590这两行代码是进行配置的2、$(@:_config=) 这里的意思就是x210_sd_config转换层x210_sd3、执行make x210_sd_config就说执行mkconfig x210_sd arm s5pc11x x210 samsung s5pc110 $# = 6 $0 = ...

2019-03-23 15:58:21 451

原创 linux socket函数编程

服务器socket-&gt;bind-&gt;listlen-&gt;accept-&gt;write在写这个服务器的代码过程中遇到很多容易出错的地方1、serveraddr.sin_port = htons(portnumber); 这里一点记住是htons()函数,用htonl会出错,有大小端问题,端口号会变2、if((newfd = accept(sockfd,(...

2019-03-14 16:32:55 501

原创 signal sigaction alarm函数

1、信号是一种异步通信机制(和单片机里面的中断很像)2、信号的目的:用来通信3、信号的本质是int 型的数字编号,在/usr/include/i386-linux-gnu/bits/signum.h被宏定义(ubuntu系统)4、常见的信号介绍(1)SIGINT 2 Ctrl+C是OS送给前台进程...

2019-03-05 17:37:16 275

原创 写一个简单的守护进程

1、进程查看命令ps(1)ps -aux偏向于进程占有各种资源(CPU、内存)(2)ps -ajx偏向于显示进程各种有关的ID号(父进程的ID ppid,进程组ID pgid,进程会话ID SID)2、守护进程(1)deamon,表示守护进程,简称d(进程后面带d的基本都是守护进程)(2)长期运行(从开机到关机)(3)与控制台脱离(普通进程和控制台绑定,控制台关闭,进程结...

2019-03-04 15:17:22 297

原创 atexit和return、exit、_exit之间的关系

1、atexit函数的原型int atexit(void (*function)(void));2、用来注册函数,进程死亡,之前调用被注册的函数 1 #include &lt;stdio.h&gt; 2 #include &lt;stdlib.h&gt; 3 #include &lt;unistd.h&gt; 4 5 void func1(void) 6 {...

2019-02-27 12:36:23 403

原创 大小端模式

大端模式:高地址放低位  其中51单片机是大端模式小端模式:高地址放高位   ARM都是小端模式用共用体的方式来检测大小端模式1 #include &lt;stdio.h&gt; 2 3 union endian 4 { 5 int a; 6 char b; 7 }; 8 9 //共用体都是从低地址进行访问的 10 void ...

2019-02-24 12:23:23 123

原创 代码段、数据段

1、代码段:就是程序的可执行部分,直观的认为就是堆叠的函数2、数据段:(也称为数据区,静态数据区,静态区)直观的理解就是全局变量(局部变量不属于程序的数据,属于函数的数据)     数据段:             bss段:又叫做ZI(zero initial段),特点是被初始化为0的数据段。             .data段:未被初始化0的全局变量,和静态局部变量特殊的...

2019-02-23 14:57:59 5379

原创 malloc的使用

1、使用堆内存的时候需要程序员自己用malloc去申请内存2、malloc的返回值类型是void*,前面一般接强制类型转换3、malloc示例代码使用   

2019-02-23 12:17:30 199

原创 进程中的内存布局

1、程序被放在内存中运行,程序运行时需要存储一些临时变量。2、内存被操作系统进行管理。3、有三种内存来源:栈、堆、数据区 栈:     运行时自动分配,自动回收,不需要程序员干预。     反复使用:栈内存的大小确定,就是哪一块空间,反复使用。     脏内存:栈在每次使用后都不会去清理,每次都保留上一次的值。     临时性:函数不能返回栈变量的指针。原因是解引用的返...

2019-02-22 21:29:06 138

原创 指针数组,数组指针,函数指针

1、指针数组的实质是数组,数组里面存的是指针变量2、数组指针实质是指针,指针指向的是一个数组如何区分他们呢,[]的结合优先级比*高int *p[5]  指针数组, p先和[]结合,是一个数组,数组里面存的都是int* 类型的指针变量,指针变量指向的是int类型的数int (*p)[5] 数组指针,p先和*结合,是一个指针,数组里面存了5个元素,元素的类型都是int类型,指针指向这个...

2019-02-21 15:51:52 85

原创 字符串指针,引出的const,再到函数的输入型参数,输出型参数

1、调用func1时出错的原因?(代码如上两图)字符串指针被定义后,不能被修改,指针指向的是常量区,修改会出现段错误。函数func1中是对字符串指针pStr进行了修改2、fun2(const char *a,char *b)指针a所指向的变量被const修饰后不可改变。3、linux的库函数中strcpy函数的源变量src就是被const修饰的,表示只能读,不能进行...

2019-02-21 13:46:35 374

原创 sizeof,strlen,函数,指针和数组之间的关系

1、sizeof是运算符,用来返回()中变量或者数据类型所占内存的字节大小。2、函数的形参如果是数组的时候,[]中的数字可有可无,传的只是一个地址过来3、结构体传参的话,c语言可以有两种,一种直接传结构体过来,另一种传jiegu结构体指针过来。传结构体指针的话,效率高。...

2019-02-21 12:49:05 265

原创 指针和强制类型转换

(1)所有的类型的数都是以二进制的形式存储在内存中,不知道什么int short char等(2)char short int 等属于整型,存储的方式一样,只是内存的格子不一样而已(它们叫二进制兼容格式),而float double则不同,和整型更不同。(3)按照什么类型的存进去的按照什么类型的取出来,如果是按整型存进去,按%f取则会出现奇怪的数字。...

2019-02-20 12:34:12 452

原创 指针和数组的类型匹配问题

int *p;int a[5]; p = a       //类型匹配int *p;int a[5];p = &amp;a     //类型不匹配a 和 &amp;a[0]都是数组第一个元素的首地址,类型都是int *;&amp;a是数组的首地址,是一个数组指针,类型是int (*)[5]。指针类型如何决定了指针如何参与运算?       int *p ,p+1实际上是地址+siz...

2019-02-19 20:11:56 257

原创 const和指针变量

第一种:const int *p         p是可变的,*p是不可变的第二种:int const *p         p是可变的,*p是不可变的第三种:int *const  p        p是不可变的·,*p是可变的第四种:const int * const p     p是不可变的,*p也是不可变的第五种:const int  const *p      p是可变的...

2019-02-19 15:28:45 159

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除