Skip to content

Commit 91c9754

Browse files
committed
#5881 Optimize inventory cache loading
1 parent 34ee998 commit 91c9754

2 files changed

Lines changed: 176 additions & 156 deletions

File tree

indra/llinventory/llinventory.cpp

Lines changed: 166 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,171 +1002,186 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
10021002
end = sd.endMap();
10031003
for (i = sd.beginMap(); i != end; ++i)
10041004
{
1005-
if (i->first == INV_ITEM_ID_LABEL)
1006-
{
1007-
mUUID = i->second;
1008-
continue;
1009-
}
1010-
1011-
if (i->first == INV_PARENT_ID_LABEL)
1012-
{
1013-
mParentUUID = i->second;
1014-
continue;
1015-
}
1005+
// Use string length as a fast pre-filter before string comparison
1006+
const std::string& key = i->first;
1007+
const LLSD& value = i->second;
1008+
const size_t key_len = key.length();
10161009

1017-
if (i->first == INV_THUMBNAIL_LABEL)
1010+
switch (key_len)
10181011
{
1019-
const LLSD &thumbnail_map = i->second;
1020-
if (thumbnail_map.has(INV_ASSET_ID_LABEL))
1021-
{
1022-
mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL];
1023-
}
1024-
/* Example:
1025-
<key> asset_id </key>
1026-
<uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
1027-
<key> perms </key>
1028-
<integer> 8 </integer>
1029-
<key>service</key>
1030-
<integer> 3 </integer>
1031-
<key>version</key>
1032-
<integer> 1 </key>
1033-
*/
1034-
continue;
1035-
}
1036-
1037-
if (i->first == INV_THUMBNAIL_ID_LABEL)
1038-
{
1039-
mThumbnailUUID = i->second.asUUID();
1040-
continue;
1041-
}
1042-
1043-
if (i->first == INV_FAVORITE_LABEL)
1044-
{
1045-
const LLSD& favorite_map = i->second;
1046-
if (favorite_map.has(INV_TOGGLED_LABEL))
1047-
{
1048-
mFavorite = favorite_map[INV_TOGGLED_LABEL].asBoolean();
1049-
}
1050-
continue;
1051-
}
1052-
1053-
if (i->first == INV_PERMISSIONS_LABEL)
1054-
{
1055-
mPermissions.importLLSD(i->second);
1056-
continue;
1057-
}
1058-
1059-
if (i->first == INV_SALE_INFO_LABEL)
1060-
{
1061-
// Sale info used to contain next owner perm. It is now in
1062-
// the permissions. Thus, we read that out, and fix legacy
1063-
// objects. It's possible this op would fail, but it
1064-
// should pick up the vast majority of the tasks.
1065-
bool has_perm_mask = false;
1066-
U32 perm_mask = 0;
1067-
if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask))
1068-
{
1069-
return false;
1070-
}
1071-
if (has_perm_mask)
1072-
{
1073-
if (perm_mask == PERM_NONE)
1012+
case 4: // "name", "desc", "type"
1013+
if (key == INV_NAME_LABEL) // "name"
10741014
{
1075-
perm_mask = mPermissions.getMaskOwner();
1015+
mName = value.asString();
1016+
LLStringUtil::replaceNonstandardASCII(mName, ' ');
1017+
LLStringUtil::replaceChar(mName, '|', ' ');
1018+
continue;
10761019
}
1077-
// fair use fix.
1078-
if (!(perm_mask & PERM_COPY))
1020+
if (key == INV_DESC_LABEL) // "desc"
10791021
{
1080-
perm_mask |= PERM_TRANSFER;
1022+
mDescription = value.asString();
1023+
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
1024+
continue;
10811025
}
1082-
mPermissions.setMaskNext(perm_mask);
1083-
}
1084-
continue;
1085-
}
1086-
1087-
if (i->first == INV_SHADOW_ID_LABEL)
1088-
{
1089-
mAssetUUID = i->second;
1090-
LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
1091-
cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
1092-
continue;
1093-
}
1026+
if (key == INV_ASSET_TYPE_LABEL) // "type"
1027+
{
1028+
if (value.isString())
1029+
{
1030+
mType = LLAssetType::lookup(value.asStringRef().c_str());
1031+
}
1032+
else if (value.isInteger())
1033+
{
1034+
S8 type = (U8)value.asInteger();
1035+
mType = static_cast<LLAssetType::EType>(type);
1036+
}
1037+
continue;
1038+
}
1039+
break;
10941040

