diff options
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 261 | 
1 files changed, 159 insertions, 102 deletions
| diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 5f97a3effa..6aed00be2a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3742,17 +3742,18 @@ void LLInventoryModel::dumpInventory() const  // returning an overall good/bad flag.  bool LLInventoryModel::validate() const  { -	bool valid = true; +    const S32 MAX_VERBOSE_ERRORS = 40; // too many errors can cause disconect or freeze +    S32 error_count = 0;  	if (getRootFolderID().isNull())  	{  		LL_WARNS() << "no root folder id" << LL_ENDL; -		valid = false; +        error_count++;  	}  	if (getLibraryRootFolderID().isNull())  	{  		LL_WARNS() << "no root folder id" << LL_ENDL; -		valid = false; +        error_count++;  	}  	if (mCategoryMap.size() + 1 != mParentChildCategoryTree.size()) @@ -3760,7 +3761,7 @@ bool LLInventoryModel::validate() const  		// ParentChild should be one larger because of the special entry for null uuid.  		LL_INFOS() << "unexpected sizes: cat map size " << mCategoryMap.size()  				<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL; -		valid = false; +        error_count++;  	}  	S32 cat_lock = 0;  	S32 item_lock = 0; @@ -3772,23 +3773,32 @@ bool LLInventoryModel::validate() const  		const LLViewerInventoryCategory *cat = cit->second;  		if (!cat)  		{ -			LL_WARNS() << "invalid cat" << LL_ENDL; -			valid = false; +            if (error_count < MAX_VERBOSE_ERRORS) +            { +                LL_WARNS() << "invalid cat" << LL_ENDL; +            } +            error_count++;  			continue;  		}  		if (cat_id != cat->getUUID())  		{ -			LL_WARNS() << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL; -			valid = false; +            if (error_count < MAX_VERBOSE_ERRORS) +            { +                LL_WARNS() << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL; +            } +            error_count++;  		}  		if (cat->getParentUUID().isNull())  		{  			if (cat_id != getRootFolderID() && cat_id != getLibraryRootFolderID())  			{ -				LL_WARNS() << "cat " << cat_id << " has no parent, but is not root (" -						<< getRootFolderID() << ") or library root (" -						<< getLibraryRootFolderID() << ")" << LL_ENDL; +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "cat " << cat_id << " has no parent, but is not root (" +                        << getRootFolderID() << ") or library root (" +                        << getLibraryRootFolderID() << ")" << LL_ENDL; +                }  			}  		}  		cat_array_t* cats; @@ -3796,8 +3806,11 @@ bool LLInventoryModel::validate() const  		getDirectDescendentsOf(cat_id,cats,items);  		if (!cats || !items)  		{ -			LL_WARNS() << "invalid direct descendents for " << cat_id << LL_ENDL; -			valid = false; +            if (error_count < MAX_VERBOSE_ERRORS) +            { +                LL_WARNS() << "invalid direct descendents for " << cat_id << LL_ENDL; +            } +            error_count++;  			continue;  		}  		if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) @@ -3806,12 +3819,15 @@ bool LLInventoryModel::validate() const  		}  		else if (cats->size() + items->size() != cat->getDescendentCount())  		{ -			LL_WARNS() << "invalid desc count for " << cat_id << " name [" << cat->getName() -					<< "] parent " << cat->getParentUUID() -					<< " cached " << cat->getDescendentCount() -					<< " expected " << cats->size() << "+" << items->size() -					<< "=" << cats->size() +items->size() << LL_ENDL; -			valid = false; +            if (error_count < MAX_VERBOSE_ERRORS) +            { +                LL_WARNS() << "invalid desc count for " << cat_id << " name [" << cat->getName() +                    << "] parent " << cat->getParentUUID() +                    << " cached " << cat->getDescendentCount() +                    << " expected " << cats->size() << "+" << items->size() +                    << "=" << cats->size() + items->size() << LL_ENDL; +            } +            error_count++;  		}  		if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)  		{ @@ -3831,8 +3847,11 @@ bool LLInventoryModel::validate() const  			if (!item)  			{ -				LL_WARNS() << "null item at index " << i << " for cat " << cat_id << LL_ENDL; -				valid = false; +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "null item at index " << i << " for cat " << cat_id << LL_ENDL; +                } +                error_count++;  				continue;  			} @@ -3840,10 +3859,13 @@ bool LLInventoryModel::validate() const  			if (item->getParentUUID() != cat_id)  			{ -				LL_WARNS() << "wrong parent for " << item_id << " found " -						<< item->getParentUUID() << " expected " << cat_id -						<< LL_ENDL; -				valid = false; +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "wrong parent for " << item_id << " found " +                        << item->getParentUUID() << " expected " << cat_id +                        << LL_ENDL; +                } +                error_count++;  			} @@ -3851,17 +3873,24 @@ bool LLInventoryModel::validate() const  			item_map_t::const_iterator it = mItemMap.find(item_id);  			if (it == mItemMap.end())  			{ -				LL_WARNS() << "item " << item_id << " found as child of " -						<< cat_id << " but not in top level mItemMap" << LL_ENDL; -				valid = false; + +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "item " << item_id << " found as child of " +                        << cat_id << " but not in top level mItemMap" << LL_ENDL; +                } +                error_count++;  			}  			else  			{  				LLViewerInventoryItem *top_item = it->second;  				if (top_item != item)  				{ -					LL_WARNS() << "item mismatch, item_id " << item_id -							<< " top level entry is different, uuid " << top_item->getUUID() << LL_ENDL; +                    if (error_count < MAX_VERBOSE_ERRORS) +                    { +                        LL_WARNS() << "item mismatch, item_id " << item_id +                            << " top level entry is different, uuid " << top_item->getUUID() << LL_ENDL; +                    }  				}  			} @@ -3870,19 +3899,25 @@ bool LLInventoryModel::validate() const  			bool found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);  			if (!found)  			{ -				LL_WARNS() << "unable to find topmost ancestor for " << item_id << LL_ENDL; -				valid = false; +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "unable to find topmost ancestor for " << item_id << LL_ENDL; +                } +                error_count++;  			}  			else  			{  				if (topmost_ancestor_id != getRootFolderID() &&  					topmost_ancestor_id != getLibraryRootFolderID())  				{ -					LL_WARNS() << "unrecognized top level ancestor for " << item_id -							<< " got " << topmost_ancestor_id -							<< " expected " << getRootFolderID() -							<< " or " << getLibraryRootFolderID() << LL_ENDL; -					valid = false; +                    if (error_count < MAX_VERBOSE_ERRORS) +                    { +                        LL_WARNS() << "unrecognized top level ancestor for " << item_id +                            << " got " << topmost_ancestor_id +                            << " expected " << getRootFolderID() +                            << " or " << getLibraryRootFolderID() << LL_ENDL; +                    } +                    error_count++;  				}  			}  		} @@ -3896,9 +3931,12 @@ bool LLInventoryModel::validate() const  			getDirectDescendentsOf(parent_id,cats,items);  			if (!cats)  			{ -				LL_WARNS() << "cat " << cat_id << " name [" << cat->getName() -						<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL; -				valid = false; +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "cat " << cat_id << " name [" << cat->getName() +                        << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL; +                } +                error_count++;  			}  			else  			{ @@ -3914,8 +3952,11 @@ bool LLInventoryModel::validate() const  				}  				if (!found)  				{ -					LL_WARNS() << "cat " << cat_id << " name [" << cat->getName() -							<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL; +                    if (error_count < MAX_VERBOSE_ERRORS) +                    { +                        LL_WARNS() << "cat " << cat_id << " name [" << cat->getName() +                            << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL; +                    }  				}  			}  		} @@ -3927,24 +3968,33 @@ bool LLInventoryModel::validate() const  		LLViewerInventoryItem *item = iit->second;  		if (item->getUUID() != item_id)  		{ -			LL_WARNS() << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL; -			valid = false; +            if (error_count < MAX_VERBOSE_ERRORS) +            { +                LL_WARNS() << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL; +            } +            error_count++;  		}  		const LLUUID& parent_id = item->getParentUUID();  		if (parent_id.isNull())  		{ -			LL_WARNS() << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL; +            if (error_count < MAX_VERBOSE_ERRORS) +            { +                LL_WARNS() << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL; +            }  		} -		else +		else if (error_count < MAX_VERBOSE_ERRORS)  		{  			cat_array_t* cats;  			item_array_t* items;  			getDirectDescendentsOf(parent_id,cats,items);  			if (!items)  			{ -				LL_WARNS() << "item " << item_id << " name [" << item->getName() -						<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL; +                if (error_count < MAX_VERBOSE_ERRORS) +                { +                    LL_WARNS() << "item " << item_id << " name [" << item->getName() +                        << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL; +                }  			}  			else  			{ @@ -3959,63 +4009,70 @@ bool LLInventoryModel::validate() const  				}  				if (!found)  				{ -					LL_WARNS() << "item " << item_id << " name [" << item->getName() -							<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL; +                    if (error_count < MAX_VERBOSE_ERRORS) +                    { +                        LL_WARNS() << "item " << item_id << " name [" << item->getName() +                            << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL; +                    }  				}  			}  		} -		// Link checking -		if (item->getIsLinkType()) -		{ -			const LLUUID& link_id = item->getUUID(); -			const LLUUID& target_id = item->getLinkedUUID(); -			LLViewerInventoryItem *target_item = getItem(target_id); -			LLViewerInventoryCategory *target_cat = getCategory(target_id); -			// Linked-to UUID should have back reference to this link. -			if (!hasBacklinkInfo(link_id, target_id)) -			{ -				LL_WARNS() << "link " << item->getUUID() << " type " << item->getActualType() -						<< " missing backlink info at target_id " << target_id -						<< LL_ENDL; -			} -			// Links should have referents. -			if (item->getActualType() == LLAssetType::AT_LINK && !target_item) -			{ -				LL_WARNS() << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL; -			} -			else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat) -			{ -				LL_WARNS() << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL; -			} -			if (target_item && target_item->getIsLinkType()) -			{ -				LL_WARNS() << "link " << item->getName() << " references a link item " -						<< target_item->getName() << " " << target_item->getUUID() << LL_ENDL; -			} -			// Links should not have backlinks. -			std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(link_id); -			if (range.first != range.second) -			{ -				LL_WARNS() << "Link item " << item->getName() << " has backlinks!" << LL_ENDL; -			} -		} -		else -		{ -			// Check the backlinks of a non-link item. -			const LLUUID& target_id = item->getUUID(); -			std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(target_id); -			for (backlink_mmap_t::const_iterator it = range.first; it != range.second; ++it) -			{ -				const LLUUID& link_id = it->second; -				LLViewerInventoryItem *link_item = getItem(link_id); -				if (!link_item || !link_item->getIsLinkType()) -				{ -					LL_WARNS() << "invalid backlink from target " << item->getName() << " to " << link_id << LL_ENDL; -				} -			} -		} +		// Link checking +        if (error_count < MAX_VERBOSE_ERRORS) +        { +            if (item->getIsLinkType()) +            { +                const LLUUID& link_id = item->getUUID(); +                const LLUUID& target_id = item->getLinkedUUID(); +                LLViewerInventoryItem *target_item = getItem(target_id); +                LLViewerInventoryCategory *target_cat = getCategory(target_id); +                // Linked-to UUID should have back reference to this link. +                if (!hasBacklinkInfo(link_id, target_id)) +                { +                    LL_WARNS() << "link " << item->getUUID() << " type " << item->getActualType() +                        << " missing backlink info at target_id " << target_id +                        << LL_ENDL; +                } +                // Links should have referents. +                if (item->getActualType() == LLAssetType::AT_LINK && !target_item) +                { +                    LL_WARNS() << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL; +                } +                else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat) +                { +                    LL_WARNS() << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL; +                } +                if (target_item && target_item->getIsLinkType()) +                { +                    LL_WARNS() << "link " << item->getName() << " references a link item " +                        << target_item->getName() << " " << target_item->getUUID() << LL_ENDL; +                } + +                // Links should not have backlinks. +                std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(link_id); +                if (range.first != range.second) +                { +                    LL_WARNS() << "Link item " << item->getName() << " has backlinks!" << LL_ENDL; +                } +            } +            else +            { +                // Check the backlinks of a non-link item. +                const LLUUID& target_id = item->getUUID(); +                std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(target_id); +                for (backlink_mmap_t::const_iterator it = range.first; it != range.second; ++it) +                { +                    const LLUUID& link_id = it->second; +                    LLViewerInventoryItem *link_item = getItem(link_id); +                    if (!link_item || !link_item->getIsLinkType()) +                    { +                        LL_WARNS() << "invalid backlink from target " << item->getName() << " to " << link_id << LL_ENDL; +                    } +                } +            } +        }  	}  	if (cat_lock > 0 || item_lock > 0) @@ -4032,9 +4089,9 @@ bool LLInventoryModel::validate() const  		LL_INFOS() << "Found " << version_unknown_count << " cats with unknown version" << LL_ENDL;  	} -	LL_INFOS() << "Validate done, valid = " << (U32) valid << LL_ENDL; +	LL_INFOS() << "Validate done, found " << error_count << " errors" << LL_ENDL; -	return valid; +	return error_count == 0;  }  ///---------------------------------------------------------------------------- | 
