c++封装的用来存储key value pair的内存池类

问题描述:

1.c++封装的用来存储key, value对的内存池;

2.key 用字符串表达,value可以是各种类型。目前value只支持六种类型,后面会继续扩展;

3.key value pair 内存结构是:key length(1byte) | key string | value type | value |。注意中间|是为了表达区分而加上的,实际内存中并没有。注意当value 是char* 对象是,value前面四个字节表达它的长度;

4.这个类写的很仓促,目前呈现给大家的仅仅是一个雏形,后面会扩展一个使用的iterator class,使得使用更加简单化,更加直观;

程序代码:

#ifndef _KEY_VALUE_STREAM_H_
#define _KEY_VALUE_STREAM_H_

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>

/*
* stream buffer can be used to store key value pair
*
*/
class KeyValueStream
{
public:
	static const int INIT_BUFFER_SIZE = 1024;

	enum ValueType
	{
		CharType,
		IntType,
		floatType,
		doubleType,
		StringType,
		TimeType

	};

	typedef struct tagStreamBuffer
	{
		char*  buffer;
		size_t size;
		size_t used;

		tagStreamBuffer* prev;

		tagStreamBuffer():buffer(0),size(0),used(0), prev(0)
		{

		}

	}StreamBuffer, *pStreamBuffer;

	/*
	*
	*
	*/
	explicit KeyValueStream( size_t bytes = INIT_BUFFER_SIZE ):m_streamBuffer(0), m_pairCount(0),
		m_headStreamBuffer( new StreamBuffer)
	{
		Init( bytes );

		*m_headStreamBuffer = *m_streamBuffer;
	}

	/*
	*
	*
	*/
	~KeyValueStream()
	{
		Clear();
	}

	/*
	* Clear all buffer
	*
	*/
	void Clear()
	{
		pStreamBuffer cur = m_streamBuffer;
		pStreamBuffer prev = 0;
		while( cur )
		{
			prev = cur->prev;
			free( cur );
			cur = prev;
		}

		delete m_headStreamBuffer;
		m_headStreamBuffer = 0;
	}

	/*
	* Insert key number pair to buffer
	*
	*/
	void InsertNumber( const char* key, int number )
	{
		InsertKey( key );

		void* buf = GetBuffer( sizeof(int) + 1 );
		*(char*)buf = IntType;
		*(int*)((char*)buf + 1) = number;

		m_pairCount++;

	}

	/*
	*Insert key char pair to buffer
	*
	*/
	void InsertChar( const char* key, char c )
	{
		InsertKey( key );

		void* buf = GetBuffer( sizeof(char) + 1 );
		*(char*)buf = CharType;
		*(char*)((char*)buf + 1) = c;

		m_pairCount++;

	}

	/*
	*Insert key string pair to buffer
	*
	*/
	void InsertString( const char* key, const char* str )
	{
		InsertKey( key );

		size_t len = strlen( str );
		void* buf = GetBuffer( len + 4 + 1 );
		*(char*)buf = StringType;
		*(int*)((char*)buf + 1) = len;
		memcpy( (char*)buf + 5, str, len );

		m_pairCount++;
	}

	/*
	*Insert key time pair to buffer
	*
	*/
	void InsertTime( const char* key, time_t time )
	{
		InsertKey( key );

		void* buf = GetBuffer( sizeof(time_t) + 1 );
		*(char*)buf = TimeType;
		*(time_t*)((char*)buf + 1) = time;

		m_pairCount++;

	}

	/*
	*Insert key float pair to buffer
	*
	*/
	void InsertFloat( const char* key, float number )
	{
		InsertKey( key );

		void* buf = GetBuffer( sizeof(float) + 1 );
		*(char*)buf = floatType;
		*(float*)((char*)buf + 1) = number;

		m_pairCount++;

	}

