mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-28 17:09:34 -05:00
switch 32bits implementation to a more compact mode allowing more profiles
This commit is contained in:
parent
4b55fc4789
commit
978ce82243
@ -46,7 +46,9 @@
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere
|
||||
|
||||
static const uint16_t UNDEFINED_INDEX_VALUE = (sizeof(uintptr_t)==4)?0xff:0xffff;
|
||||
static const uint16_t UNDEFINED_GROUP_INDEX_VALUE = (sizeof(uintptr_t)==4)?0x1ff:0xffff; // max value for 9 bits
|
||||
static const uint16_t UNDEFINED_NODE_INDEX_VALUE = (sizeof(uintptr_t)==4)?0x1ff:0xffff; // max value for 9 bits
|
||||
static const uint16_t UNDEFINED_PROFILE_INDEX_VALUE = (sizeof(uintptr_t)==4)?0xfff:0xffff; // max value for 12 bits
|
||||
|
||||
const QString RsFriendListModel::FilterString("filtered");
|
||||
const uint32_t MAX_INTERNAL_DATA_UPDATE_DELAY = 300 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes.
|
||||
@ -64,29 +66,37 @@ RsFriendListModel::RsFriendListModel(QObject *parent)
|
||||
}
|
||||
|
||||
RsFriendListModel::EntryIndex::EntryIndex()
|
||||
: type(ENTRY_TYPE_UNKNOWN),group_index(UNDEFINED_INDEX_VALUE),profile_index(UNDEFINED_INDEX_VALUE),node_index(UNDEFINED_INDEX_VALUE)
|
||||
: type(ENTRY_TYPE_UNKNOWN),group_index(UNDEFINED_GROUP_INDEX_VALUE),profile_index(UNDEFINED_PROFILE_INDEX_VALUE),node_index(UNDEFINED_NODE_INDEX_VALUE)
|
||||
{
|
||||
}
|
||||
|
||||
// The index encodes the whole hierarchy of parents. This allows to very efficiently compute indices of the parent of an index.
|
||||
//
|
||||
// The format is the following:
|
||||
// On 32 bits architectures the format is the following:
|
||||
//
|
||||
// 0x 00 00 00 00
|
||||
// | | | |
|
||||
// | | | +---- location/node index
|
||||
// | | +------- profile index
|
||||
// | +---------- group index
|
||||
// +------------- type
|
||||
// 0x [2 bits] [9 bits] [12 bits] [9 bits]
|
||||
// | | | |
|
||||
// | | | +---- location/node index
|
||||
// | | +-------------- profile index
|
||||
// | +----------------------- group index
|
||||
// +-------------------------------- type
|
||||
//
|
||||
// Only valid indexes a 0x01->UNDEFINED_INDEX_VALUE. 0x00 means "no index"
|
||||
// We propose 2 implementations, one for 32bits, that only allows up to 256 friends/groups/nodes, and one for 64bits which allows 16bits values.
|
||||
// On 64 bits architectures the format is the following:
|
||||
//
|
||||
// 0x [16 bits] [16 bits] [16 bits] [16 bits]
|
||||
// | | | |
|
||||
// | | | +---- location/node index
|
||||
// | | +-------------- profile index
|
||||
// | +----------------------- group index
|
||||
// +-------------------------------- type
|
||||
//
|
||||
// Only valid indexes a 0x00->UNDEFINED_INDEX_VALUE-1.
|
||||
|
||||
template<> bool RsFriendListModel::convertIndexToInternalId<4>(const EntryIndex& e,quintptr& id)
|
||||
{
|
||||
// the internal id is set to the place in the table of items. We simply shift to allow 0 to mean something special.
|
||||
|
||||
id = (((uint32_t)e.type) << 24) + ((uint32_t)e.group_index << 16) + ((uint32_t)e.profile_index << 8) + (uint32_t)e.node_index;
|
||||
id = (((uint32_t)e.type) << 30) + ((uint32_t)e.group_index << 21) + ((uint32_t)e.profile_index << 9) + (uint32_t)e.node_index;
|
||||
return true;
|
||||
}
|
||||
template<> bool RsFriendListModel::convertIndexToInternalId<8>(const EntryIndex& e,quintptr& id)
|
||||
@ -102,11 +112,11 @@ template<> bool RsFriendListModel::convertInternalIdToIndex<4>(quintptr ref,Entr
|
||||
if(ref == 0)
|
||||
return false ;
|
||||
|
||||
e.group_index = (ref >> 16) & 0xff;
|
||||
e.profile_index = (ref >> 8) & 0xff;
|
||||
e.node_index = (ref >> 0) & 0xff;
|
||||
e.group_index = (ref >> 21) & 0x1ff;// 9 bits
|
||||
e.profile_index = (ref >> 9) & 0xfff;// 12 bits
|
||||
e.node_index = (ref >> 0) & 0x1ff;// 9 bits
|
||||
|
||||
e.type = static_cast<EntryType>((ref >> 24) & 0xff);
|
||||
e.type = static_cast<EntryType>((ref >> 30) & 0x03);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -163,7 +173,7 @@ int RsFriendListModel::rowCount(const QModelIndex& parent) const
|
||||
return mGroups[index.group_index].child_profile_indices.size();
|
||||
|
||||
if(index.type == ENTRY_TYPE_PROFILE)
|
||||
if(index.group_index < UNDEFINED_INDEX_VALUE)
|
||||
if(index.group_index < UNDEFINED_GROUP_INDEX_VALUE)
|
||||
return mProfiles[mGroups[index.group_index].child_profile_indices[index.profile_index]].child_node_indices.size();
|
||||
else
|
||||
return mProfiles[index.profile_index].child_node_indices.size();
|
||||
@ -189,7 +199,7 @@ bool RsFriendListModel::hasChildren(const QModelIndex &parent) const
|
||||
return false;
|
||||
|
||||
if(parent_index.type == ENTRY_TYPE_PROFILE)
|
||||
if(parent_index.group_index < UNDEFINED_INDEX_VALUE)
|
||||
if(parent_index.group_index < UNDEFINED_GROUP_INDEX_VALUE)
|
||||
return !mProfiles[mGroups[parent_index.group_index].child_profile_indices[parent_index.profile_index]].child_node_indices.empty();
|
||||
else
|
||||
return !mProfiles[parent_index.profile_index].child_node_indices.empty();
|
||||
@ -209,17 +219,17 @@ RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::parent() const
|
||||
case ENTRY_TYPE_GROUP: return EntryIndex();
|
||||
|
||||
case ENTRY_TYPE_PROFILE:
|
||||
if(i.group_index==UNDEFINED_INDEX_VALUE)
|
||||
if(i.group_index==UNDEFINED_GROUP_INDEX_VALUE)
|
||||
return EntryIndex();
|
||||
else
|
||||
{
|
||||
i.type = ENTRY_TYPE_GROUP;
|
||||
i.profile_index = UNDEFINED_INDEX_VALUE;
|
||||
i.profile_index = UNDEFINED_PROFILE_INDEX_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENTRY_TYPE_NODE: i.type = ENTRY_TYPE_PROFILE;
|
||||
i.node_index = UNDEFINED_INDEX_VALUE;
|
||||
i.node_index = UNDEFINED_NODE_INDEX_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -258,7 +268,7 @@ uint32_t RsFriendListModel::EntryIndex::parentRow(uint32_t nb_groups) const
|
||||
default:
|
||||
case ENTRY_TYPE_UNKNOWN : return 0;
|
||||
case ENTRY_TYPE_GROUP : return group_index;
|
||||
case ENTRY_TYPE_PROFILE : return (group_index==UNDEFINED_INDEX_VALUE)?(profile_index+nb_groups):profile_index;
|
||||
case ENTRY_TYPE_PROFILE : return (group_index==UNDEFINED_GROUP_INDEX_VALUE)?(profile_index+nb_groups):profile_index;
|
||||
case ENTRY_TYPE_NODE : return node_index;
|
||||
}
|
||||
}
|
||||
@ -736,7 +746,7 @@ const RsFriendListModel::HierarchicalProfileInformation *RsFriendListModel::getP
|
||||
if(e.type != ENTRY_TYPE_PROFILE)
|
||||
return NULL ;
|
||||
|
||||
if(e.group_index < UNDEFINED_INDEX_VALUE)
|
||||
if(e.group_index < UNDEFINED_GROUP_INDEX_VALUE)
|
||||
{
|
||||
const HierarchicalGroupInformation& group(mGroups[e.group_index]);
|
||||
|
||||
@ -756,7 +766,7 @@ const RsFriendListModel::HierarchicalNodeInformation *RsFriendListModel::getNode
|
||||
|
||||
uint32_t pindex = 0;
|
||||
|
||||
if(e.group_index < UNDEFINED_INDEX_VALUE)
|
||||
if(e.group_index < UNDEFINED_GROUP_INDEX_VALUE)
|
||||
{
|
||||
const HierarchicalGroupInformation& group(mGroups[e.group_index]);
|
||||
|
||||
@ -1091,7 +1101,7 @@ void RsFriendListModel::updateInternalData()
|
||||
EntryIndex e;
|
||||
e.type = ENTRY_TYPE_PROFILE;
|
||||
e.profile_index = i;
|
||||
e.group_index = UNDEFINED_INDEX_VALUE;
|
||||
e.group_index = UNDEFINED_GROUP_INDEX_VALUE;
|
||||
|
||||
mTopLevel.push_back(e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user