From 76dd93051e7e78916c8dde97804c7e2a632acc81 Mon Sep 17 00:00:00 2001 From: wyy Date: Thu, 5 Jun 2014 00:48:49 +0800 Subject: [PATCH] add localvector --- src/DictTrie.hpp | 2 +- src/Limonp/LocalVector.hpp | 173 +++++++++++++++++++++++++++++++++++++ src/Limonp/StringUtil.hpp | 18 ++-- src/TransCode.hpp | 3 +- src/Trie.hpp | 18 ++-- 5 files changed, 197 insertions(+), 17 deletions(-) create mode 100644 src/Limonp/LocalVector.hpp diff --git a/src/DictTrie.hpp b/src/DictTrie.hpp index 9f81adc..17af029 100644 --- a/src/DictTrie.hpp +++ b/src/DictTrie.hpp @@ -44,7 +44,7 @@ namespace CppJieba class DictTrie: public InitOnOff { public: - typedef Trie TrieType; + typedef Trie, vector > TrieType; private: vector _nodeInfos; TrieType * _trie; diff --git a/src/Limonp/LocalVector.hpp b/src/Limonp/LocalVector.hpp new file mode 100644 index 0000000..93872bf --- /dev/null +++ b/src/Limonp/LocalVector.hpp @@ -0,0 +1,173 @@ +#ifndef LIMONP_LOCAL_VECTOR_HPP +#define LIMONP_LOCAL_VECTOR_HPP + +#include +#include +#include +#include + +namespace Limonp +{ + using namespace std; + const size_t LOCAL_VECTOR_BUFFER_SIZE = 32; + template + class LocalVector + { + public: + typedef const T* const_iterator ; + typedef T value_type; + typedef size_t size_type; + private: + T _buffer[LOCAL_VECTOR_BUFFER_SIZE]; + T * _ptr; + size_t _size; + size_t _capacity; + public: + LocalVector() + { + _init(); + }; + LocalVector(const LocalVector& vec) + { + _init(); + *this = vec; + } + LocalVector(const_iterator begin, const_iterator end) // TODO: make it faster + { + _init(); + while(begin != end) + { + push_back(*begin++); + } + } + LocalVector(size_t size, const T& t) // TODO: make it faster + { + _init(); + while(size--) + { + push_back(t); + } + } + ~LocalVector() + { + if(_ptr != _buffer) + { + free(_ptr); + } + }; + public: + LocalVector& operator = (const LocalVector& vec) + { + clear(); + _size = vec.size(); + _capacity = vec.capacity(); + if(vec._buffer == vec._ptr) + { + memcpy(_buffer, vec._buffer, sizeof(T) * _size); + _ptr = _buffer; + } + else + { + _ptr = (T*) malloc(vec.capacity() * sizeof(T)); + assert(_ptr); + memcpy(_ptr, vec._ptr, vec.size() * sizeof(T)); + } + return *this; + } + private: + void _init() + { + _ptr = _buffer; + _size = 0; + _capacity = LOCAL_VECTOR_BUFFER_SIZE; + } + public: + T& operator [] (size_t i) + { + return _ptr[i]; + } + const T& operator [] (size_t i) const + { + return _ptr[i]; + } + void push_back(const T& t) + { + if(!full()) + { + _ptr[_size++] = t; + return ; + } + assert(_capacity); + reserve(_capacity * 2); + _ptr[_size ++ ] = t; + } + void reserve(size_t size) + { + if(size <= _capacity) + { + return; + } + T * next = (T*)malloc(sizeof(T) * size); + assert(next); + T * old = _ptr; + _ptr = next; + memcpy(_ptr, old, sizeof(T) * _capacity); + _capacity = size; + if(old != _buffer) + { + free(old); + } + } + bool full() const + { + return size() == capacity(); + } + bool empty() const + { + return 0 == size(); + } + size_t size() const + { + return _size; + } + size_t capacity() const + { + return _capacity; + } + const_iterator begin() const + { + return _ptr; + } + const_iterator end() const + { + return _ptr + _size; + } + void clear() + { + if(_ptr != _buffer) + { + free(_ptr); + } + _init(); + } + }; + + template + ostream & operator << (ostream& os, const LocalVector& vec) + { + if(vec.empty()) + { + return os << "[]"; + } + os<<"[\""<& vec) + template + bool utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) { if(!str) { @@ -247,12 +248,14 @@ namespace Limonp } return true; } - inline bool utf8ToUnicode(const string& str, vector& vec) + template + bool utf8ToUnicode(const string& str, Uint16Container& vec) { return utf8ToUnicode(str.c_str(), str.size(), vec); } - inline bool unicodeToUtf8(vector::const_iterator begin, vector::const_iterator end, string& res) + template + bool unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) { if(begin >= end) { @@ -284,7 +287,8 @@ namespace Limonp } - inline bool gbkTrans(const char* const str, size_t len, vector& vec) + template + bool gbkTrans(const char* const str, size_t len, Uint16Container& vec) { vec.clear(); if(!str) @@ -316,12 +320,14 @@ namespace Limonp return true; } - inline bool gbkTrans(const string& str, vector& vec) + template + bool gbkTrans(const string& str, Uint16Container& vec) { return gbkTrans(str.c_str(), str.size(), vec); } - inline bool gbkTrans(vector::const_iterator begin, vector::const_iterator end, string& res) + template + bool gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) { if(begin >= end) { diff --git a/src/TransCode.hpp b/src/TransCode.hpp index 2f983b4..a9a4d11 100644 --- a/src/TransCode.hpp +++ b/src/TransCode.hpp @@ -7,13 +7,14 @@ #include "Limonp/StringUtil.hpp" +#include "Limonp/LocalVector.hpp" namespace CppJieba { using namespace Limonp; typedef uint16_t UnicodeValueType; - typedef std::vector Unicode; + typedef Limonp::LocalVector Unicode; namespace TransCode { inline bool decode(const string& str, Unicode& res) diff --git a/src/Trie.hpp b/src/Trie.hpp index 4bda075..dbaf989 100644 --- a/src/Trie.hpp +++ b/src/Trie.hpp @@ -17,7 +17,7 @@ namespace CppJieba const ValueType * ptValue; }; - template + template , class KeysContainerType = vector, class ValueContainerType = vector > class Trie { public: @@ -25,7 +25,7 @@ namespace CppJieba private: TrieNodeType* _root; public: - Trie(const vector >& keys, const vector& valuePointers) + Trie(const KeysContainerType& keys, const ValueContainerType& valuePointers) { _root = new TrieNodeType; _root->ptKeyMap = NULL; @@ -41,11 +41,11 @@ namespace CppJieba } } public: - const ValueType* find(typename vector::const_iterator begin, typename vector::const_iterator end) const + const ValueType* find(typename KeyContainerType::const_iterator begin, typename KeyContainerType::const_iterator end) const { typename TrieNodeType::KeyMapType::const_iterator citer; const TrieNodeType* ptNode = _root; - for(typename vector::const_iterator it = begin; it != end; it++) + for(typename KeyContainerType::const_iterator it = begin; it != end; it++) { assert(ptNode); if(NULL == ptNode->ptKeyMap || ptNode->ptKeyMap->end() == (citer = ptNode->ptKeyMap->find(*it))) @@ -56,12 +56,12 @@ namespace CppJieba } return ptNode->ptValue; } - bool find(typename vector::const_iterator begin, typename vector ::const_iterator end, map::size_type, const ValueType* >& ordererMap, size_t offset = 0) const + bool find(typename KeyContainerType::const_iterator begin, typename KeyContainerType::const_iterator end, map& ordererMap, size_t offset = 0) const { const TrieNodeType * ptNode = _root; typename TrieNodeType::KeyMapType::const_iterator citer; ordererMap.clear(); - for(typename vector::const_iterator itr = begin; itr != end ; itr++) + for(typename KeyContainerType::const_iterator itr = begin; itr != end ; itr++) { assert(ptNode); if(NULL == ptNode->ptKeyMap || ptNode->ptKeyMap->end() == (citer = ptNode->ptKeyMap->find(*itr))) @@ -77,7 +77,7 @@ namespace CppJieba return ordererMap.size(); } private: - void _createTrie(const vector >& keys, const vector& valuePointers) + void _createTrie(const KeysContainerType& keys, const ValueContainerType& valuePointers) { if(valuePointers.empty() || keys.empty()) { @@ -91,13 +91,13 @@ namespace CppJieba } } private: - void _insertNode(const vector& key, const ValueType* ptValue) + void _insertNode(const KeyContainerType& key, const ValueType* ptValue) { TrieNodeType* ptNode = _root; typename TrieNodeType::KeyMapType::const_iterator kmIter; - for(typename vector::const_iterator citer = key.begin(); citer != key.end(); citer++) + for(typename KeyContainerType::const_iterator citer = key.begin(); citer != key.end(); citer++) { if(NULL == ptNode->ptKeyMap) {