1
0
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:
tianduanrui 2019-06-01 10:12:39 +08:00
parent ac2c5ebd97
commit 85207b7c70
5 changed files with 1740 additions and 17 deletions

View File

@ -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

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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