前面的硬哈希
我觉得非常棒!
看微信文章 说的很好 它有痛点:在插入和删除的时候麻烦!二叉树因运而生!
https://mp.weixin.qq.com/s/ZT_dAmN4N3gVvvxY05Azhg
https://mp.weixin.qq.com/s/ZkXbIKWU9ldFKuP4JVBsSw 神文 !
其实我的业务情况硬哈希这样很好的 这里就是练笔!
我做一个1K的内存保存数据 也就是掉电保存flash是1K 本地SRAM也是1k
我用malloc把一个一个的节点做出来 每次上电就可以flash->sram 这个样子一个树 就出来了!
本文准备malloc部分
++++之前已经有了MALLOC模块 需要一个池子+一个管理表 我计划按需分配 不要表了!就是池子!
++++我可以flash--池子完成对应 一上电全部读出来 整个树就好了 也可以爱护flash 只保持数据 每次上电我就创建树
#include "gtreemalloc.h"
#include "stdio.h" //printf
//内存池(32字节对齐)
__align(32) u8 mem1base[MEM1_MAX_SIZE]__attribute__((at(0x10000800))); //SRAM内存池
//内存管理表
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE] __attribute__((at(0x10000800+MEM1_MAX_SIZE))); //SRAM内存池MAP
//内存管理参数//对接宏定义
const u32 memtblsize = MEM1_ALLOC_TABLE_SIZE; //内存表大小[1024/32]
const u32 memblksize = MEM1_BLOCK_SIZE; //内存分块大小
const u32 memsize = MEM1_MAX_SIZE; //内存总大小
//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
my_mem_init, //【函数】内存初始化
my_mem_perused, //【函数】内存使用率
mem1base, //【数组】内存池
mem1mapbase, //【数组】内存表
};
void mymemcpy(void *des,void *src,u32 n)
{
u8 *xdes=des;
u8 *xsrc=src;
while(n--)*xdes++=*xsrc++;
}
void mymemset(void *s,u8 c,u32 count)
{
u8 *xs = s;
while(count--)*xs++=c;
}
//内存管理初始化
void my_mem_init(void)
{
mymemset(mallco_dev.membase, 0,memsize); //内存池所有数据清零【意义不大可以不要】
mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零 【WHY*2?因为是自己写的memset是按字节赋值的U8而数组是U16要*2】
}
//获取内存使用率
//返回值:使用率(0~100)
u8 my_mem_perused(void)
{
u32 used=0;
u32 i;
for(i=0;i<memtblsize;i++)
{
if(mallco_dev.memmap[i])used++;
}
return (used*100)/(memtblsize);
}
//内存分配(内部调用)
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
u32 my_mem_malloc(u32 size)
{
signed long offset=0;
u32 nmemb; //需要的内存块数
u32 cmemb=0;//连续空内存块数
u32 i;
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/memblksize; //获取需要分配的连续内存块数
if(size%memblksize){printf("不是整数倍 需要再次设计\r\n");nmemb++;}
for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区
{
if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
mallco_dev.memmap[offset+i]=nmemb;
}
return (offset*memblksize);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
u8 my_mem_free(u32 offset)
{
int i;
if(offset<memsize)//偏移在内存池内.
{
int index=offset/memblksize; //偏移所在内存块号码
int nmemb=mallco_dev.memmap[index]; //内存块数量
for(i=0;i<nmemb;i++) //内存块清零
{
mallco_dev.memmap[index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
//释放内存(外部调用)
//ptr:内存首地址
void myfree(void *ptr)
{
u32 offset;
if(ptr==NULL)return;//地址为0.
offset=(u32)ptr-(u32)mallco_dev.membase;
my_mem_free(offset); //释放内存
}
//分配内存(外部调用)
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u32 size)
{
u32 offset;
offset=my_mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)mallco_dev.membase+offset);
}
u8 used=0;
u8 *p=0;
void MALLOCTEST(void)
{
printf("内存管理 \r\n \
一个池子在%p 后面连续 %d 个字节做为池子 \r\n \
一个表紧跟着池子在%p 后面连续 %d 个字节挨个对应池子的一片一片管理 \r\n \
",mem1base,MEM1_MAX_SIZE,mem1mapbase,MEM1_ALLOC_TABLE_SIZE);
mallco_dev.init();
p=mymalloc(20);//申请20字节
mymemset(p,0,20);
mymemcpy(p,"HELLO",5);
// HELLO48-45-4C-4C-4F
printf("%s",p);
for(char i=0;i<5;i++)printf("%02X-",p[i]);printf("\b");
used = mallco_dev.perused();
myfree(p); //释放内存
}
#ifndef __GTREEMALLOC_H
#define __GTREEMALLOC_H
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
#ifndef NULL
#define NULL 0
#endif
//mem1内存参数设定.mem1完全处于内部SRAM里面.
#define MEM1_BLOCK_SIZE 32 //内存块大小为32字节
#define MEM1_BLOCK_NUM 1 //约定分配多少K内存来做MALLOC功能
#define MEM1_MAX_SIZE MEM1_BLOCK_NUM*1024 //最大管理内存 40K
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //内存表大小
//内存管理控制器
struct _m_mallco_dev
{
void (*init)(void); //【函数】初始化
u8 (*perused)(void); //【函数】内存使用率
u8 *membase; //【不是函数是一个数组指针需要指向实体】内存池 真正的内存
u16 *memmap; //【不是函数是一个数组指针需要指向实体】内存表 管理上面的池子
};
extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义
void mymemset(void *s,u8 c,u32 count); //设置内存
void mymemcpy(void *des,void *src,u32 n);//复制内存
void my_mem_init(void); //内存管理初始化函数(外/内部调用)
u32 my_mem_malloc(u32 size); //内存分配(内部调用)
u8 my_mem_free(u32 offset); //内存释放(内部调用)
u8 my_mem_perused(void); //获得内存使用率(外/内部调用)
//用户调用函数
void myfree(void *ptr); //内存释放(外部调用)
void *mymalloc(u32 size); //内存分配(外部调用)
void MALLOCTEST(void);
#endif