	/*
	*Insert key double pair to buffer
	*
	*/
	void InsertDouble( const char* key, double number )
	{
		InsertKey( key );

		void* buf = GetBuffer( sizeof(double) + 1 );
		*(char*)buf = doubleType;
		*(double*)((char*)buf + 1) = number;

		m_pairCount++;

	}

	/*
	*get number value by key from buffer
	*
	*/
	int GetNumber( const char* key )
	{
		void* buf = GetValueByKey( key, strlen(key) );
		assert( *(char*)buf == IntType );

		return *(int*)((char*)buf + 1);
	}

	/*
	*get char value by key from buffer
	*
	*/
	char GetChar( const char* key )
	{
		void* buf = GetValueByKey( key, strlen(key) );
		assert( *(char*)buf == CharType );

		return *(char*)((char*)buf + 1);
	}

	/*
	*get string value by key from buffer
	*
	*/
	const char* GetString( const char* key )
	{
		void* buf = GetValueByKey( key, strlen(key) );
		assert( *(char*)buf == StringType );

		return (const char*)((char*)buf + 1 + 4);
	}

	/*
	*get time value by key from buffer
	*
	*/
	time_t GetTime( const char* key )
	{
		void* buf = GetValueByKey( key, strlen(key) );
		assert( *(char*)buf == TimeType );

		return *(time_t*)((char*)buf + 1);
	}

	/*
	*get float value by key from buffer
	*
	*/
	float GetFloat( const char* key )
	{
		void* buf = GetValueByKey( key, strlen(key) );
		assert( *(char*)buf == floatType );

		return *(float*)((char*)buf + 1);
	}

	/*
	*get double value by key from buffer
	*
	*/
	double GetDouble( const char* key )
	{
		void* buf = GetValueByKey( key, strlen(key) );
		assert( *(char*)buf == doubleType );

		return *(double*)((char*)buf + 1);
	}

	/*
	*implement get value by key
	*
	*/
	void* GetValueByKey( const char* key, size_t len )
	{
		char* buf = m_headStreamBuffer->buffer;
		char* endBuf = m_headStreamBuffer->buffer + m_streamBuffer->size;
		StreamBuffer* curStreamBuf = m_headStreamBuffer;

		while( buf )
		{
			if( buf >= endBuf )
			{
				buf = (char*)curStreamBuf->prev;
				curStreamBuf = curStreamBuf->prev;
			}

			if( *buf == len )
			{
				if( !strncmp( buf + 1, key, len ) )
				{
					return buf + 1 + *buf;
				}
			}
			//else
			{
				char keyLen = *buf;
				char type = *(char*)((char*)buf + 1 + keyLen);

				int valueLen = 0;
				switch( type )
				{
				case IntType:
					valueLen = sizeof(int) + 1;
					break;
				case CharType:
					valueLen = sizeof(char) + 1;
					break;
				case floatType:
					valueLen = sizeof(float) + 1;
					break;
				case doubleType:
					valueLen = sizeof(double) + 1;
					break;
				case TimeType:
					valueLen = sizeof(time_t) + 1;
					break;
				case StringType:
					valueLen = *(int*)((char*)buf + 1 + keyLen + 1);
					break;
				default:
					break;

				}

				buf += 1 + keyLen + valueLen;
				if( type == StringType)
					buf += 5;
			}
		}

		return NULL;

	}

private:

	/*
	* implement key to buffer
	*
	*/
	void InsertKey( const char* key )
	{
		size_t len = strlen(key);
		len++;

		void* buf = GetBuffer( len );
		*(char*)buf = len - 1;
		memcpy( (char*)buf + 1, key, len - 1 );
	}

	/*
	* allocate new buffer given size
	*
	*/
	void* GetBuffer( size_t bytes )
	{
		if( m_streamBuffer->used + bytes > m_streamBuffer->size )
		{
			Init( bytes );
		}

		void* ptr = m_streamBuffer->buffer;
		m_streamBuffer->buffer += bytes;
		m_streamBuffer->used += bytes;

		return ptr;
	}

