首页 > 代码库 > c++封装的用来存储key value pair的内存池类

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