3.30一周拾遗
一些杂项的积累
PHP配置文件找不到怎么破
使用PHP的phpinfo();来进行查找
1
|
// PHP CLI
|
Segment Fault 段错误 怎么进行debug
首先Linux系统默认是不dump Core的 需要设置unlimit 让系统对Fault的Core进行Dump
1
|
ulimit -c unlimited
|
就可以将出错时的内核文件进行输出 .Core.XXXX文件
然后 yum install gdb 然后
1
|
gdb php core.XXXX 进行分析 可以找出出错的行数
|
[未解决问题] 对PHP扩展开发的时候 return_value_used变量不能用
提示未定义 而且在源码包内对PHP_FUNCTION的宏定义中找不到这个变量 难道是PHP7更新之后自动可以GC的缘故?
Redis 内存数据库数据结构整理
SDS (动态字符串)
1
|
struct sdshdr {
|
SDS使用空间预分配和惰性空间释放策略 提升性能
空间与分配:
如果小于1MB
预分配相同的size
如果大于1MB
预分配1MB的size
二进制安全
避免使用 \0 导致字符串截断
Redis在读取字符串的时候是依据 SDS结构之内的len进行读取 有多少读多少
对比C字符串的优点
-
O(1)获取长度复杂度
-
杜绝缓冲区溢出
-
减少修改字符串带来的内存重新分配次数
-
二进制安全
链表
链表提供高效的结点重排能力
1
|
typedef struct listNode {
|
API时间复杂度
-
返回值所在的index O(N)
-
返回index所在的值 O(N)
-
删除指定结点O(N)
-
复制一个副本O(N)
-
释放链表 O(N)
字典—使用哈希表实现
又被称为符号表、关联数组、或者映射
字典使用哈希表实现
1
|
typedef struct dictEntry{ // 哈希表结点
|
解决HashTable的方法
有链接法和开放寻址法
链接法就是当发生index冲突的时候,在index处形成链表,新插入的在前面
开放寻址法就是发生index冲突的时候,自动向下寻址
HashTable的API时间复杂度
-
向HashTable加新的元素 O(1)
-
释放HashTable O(N)
跳跃表-有序set的实现之一
跳跃表支持平均O(logN)、最坏O(N)的复杂度查找
。。。说实话跳跃表没咋看懂
跳跃表API时间复杂度
-
寻找 删除 返回排位 平均O(logN) 最坏O(N)
-
给定一个范围 如果有一个在范围之内 就可以 O(1)
整数集合 set的单纯整数实现
1
|
typedef struct intset{
|
整数集合API时间复杂度
-
添加新元素复杂度为O(N) // 因为每次操作都可能引起升级 所以会大一点
-
整数集合不会降级 保证性能
压缩列表 列表键和哈希键的实现之一
压缩列表是连续内存构成的顺序结构
[zlbytes, zltail, zllen, entry1, entry2, …, zlend];
zlbytes: 表示压缩列表总长度
zltail: 压缩列表尾部指针P
zllen: 压缩列表数据个数
通过以上三个参数 可以分别计算出每个数据点的指针 从尾部开始计算即可
压缩列表结点构成
[previous_entry_length, encoding, content]
pre记录了前一个结点的长度
可以根据当前结点的起始地址计算出前一个结点的起始地址指针
压缩列表API时间复杂度
-
创建一个包含指定结点的压缩列表 O(N) 最坏O(N*N)
-
插入结点 O(N) 最坏O(N*N)
-
返回index的结点O(N)
-
找到包含指定值的 O(N) 最坏O(N*N)
-
删除指定结点 O(N) 最坏O(N*N)
-
返回结点数量 结点数量小于65535 O(1) 最坏O(N*N)
REDIS对象以及实现
Redis_string
int raw embstr;
redis_list
ziplist hashtable intlist
redis_hash
ziplist hashtable
redis_set
intset hashtable
reids_zset
ziplist skiplist