• redis设计与实现总结--简单动态字符串和链表


    简单动态字符串(SDS)

    struct sdshdr {
        //记录buf数组中已使用字节的数量
        //等于SDS所保存字符串的长度
        int len;
        //记录buf数组中未使用字节的数量
        int free;
        //字节数组,用于保存字符串
        char buf[];
    }
    一般会留最后一个字节来保存'',不计算再len中,方便使用c字符串函数
     
    为了防止缓冲区异常,每次SDS扩展会先看预留空间是否够,否则另外申请大空间复制,再扩展。
    但如果缩短并不会变,只有free的值变。
     
    为了避免缓冲区溢出(增长)和内存泄露(缩短)
    SDS的空间分配策略
    1.空间预分配
    当需要增加字符串长度时:
        修改后SDS长度小于1MB,则程序分配和len属性相同大小的未使用空间,这时len=free。
        修改后SDS长度大于1MB,则分配1MB未分配空间。
    2.惰性空间释放
        但如果缩短并不会变,只有free的值变。而且提供了相应的API(sdsfree,sdsrange)防止内存浪费。
     
    SDSbuf数组内可以保存的是二进制数据,因为不是根据''判断,而是根据len长度来判断。
     
    对比C字符串,SDS有如下优点:
    1.常数复杂度获取字符串长度。
    2.杜绝缓冲区溢出。
    3.减少修改字符串长度时所需的内存重分配次数。
    4.二进制安全。
    5.兼容部分C字符串函数。
     

    链表

    双向无环链表
    应用:列表键,发布与订阅,慢查询,监视器等。
    typedef struct listNode {
        //前置节点
        struct listNode *prev;
        //后置节点
        struct listNode *next;
        //节点的值
        void *value;
    }listNode;
    typedef struct list {
        //表头节点
        listNode *head;
        //表尾节点
        listNode *tail;
        //链表所包含的节点数
        unsigned long len;
        //节点复制函数
        void *(*dup)(void *ptr);
            //节点释放函数
            void *(free)(void *ptr);
            //节点对比函数
            inr  *(*match)(void *ptr,void *key);
    }list;

    三个函数去实现多态。

  • 相关阅读:
    JSBinding+SharpKit / MonoBehaviour替换成JSComponent原理
    JSBinding + SharpKit / JavaScript 加载流程
    JSBinding + SharpKit / 常见问题
    JSBinding + SharpKit / Coroutine支持
    Mysql 自定义HASH索引带来的巨大性能提升----[真相篇]
    Mysql 自定义HASH索引带来的巨大性能提升----[挖坑篇]
    python实现冒泡排序
    python 实现二分法查找
    Mysql 存储过程+定时任务,完成分区自动维护
    innodb insert buffer 插入缓冲区的理解
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/14744944.html
Copyright © 2020-2023  润新知