1095-
if (i->first == INV_ASSET_ID_LABEL)
1096-
{
1097-
mAssetUUID = i->second;
1098-
continue;
1099-
}
1041+
case 5: // "flags"
1042+
if (key == INV_FLAGS_LABEL)
1043+
{
1044+
if (value.isBinary())
1045+
{
1046+
mFlags = ll_U32_from_sd(value);
1047+
}
1048+
else if (value.isInteger())
1049+
{
1050+
mFlags = value.asInteger();
1051+
}
1052+
continue;
1053+
}
1054+
break;
11001055

1101-
if (i->first == INV_LINKED_ID_LABEL)
1102-
{
1103-
mAssetUUID = i->second;
1104-
continue;
1105-
}
1056+
case 7: // "item_id"
1057+
if (key == INV_ITEM_ID_LABEL)
1058+
{
1059+
mUUID = value;
1060+
continue;
1061+
}
1062+
break;
11061063

1107-
if (i->first == INV_ASSET_TYPE_LABEL)
1108-
{
1109-
LLSD const &label = i->second;
1110-
if (label.isString())
1111-
{
1112-
mType = LLAssetType::lookup(label.asStringRef().c_str());
1113-
}
1114-
else if (label.isInteger())
1115-
{
1116-
S8 type = (U8) label.asInteger();
1117-
mType = static_cast<LLAssetType::EType>(type);
1118-
}
1119-
continue;
1120-
}
1064+
case 8: // "asset_id", "inv_type"
1065+
if (key == INV_ASSET_ID_LABEL)
1066+
{
1067+
mAssetUUID = value;
1068+
continue;
1069+
}
1070+
if (key == INV_INVENTORY_TYPE_LABEL) // "inv_type"
1071+
{
1072+
if (value.isString())
1073+
{
1074+
mInventoryType = LLInventoryType::lookup(value.asStringRef().c_str());
1075+
}
1076+
else if (value.isInteger())
1077+
{
1078+
S8 type = (U8)value.asInteger();
1079+
mInventoryType = static_cast<LLInventoryType::EType>(type);
1080+
}
1081+
continue;
1082+
}
1083+
if (key == INV_FAVORITE_LABEL) // "favorite"
1084+
{
1085+
if (value.has(INV_TOGGLED_LABEL))
1086+
{
1087+
mFavorite = value[INV_TOGGLED_LABEL].asBoolean();
1088+
}
1089+
continue;
1090+
}
1091+
break;
11211092

1122-
if (i->first == INV_INVENTORY_TYPE_LABEL)
1123-
{
1124-
LLSD const &label = i->second;
1125-
if (label.isString())
1126-
{
1127-
mInventoryType = LLInventoryType::lookup(label.asStringRef().c_str());
1128-
}
1129-
else if (label.isInteger())
1130-
{
1131-
S8 type = (U8) label.asInteger();
1132-
mInventoryType = static_cast<LLInventoryType::EType>(type);
1133-
}
1134-
continue;
1135-
}
1093+
case 9: // "parent_id", "shadow_id", "linked_id", "sale_info"
1094+
if (key == INV_PARENT_ID_LABEL)
1095+
{
1096+
mParentUUID = value;
1097+
continue;
1098+
}
1099+
if (key == INV_SHADOW_ID_LABEL)
1100+
{
1101+
mAssetUUID = value;
1102+
LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
1103+
cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
1104+
continue;
1105+
}
1106+
if (key == INV_LINKED_ID_LABEL)
1107+
{
1108+
mAssetUUID = value;
1109+
continue;
1110+
}
1111+
if (key == INV_SALE_INFO_LABEL)
1112+
{
1113+
// Sale info used to contain next owner perm. It is now in
1114+
// the permissions. Thus, we read that out, and fix legacy
1115+
// objects. It's possible this op would fail, but it
1116+
// should pick up the vast majority of the tasks.
1117+
bool has_perm_mask = false;
1118+
U32 perm_mask = 0;
1119+
if (!mSaleInfo.fromLLSD(value, has_perm_mask, perm_mask))
1120+
{
1121+
return false;
1122+
}
1123+
if (has_perm_mask)
1124+
{
1125+
if (perm_mask == PERM_NONE)
1126+
{
1127+
perm_mask = mPermissions.getMaskOwner();
1128+
}
1129+
// fair use fix.
1130+
if (!(perm_mask & PERM_COPY))
1131+
{
1132+
perm_mask |= PERM_TRANSFER;
1133+
}
1134+
mPermissions.setMaskNext(perm_mask);
1135+
}
1136+
continue;
1137+
}
1138+
break;
11361139