	/*
	*init
	*/
	void Init( size_t bytes )
	{
		if( bytes < INIT_BUFFER_SIZE )
			bytes = INIT_BUFFER_SIZE;

		StreamBuffer* newBuf = (StreamBuffer*)malloc( sizeof(StreamBuffer) + bytes );
		assert( newBuf );
		newBuf->buffer = (char*)(newBuf + 1);
		newBuf->size = bytes;
		newBuf->used = 0;
		newBuf->prev = 0;

		newBuf->prev = m_streamBuffer;
		m_streamBuffer = newBuf;
	}

private:
	StreamBuffer* m_streamBuffer;
	size_t        m_pairCount;

	StreamBuffer* m_headStreamBuffer;

};

/*
* Test interface
*
*/
void TestKeyValueStream()
{
	KeyValueStream stream;
	stream.InsertChar( "char", ‘a‘ );
	stream.InsertNumber( "number", 1 );
	stream.InsertNumber( "number1", 2 );
	stream.InsertNumber( "number2", 3 );
	stream.InsertNumber( "number3", 4 );
	stream.InsertFloat( "float", 1.3 );
	stream.InsertDouble( "double", 1.33 );
	stream.InsertString( "string", "comefromechina");
	time_t timer;
	time(&timer);

	stream.InsertTime("time", timer );

	assert( stream.GetChar("char") == ‘a‘);
	assert( stream.GetNumber("number") == 1);
	assert( stream.GetNumber("number1") == 2);
	assert( stream.GetNumber("number2") == 3);
	assert( stream.GetNumber("number3") == 4);
	assert( (stream.GetFloat("float") - 1.3) < 0.0000001 );
	assert( (stream.GetDouble("double") - 1.33) < 0.000001);
	assert( !strncmp( stream.GetString("string"), "comefromechina", strlen("comefromechina")));
	assert( stream.GetTime("time") == timer );

}

#endif 

c++封装的用来存储key value pair的内存池类

时间: 2024-10-26 21:55:50

c++封装的用来存储key value pair的内存池类的相关文章

InnoDB 存储引擎的线程与内存池

