mirror of
https://gitee.com/drabel/LibQQt.git
synced 2025-01-04 10:18:44 +08:00
a buged ordered map.
This commit is contained in:
parent
ac2c5ebd97
commit
85207b7c70
@ -62,7 +62,7 @@ void QQtDictionary::setChild ( const QList<QQtDictionary>& list )
|
||||
m_list = list;
|
||||
}
|
||||
|
||||
void QQtDictionary::setChild ( const QMap<QString, QQtDictionary>& map )
|
||||
void QQtDictionary::setChild ( const QQtOrderedMap<QString, QQtDictionary>& map )
|
||||
{
|
||||
m_type = DictMap;
|
||||
m_map = map;
|
||||
@ -359,7 +359,7 @@ QQtDictionary& QQtDictionary::operator [] ( const QString& key )
|
||||
return m_map.operator [] ( key );
|
||||
}
|
||||
|
||||
QQtDictionary& QQtDictionary::operator = ( const QMap<QString, QQtDictionary>& map )
|
||||
QQtDictionary& QQtDictionary::operator = ( const QQtOrderedMap<QString, QQtDictionary>& map )
|
||||
{
|
||||
m_type = DictMap;
|
||||
m_map = map;
|
||||
@ -533,13 +533,28 @@ void QQtDictionary::parseDictionaryToJsonValue ( const QQtDictionary& node, QJso
|
||||
QList<QQtDictionary>& l = node.getList();
|
||||
QJsonValue value;
|
||||
parseDictionaryToJsonValue ( l[i], value );
|
||||
array.append ( value );
|
||||
//array.append ( value );
|
||||
array.push_back ( value );
|
||||
}
|
||||
result = array;
|
||||
break;
|
||||
}
|
||||
case DictMap:
|
||||
{
|
||||
//"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
|
||||
QJsonObject object;
|
||||
for ( QQtOrderedMap<QString, QQtDictionary>::Iterator itor = node.getMap().begin(); itor != node.getMap().end(); itor++ )
|
||||
{
|
||||
//QQtOrderedMap<QString, QQtDictionary>& m = node.getMap();
|
||||
const QString& key = itor.key();
|
||||
const QQtDictionary& srcvalue = itor.value();
|
||||
QJsonValue value;
|
||||
parseDictionaryToJsonValue ( srcvalue, value );
|
||||
object.insert ( key, value );
|
||||
}
|
||||
result = object;
|
||||
break;
|
||||
}
|
||||
case DictMax:
|
||||
default:
|
||||
break;
|
||||
@ -557,9 +572,9 @@ bool QQtDictionary::operator == ( const QQtDictionary& other ) const
|
||||
return false;
|
||||
}
|
||||
|
||||
QMap<QString, QQtDictionary>& QQtDictionary::getMap() const
|
||||
QQtOrderedMap<QString, QQtDictionary>& QQtDictionary::getMap() const
|
||||
{
|
||||
return ( QMap<QString, QQtDictionary>& ) m_map;
|
||||
return ( QQtOrderedMap<QString, QQtDictionary>& ) m_map;
|
||||
}
|
||||
|
||||
QList<QQtDictionary>& QQtDictionary::getList() const
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <qqtorderedmap.h>
|
||||
#include <qqtcore.h>
|
||||
#include <qqt-local.h>
|
||||
|
||||
@ -12,13 +12,13 @@
|
||||
* 遍历时
|
||||
*/
|
||||
class QQtDictionary;
|
||||
typedef QMap<QString, QQtDictionary> QQtDictionaryMap;
|
||||
typedef QMapIterator<QString, QQtDictionary> QQtDictionaryMapIterator;
|
||||
typedef QMutableMapIterator<QString, QQtDictionary> QQtDictionaryMutableMapIterator;
|
||||
typedef QQtOrderedMap<QString, QQtDictionary> QQtDictionaryMap;
|
||||
typedef QQtOrderedMap<QString, QQtDictionary>::Iterator QQtDictionaryMapIterator;
|
||||
typedef QQtOrderedMap<QString, QQtDictionary>::ConstIterator QQtDictionaryMapConstIterator;
|
||||
|
||||
typedef QList<QQtDictionary> QQtDictionaryList;
|
||||
typedef QListIterator<QQtDictionary> QQtDictionaryListIterator;
|
||||
typedef QMutableListIterator<QQtDictionary> QQtDictionaryMutableListIterator;
|
||||
typedef QList<QQtDictionary>::Iterator QQtDictionaryListIterator;
|
||||
typedef QList<QQtDictionary>::ConstIterator QQtDictionaryListConstIterator;
|
||||
|
||||
/**
|
||||
* @brief The QQtDictionary class
|
||||
@ -30,8 +30,8 @@ typedef QMutableListIterator<QQtDictionary> QQtDictionaryMutableListIterator;
|
||||
* 接受嵌套访问 操作方式 dict["cccc"][0]["eeeee"]
|
||||
* 通过重载函数来实现类型的变化,不建议使用中更改类型。
|
||||
* 比json和xml的数据结构要庞大。toJson toXML fromJson fromXML
|
||||
* QVariant 不能直接获取到真实数据,改变必须使用临时变量。
|
||||
* 而且,接口设计也不够灵活,存入和取出都不太方便。
|
||||
* QVariant 不能直接获取到真实数据,改变必须使用临时变量,而且,接口设计也不够灵活,存入和取出都不太方便。
|
||||
* QQtDictionary封装了QVariant,实现直接操作真实数据。提供大量操作符。存取数据方便快捷,类型多样。
|
||||
*/
|
||||
class QQTSHARED_EXPORT QQtDictionary
|
||||
{
|
||||
@ -72,7 +72,7 @@ public:
|
||||
/*获取全部数据*/
|
||||
/*获取当前字典的全部数据*/
|
||||
/*保存为[key]=[value]的*/
|
||||
QMap<QString, QQtDictionary>& getMap() const;
|
||||
QQtOrderedMap<QString, QQtDictionary>& getMap() const;
|
||||
/*保存为index=[value]*/
|
||||
QList<QQtDictionary>& getList() const ;
|
||||
|
||||
@ -106,7 +106,7 @@ public:
|
||||
/*whole value list*/
|
||||
void setChild ( const QList<QQtDictionary>& list );
|
||||
/*whole value map*/
|
||||
void setChild ( const QMap<QString, QQtDictionary>& map );
|
||||
void setChild ( const QQtOrderedMap<QString, QQtDictionary>& map );
|
||||
|
||||
/*自己本身没有孩子,添加一个个的孩子*/
|
||||
/*index = int*/
|
||||
@ -145,7 +145,7 @@ public:
|
||||
QQtDictionary& operator [] ( const QString& key );
|
||||
const QQtDictionary operator[] ( const QString& key ) const;
|
||||
|
||||
QQtDictionary& operator = ( const QMap<QString, QQtDictionary>& map );
|
||||
QQtDictionary& operator = ( const QQtOrderedMap<QString, QQtDictionary>& map );
|
||||
QQtDictionary& operator = ( const QList<QQtDictionary>& list );
|
||||
QQtDictionary& operator = ( const QQtDictionary& other );
|
||||
QQtDictionary& operator = ( const QVariant& value );
|
||||
@ -189,7 +189,7 @@ private:
|
||||
QList<QQtDictionary> m_list; //[index]
|
||||
/*不是叶子映射,是个子字典,是个叶子,是个叶子的值组合*/
|
||||
/*映射保存在这里,QStirng可以升级为QVariant*/
|
||||
QMap<QString, QQtDictionary> m_map;
|
||||
QQtOrderedMap<QString, QQtDictionary> m_map;
|
||||
/*是个列表和子字典,这是错误的,不可能的*/
|
||||
};
|
||||
|
||||
|
387
src/core/qqtorderedmap.cpp
Normal file
387
src/core/qqtorderedmap.cpp
Normal file
@ -0,0 +1,387 @@
|
||||
#include <qqtorderedmap.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef QT_QMAP_DEBUG
|
||||
# include <qstring.h>
|
||||
# include <qvector.h>
|
||||
#endif
|
||||
|
||||
const QQtOrderedMapDataBase QQtOrderedMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, 0, 0 }, 0 };
|
||||
|
||||
const QQtOrderedMapNodeBase* QQtOrderedMapNodeBase::nextNode() const
|
||||
{
|
||||
const QQtOrderedMapNodeBase* n = this;
|
||||
if ( n->right )
|
||||
{
|
||||
n = n->right;
|
||||
while ( n->left )
|
||||
n = n->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QQtOrderedMapNodeBase* y = n->parent();
|
||||
while ( y && n == y->right )
|
||||
{
|
||||
n = y;
|
||||
y = n->parent();
|
||||
}
|
||||
n = y;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const QQtOrderedMapNodeBase* QQtOrderedMapNodeBase::previousNode() const
|
||||
{
|
||||
const QQtOrderedMapNodeBase* n = this;
|
||||
if ( n->left )
|
||||
{
|
||||
n = n->left;
|
||||
while ( n->right )
|
||||
n = n->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QQtOrderedMapNodeBase* y = n->parent();
|
||||
while ( y && n == y->left )
|
||||
{
|
||||
n = y;
|
||||
y = n->parent();
|
||||
}
|
||||
n = y;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void QQtOrderedMapDataBase::rotateLeft ( QQtOrderedMapNodeBase* x )
|
||||
{
|
||||
QQtOrderedMapNodeBase*& root = header.left;
|
||||
QQtOrderedMapNodeBase* y = x->right;
|
||||
x->right = y->left;
|
||||
if ( y->left != 0 )
|
||||
y->left->setParent ( x );
|
||||
y->setParent ( x->parent() );
|
||||
if ( x == root )
|
||||
root = y;
|
||||
else if ( x == x->parent()->left )
|
||||
x->parent()->left = y;
|
||||
else
|
||||
x->parent()->right = y;
|
||||
y->left = x;
|
||||
x->setParent ( y );
|
||||
}
|
||||
|
||||
|
||||
void QQtOrderedMapDataBase::rotateRight ( QQtOrderedMapNodeBase* x )
|
||||
{
|
||||
QQtOrderedMapNodeBase*& root = header.left;
|
||||
QQtOrderedMapNodeBase* y = x->left;
|
||||
x->left = y->right;
|
||||
if ( y->right != 0 )
|
||||
y->right->setParent ( x );
|
||||
y->setParent ( x->parent() );
|
||||
if ( x == root )
|
||||
root = y;
|
||||
else if ( x == x->parent()->right )
|
||||
x->parent()->right = y;
|
||||
else
|
||||
x->parent()->left = y;
|
||||
y->right = x;
|
||||
x->setParent ( y );
|
||||
}
|
||||
|
||||
|
||||
void QQtOrderedMapDataBase::rebalance ( QQtOrderedMapNodeBase* x )
|
||||
{
|
||||
QQtOrderedMapNodeBase*& root = header.left;
|
||||
x->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
while ( x != root && x->parent()->color() == QQtOrderedMapNodeBase::Red )
|
||||
{
|
||||
if ( x->parent() == x->parent()->parent()->left )
|
||||
{
|
||||
QQtOrderedMapNodeBase* y = x->parent()->parent()->right;
|
||||
if ( y && y->color() == QQtOrderedMapNodeBase::Red )
|
||||
{
|
||||
x->parent()->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
y->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
x->parent()->parent()->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
x = x->parent()->parent();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( x == x->parent()->right )
|
||||
{
|
||||
x = x->parent();
|
||||
rotateLeft ( x );
|
||||
}
|
||||
x->parent()->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
x->parent()->parent()->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
rotateRight ( x->parent()->parent() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QQtOrderedMapNodeBase* y = x->parent()->parent()->left;
|
||||
if ( y && y->color() == QQtOrderedMapNodeBase::Red )
|
||||
{
|
||||
x->parent()->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
y->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
x->parent()->parent()->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
x = x->parent()->parent();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( x == x->parent()->left )
|
||||
{
|
||||
x = x->parent();
|
||||
rotateRight ( x );
|
||||
}
|
||||
x->parent()->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
x->parent()->parent()->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
rotateLeft ( x->parent()->parent() );
|
||||
}
|
||||
}
|
||||
}
|
||||
root->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
}
|
||||
|
||||
void QQtOrderedMapDataBase::freeNodeAndRebalance ( QQtOrderedMapNodeBase* z )
|
||||
{
|
||||
QQtOrderedMapNodeBase*& root = header.left;
|
||||
QQtOrderedMapNodeBase* y = z;
|
||||
QQtOrderedMapNodeBase* x;
|
||||
QQtOrderedMapNodeBase* x_parent;
|
||||
if ( y->left == 0 )
|
||||
{
|
||||
x = y->right;
|
||||
if ( y == mostLeftNode )
|
||||
{
|
||||
if ( x )
|
||||
mostLeftNode = x; // It cannot have (left) children due the red black invariant.
|
||||
else
|
||||
mostLeftNode = y->parent();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( y->right == 0 )
|
||||
{
|
||||
x = y->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = y->right;
|
||||
while ( y->left != 0 )
|
||||
y = y->left;
|
||||
x = y->right;
|
||||
}
|
||||
}
|
||||
if ( y != z )
|
||||
{
|
||||
z->left->setParent ( y );
|
||||
y->left = z->left;
|
||||
if ( y != z->right )
|
||||
{
|
||||
x_parent = y->parent();
|
||||
if ( x )
|
||||
x->setParent ( y->parent() );
|
||||
y->parent()->left = x;
|
||||
y->right = z->right;
|
||||
z->right->setParent ( y );
|
||||
}
|
||||
else
|
||||
{
|
||||
x_parent = y;
|
||||
}
|
||||
if ( root == z )
|
||||
root = y;
|
||||
else if ( z->parent()->left == z )
|
||||
z->parent()->left = y;
|
||||
else
|
||||
z->parent()->right = y;
|
||||
y->setParent ( z->parent() );
|
||||
// Swap the colors
|
||||
QQtOrderedMapNodeBase::Color c = y->color();
|
||||
y->setColor ( z->color() );
|
||||
z->setColor ( c );
|
||||
y = z;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_parent = y->parent();
|
||||
if ( x )
|
||||
x->setParent ( y->parent() );
|
||||
if ( root == z )
|
||||
root = x;
|
||||
else if ( z->parent()->left == z )
|
||||
z->parent()->left = x;
|
||||
else
|
||||
z->parent()->right = x;
|
||||
}
|
||||
if ( y->color() != QQtOrderedMapNodeBase::Red )
|
||||
{
|
||||
while ( x != root && ( x == 0 || x->color() == QQtOrderedMapNodeBase::Black ) )
|
||||
{
|
||||
if ( x == x_parent->left )
|
||||
{
|
||||
QQtOrderedMapNodeBase* w = x_parent->right;
|
||||
if ( w->color() == QQtOrderedMapNodeBase::Red )
|
||||
{
|
||||
w->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
x_parent->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
rotateLeft ( x_parent );
|
||||
w = x_parent->right;
|
||||
}
|
||||
if ( ( w->left == 0 || w->left->color() == QQtOrderedMapNodeBase::Black ) &&
|
||||
( w->right == 0 || w->right->color() == QQtOrderedMapNodeBase::Black ) )
|
||||
{
|
||||
w->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
x = x_parent;
|
||||
x_parent = x_parent->parent();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( w->right == 0 || w->right->color() == QQtOrderedMapNodeBase::Black )
|
||||
{
|
||||
if ( w->left )
|
||||
w->left->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
w->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
rotateRight ( w );
|
||||
w = x_parent->right;
|
||||
}
|
||||
w->setColor ( x_parent->color() );
|
||||
x_parent->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
if ( w->right )
|
||||
w->right->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
rotateLeft ( x_parent );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QQtOrderedMapNodeBase* w = x_parent->left;
|
||||
if ( w->color() == QQtOrderedMapNodeBase::Red )
|
||||
{
|
||||
w->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
x_parent->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
rotateRight ( x_parent );
|
||||
w = x_parent->left;
|
||||
}
|
||||
if ( ( w->right == 0 || w->right->color() == QQtOrderedMapNodeBase::Black ) &&
|
||||
( w->left == 0 || w->left->color() == QQtOrderedMapNodeBase::Black ) )
|
||||
{
|
||||
w->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
x = x_parent;
|
||||
x_parent = x_parent->parent();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( w->left == 0 || w->left->color() == QQtOrderedMapNodeBase::Black )
|
||||
{
|
||||
if ( w->right )
|
||||
w->right->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
w->setColor ( QQtOrderedMapNodeBase::Red );
|
||||
rotateLeft ( w );
|
||||
w = x_parent->left;
|
||||
}
|
||||
w->setColor ( x_parent->color() );
|
||||
x_parent->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
if ( w->left )
|
||||
w->left->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
rotateRight ( x_parent );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( x )
|
||||
x->setColor ( QQtOrderedMapNodeBase::Black );
|
||||
}
|
||||
free ( y );
|
||||
--size;
|
||||
}
|
||||
|
||||
void QQtOrderedMapDataBase::recalcMostLeftNode()
|
||||
{
|
||||
mostLeftNode = &header;
|
||||
while ( mostLeftNode->left )
|
||||
mostLeftNode = mostLeftNode->left;
|
||||
}
|
||||
|
||||
static inline int qMapAlignmentThreshold()
|
||||
{
|
||||
// malloc on 32-bit platforms should return pointers that are 8-byte
|
||||
// aligned or more while on 64-bit platforms they should be 16-byte aligned
|
||||
// or more
|
||||
return 2 * sizeof ( void* );
|
||||
}
|
||||
|
||||
static inline void* qMapAllocate ( int alloc, int alignment )
|
||||
{
|
||||
return alignment > qMapAlignmentThreshold()
|
||||
? qMallocAligned ( alloc, alignment )
|
||||
: ::malloc ( alloc );
|
||||
}
|
||||
|
||||
static inline void qMapDeallocate ( QQtOrderedMapNodeBase* node, int alignment )
|
||||
{
|
||||
if ( alignment > qMapAlignmentThreshold() )
|
||||
qFreeAligned ( node );
|
||||
else
|
||||
::free ( node );
|
||||
}
|
||||
|
||||
QQtOrderedMapNodeBase* QQtOrderedMapDataBase::createNode ( int alloc, int alignment, QQtOrderedMapNodeBase* parent, bool left )
|
||||
{
|
||||
QQtOrderedMapNodeBase* node = static_cast<QQtOrderedMapNodeBase*> ( qMapAllocate ( alloc, alignment ) );
|
||||
Q_CHECK_PTR ( node );
|
||||
|
||||
memset ( node, 0, alloc );
|
||||
++size;
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
if ( left )
|
||||
{
|
||||
parent->left = node;
|
||||
if ( parent == mostLeftNode )
|
||||
mostLeftNode = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->right = node;
|
||||
}
|
||||
node->setParent ( parent );
|
||||
rebalance ( node );
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
void QQtOrderedMapDataBase::freeTree ( QQtOrderedMapNodeBase* root, int alignment )
|
||||
{
|
||||
if ( root->left )
|
||||
freeTree ( root->left, alignment );
|
||||
if ( root->right )
|
||||
freeTree ( root->right, alignment );
|
||||
qMapDeallocate ( root, alignment );
|
||||
}
|
||||
|
||||
QQtOrderedMapDataBase* QQtOrderedMapDataBase::createData()
|
||||
{
|
||||
QQtOrderedMapDataBase* d = new QQtOrderedMapDataBase;
|
||||
|
||||
d->ref.initializeOwned();
|
||||
d->size = 0;
|
||||
|
||||
d->header.p = 0;
|
||||
d->header.left = 0;
|
||||
d->header.right = 0;
|
||||
d->mostLeftNode = & ( d->header );
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void QQtOrderedMapDataBase::freeData ( QQtOrderedMapDataBase* d )
|
||||
{
|
||||
delete d;
|
||||
}
|
1319
src/core/qqtorderedmap.h
Normal file
1319
src/core/qqtorderedmap.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -36,10 +36,12 @@ contains (DEFINES, __WIN__) {
|
||||
#core
|
||||
SOURCES += \
|
||||
$$PWD/core/qqtcore.cpp \
|
||||
$$PWD/core/qqtorderedmap.cpp \
|
||||
$$PWD/core/qqtdictionary.cpp \
|
||||
$$PWD/core/qqtobjectmanager.cpp
|
||||
HEADERS += \
|
||||
$$PWD/core/qqtcore.h \
|
||||
$$PWD/core/qqtorderedmap.h \
|
||||
$$PWD/core/qqtdictionary.h \
|
||||
$$PWD/core/qqtobjectmanager.h
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user