数据结构:缓冲区/缓存简单实现

  1. 简单图解
    缓冲区内部:容量为 capacity 的 内存块 可以看作 长度为 capacity 的 字节数组
    缓冲区内部
    读/写指针的变化:版本二中的读写操作函数使用 memcpy 函数复制内存,当写指针在读指针右边时,读取操作最多调用 1 次 memcpy 函数,而写入操作最多调用 2 次 memcpy 函数。当写指针在读指针左边时,读取操作最多调用两次 memcpy 函数,而写入操作最多调用 1 次 memcpy 函数。
    读写指针的变化

  2. (读写操作,版本一:函数内部 每次读/写一个字节,操作大量数据时效率很低)
    利用 取余运算 使得读/写指针在长度为 capacity 的连续内存空间上循环进行读/写操作

  3. (读写操作,版本二:使用 memcpy 函数复制内存 ,效率高)

  4. (读写操作,版本三:线程安全版本,可以使用互斥量并委托使用版本二的读写函数作简单实现)


目录
  1. 头文件 buffer.h
  2. 源文件 buffer.c
  3. 简单测试 test.c

1. 头文件 buffer.h
/* buffer.h */
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

struct buffer {
   
	/* 缓冲区容量,用于 malloc 申请内存空间 */
    size_t capacity;
    /* 累计所有写入操作实际写入的字节总数,其对 capacity 取余即为‘下一个写入位置’ */
    size_t byte_writed_count;
    /* 累计所有读取操作实际读取的字节总数,其对 capacity 取余即为‘下一个读取位置’ */
    size_t byte_readed_count;
    /* 指向实际缓冲区 */
    char *data;
};
/* 初始化缓冲区 buf,使用指定容量 capacity 申请内存空间 */
void buffer_init(struct buffer *buf, size_t capacity);
/* 版本一:读写函数,内部每次读写一个字节,
   将指针 chars 指向的长度为 len 的数据写入缓冲区 buf,
   返回值:实际写入的字节数,可能小于 len,当缓冲区可写空间不足时。 */
size_t buffer_write(struct buffer *buf, char *chars, size_t len);
/* 从缓冲区 buf 中读取长度为 len 的数据到指针 chars 指向的空间,
   返回值:实际读取的字节数,可能小于 len,当缓冲区没有足够的数据时。 */
size_t buffer_read(struct buffer *buf, char *chars, size_t len);
/* 版本二:读/写函数,内部使用 memcpy 函数进行内存复制,效率高 */
size_t buffer_write_by_memcpy(struct buffer *buf, char *chars, size_t len);
size_t buffer_read_by_memcpy(struct buffer *buf, char *chars, size_t len);

/* (待实现)版本三:线程安全版本
   (待实现)线程安全写,应与线程安全读 buffer_pread 配合使用 */
// size_t buffer_pwrite(struct buffer *buf, char *chars, size_t len);
/* (待实现)线程安全读,应与线程安全写 buffer_pwrite 配合使用 */
// size_t buffer_pread(struct buffer *buf, char *chars, size_t len);

/* 返回值:缓冲区中已缓存的(可读取)字节数 */
size_t buffer_available_read(struct buffer *buf);
/* 返回值:缓冲区可写入的字节数 */
size_t buffer_available_write(struct buffer *buf);
/* 返回值:缓冲区容量 capacity */
size_t buffer_capacity(struct buffer *buf);
/* 清空缓冲区,实际上仅仅重置读/写指针,缓冲区容量不变 */
void buffer_clear(struct buffer *buf);
/* 销毁/释放缓冲区,free 内存资源 */
void buffer_destroy(struct buffer *buf);
/* 简单错误日志输出至 stderr */
void errlog(const char *msg);
/* 简单日志输出至 stdout */
void infolog(const char *msg);
2. 源文件 buffer.c
/* buffer.c */
#include "buffer.h"

// 初始化缓冲区 buf,使用指定容量 capacity 申请内存空间
void buffer_init(struct buffer *buf, size_t capacity){
   
    if(buf == NULL || capacity <= 0){
   
        errlog("Invalid argument.");
        // error
        errno = EINVAL; // // Invalid argument
        exit(EXIT_FAILURE);
    }
	// 实际分配内存
    buf -> data = malloc(capacity);
    if(buf -> data == NULL){
   
        errlog("Cannot allocate memory: unknown error.");
        // error
        errno = ENOMEM;
        exit(EXIT_FAILURE);
    }
    buf -> capacity = capacity;
    buf -> byte_readed_count = 0;
    buf -> byte_writed_count = 0
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值