InnoDB 存储引擎的线程与内存池 InnoDB体系结构如下: 后台线程: 1.后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据: 2.另外,将以修改的数据文件刷新到磁盘文件: 3.同时,保证在数据库发生异常的情况下,InnoDB能恢复到正常运行状态. 内存池:InnoDB有多个内存块,这些内存块组成了一个大的内存池.这些内存块包括有:缓冲池(innodb_buffer_pool)和日志缓冲(log_buffer)以及额外内存池(innodb_addtional

一个依靠STL vector的接口进行申请和回收管理的内存池类( c++ 封装)

其他出现两次,只有一个出现一次的那道题我就不更了,直接抑或,最后的结果就是那个数.为什么可以这样做呢?因为一个32位int,如果所有数都出现了两次,那么为1的那些位统计的个数一定是2的倍数,抑或之后全变成0.一个数出现了一次,它为1的那些位上,1的个数必定是奇数,抑或之后一定还是1. 我之前知道出现两次这个题的解法,但是理解的不够深,以为抑或是关键,其实不是,出现了偶数次才是关键.理解了这点,推广到出现3次上,如果所有的出现了三次,那么为1的那些位1的个数一定是三的倍数,那如果有一个数出现了一次

用 LFS 文件系统存储 key value

有些人问 LFS 能不能存储 key value? 单线程写的时候是可以的,多线程读也是可以的.(嗯,可以考虑在未来增加并发写的功能.) 那么如何做呢?其实 key value 是一个哈希结构,正好,LFS 里支持哈希索引. 支持 key value 代表着,也可以通过文件名读写文件(只是没有文件夹的概念,但文件名依然可以是一个包含文件夹的路径名). 注:下面的方法可以封装成更通用的接口来使用,这里这么做是为了让大家明白如何做 //set(key, value) Socket con = LFS

深度剖析数据在内存中的存储2——浮点数数在内存中的存储

根据国际标准IEEE:任意一个二进制浮点数V可以表示为下面形式:(-1)^SM2^E:(-1)^S表示符号位,当S为0,V为正数:当S为1,V为负数.由其物理结构决定了,浮点数为有符号数.M为有效数字,大于等于1,小于2.2^E表示指数位.eg:5=>0101=>(-1)^01.012^2. S=0,M=1.01,E=2规定:对于32位的浮点数(单精度浮点数存储),最高1位是符号位(S),接着的8位为指数位(E),剩下的23位是有效数字位(M),不满23位后面补0.对于64位的浮点数(双精度浮

捕获异常、存sd卡、封装请求头体、加密map值、网络工具类、生成Json、Https协议、传log日志到服务器、app崩溃友好重启

点击打开链接,免积分下载 在集成了统计SDK(友盟统计,百度统计等)之后,有一个非常有利于测试的功能:错误分析!此功能能够将程序在运行中碰到的崩溃(runtimeException)问题反馈到服务器,帮助开发者改善产品,多适配机器.然而在公司android开发中不集成这些SDK,那应该怎么实现这样的功能呢?下面让我们来看下如何使用UncaughtExceptionHandler来捕获异常. 在Android开发中,常常会出现uncheched Exception 导致程序的crash,为了提供良

c语言 变量的存储类别以及对应的内存分配?

<h4><strong>1.变量的存储类别</strong></h4>从变量值存在的角度来分,可以分为静态存储方式和动态存储方式.所谓静态存储方式指在程序运行期间由系统分配固定的存储空间的方式(<strong>程序开始执行时分配,在程序完毕时释放,在程序过程中它们占据国定的存储单元,而不是动态分配和释放</strong>).而动态存储方式在运行期间根据需要进行动态存储方式(<strong>在程序过程中申请和释放的一些空间&

存储链接、类别、内存管理术语

C语言最基本的术语:作用域:变量可访问的范围.它直接关系到标识符所能运行代码块的运行范围.如:我们在main函数前面定义了一个变量,那么这个变量就具有文件作用域,它的访问范围为代码定义开始到文件结尾.也就是说具有文件作用域. 块作用域:从代码申请开始到这个函数块结束. 函数作用域:只要goto标签所能访问的地方,就是函数标识符在函数内部,到函数结束标识符能够访问. 翻译单元:当一个头文件包含另一个头文件时,编译器会将头文件替换为#include指令,编译器文件和所有头文件都看成是包含信息的单独文

关于Docker默认存储位置及Docker系统默认池存储、卷存储限制空间修改

一.Docker默认存储位置 Docker默认存储位置在/var/lib/docker,通过命令 docker info | grep "Docker Root Dir"进行查看.有时候因为磁盘空间的问题,我们需要对其进行修改,下面有几种方法来解决docker默认存储位置的问题: 直接将数据盘挂载到/var/lib/docker目录上: 基于软连接的方式进行修改:数据盘挂载在/data目录下面,我们这样操作 mv /var/lib/docker /data/dockerln &

存储类别、链接和内存管理

C变量作用域:块作用域.函数作用域.函数原型作用域.文件作用域. C变量的3种链接属性:外部链接.内部链接.无链接.前三种作用域变量都是无链接(仅在作用域内被使用):文件作用域变量根据定义形式来看,如果是static则为内部链接(仅在本文件内被使用),否则为外部链接(能被多个文件共享). 存储期:静态存储期(文件作用域变量,存在于整个程序的执行时间内) 线程存储期(用于并发程序设计,从被声明到线程结束) 自动存储期(块作用域变量,从进入块到块结束:VLA变长数组略有不同,是从被声明到块结束) 综