1137-
if (i->first == INV_FLAGS_LABEL)
1138-
{
1139-
LLSD const &label = i->second;
1140-
if (label.isBinary())
1141-
{
1142-
mFlags = ll_U32_from_sd(label);
1143-
}
1144-
else if (label.isInteger())
1145-
{
1146-
mFlags = label.asInteger();
1147-
}
1148-
continue;
1149-
}
1140+
case 10: // "created_at", "thumbnail"
1141+
if (key == INV_CREATION_DATE_LABEL)
1142+
{
1143+
mCreationDate = value.asInteger();
1144+
continue;
1145+
}
1146+
if (key == INV_THUMBNAIL_LABEL)
1147+
{
1148+
if (value.has(INV_ASSET_ID_LABEL))
1149+
{
1150+
mThumbnailUUID = value[INV_ASSET_ID_LABEL];
1151+
}
1152+
/* Example:
1153+
<key> asset_id </key>
1154+
<uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
1155+
<key> perms </key>
1156+
<integer> 8 </integer>
1157+
<key>service</key>
1158+
<integer> 3 </integer>
1159+
<key>version</key>
1160+
<integer> 1 </key>
1161+
*/
1162+
continue;
1163+
}
1164+
break;
11501165

1151-
if (i->first == INV_NAME_LABEL)
1152-
{
1153-
mName = i->second.asString();
1154-
LLStringUtil::replaceNonstandardASCII(mName, ' ');
1155-
LLStringUtil::replaceChar(mName, '|', ' ');
1156-
continue;
1157-
}
1166+
case 11: // "permissions"
1167+
if (key == INV_PERMISSIONS_LABEL)
1168+
{
1169+
mPermissions.importLLSD(value);
1170+
continue;
1171+
}
1172+
break;
11581173

1159-
if (i->first == INV_DESC_LABEL)
1160-
{
1161-
mDescription = i->second.asString();
1162-
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
1163-
continue;
1164-
}
1174+
case 12: // "thumbnail_id"
1175+
if (key == INV_THUMBNAIL_ID_LABEL)
1176+
{
1177+
mThumbnailUUID = value.asUUID();
1178+
continue;
1179+
}
1180+
break;
11651181

1166-
if (i->first == INV_CREATION_DATE_LABEL)
1167-
{
1168-
mCreationDate = i->second.asInteger();
1169-
continue;
1182+
default:
1183+
// Unknown field - skip
1184+
break;
11701185
}
11711186
}
11721187

indra/newview/llinventorymodel.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,10 +2719,11 @@ bool LLInventoryModel::loadSkeleton(
27192719
for(LLSD::array_const_iterator it = options.beginArray(),
27202720
end = options.endArray(); it != end; ++it)
27212721
{
2722-
LLSD name = (*it)["name"];
2723-
LLSD folder_id = (*it)["folder_id"];
2724-
LLSD parent_id = (*it)["parent_id"];
2725-
LLSD version = (*it)["version"];
2722+
const LLSD &folder = *it;
2723+
const LLSD &name = folder["name"];
2724+
const LLSD &folder_id = folder["folder_id"];
2725+
const LLSD &parent_id = folder["parent_id"];
2726+
const LLSD &version = folder["version"];
27262727
if(name.isDefined()
27272728
&& folder_id.isDefined()
27282729
&& parent_id.isDefined()
@@ -2736,7 +2737,7 @@ bool LLInventoryModel::loadSkeleton(
27362737
cat->setParent(parent_id.asUUID());
27372738

27382739
LLFolderType::EType preferred_type = LLFolderType::FT_NONE;
2739-
LLSD type_default = (*it)["type_default"];
2740+
const LLSD &type_default = folder["type_default"];
27402741
if(type_default.isDefined())
27412742
{
27422743
preferred_type = (LLFolderType::EType)type_default.asInteger();
@@ -3454,6 +3455,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
34543455
const LLSD& llsd_cats = inventory["categories"];
34553456
if (llsd_cats.isArray())
34563457
{
3458+
size_t cats_count = llsd_cats.size();
3459+
categories.reserve(cats_count);
34573460
LLSD::array_const_iterator iter = llsd_cats.beginArray();
34583461
LLSD::array_const_iterator end = llsd_cats.endArray();
34593462
for (; iter != end; ++iter)
@@ -3472,6 +3475,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
34723475
const LLSD& llsd_items = inventory["items"];
34733476
if (llsd_items.isArray())
34743477
{
3478+
size_t items_count = llsd_items.size();
3479+
items.reserve(items_count);
34753480
LLSD::array_const_iterator iter = llsd_items.beginArray();
34763481
LLSD::array_const_iterator end = llsd_items.endArray();
34773482
for (; iter != end; ++iter)

0 commit comments

Comments
 (0)