Issue in TermPart.TermsComparer After Upgrade

Apr 26, 2012 at 10:10 PM

I have upgraded Contrib.Taxonomies (I am on Rev 112) and have encountered an issue.  Inside Contrib.Taxonomies.Models.TermPart.TermsComparer I am having an error on this line of code (line 111):

var xParent = _index[xFullPath];
var yParent = _index[yFullPath];

return Compare(xParent, yParent);

The issue is that _index does not always contain "yFullPath".  I am not sure if this is an issue with my database (i.e. some corruption) or if there is some other issue (I welcome your thoughts).  Currently to get everything to work I just wrap that line of code above in a Try/Catch.  Everything seems to be working fine on the website after this.

Apr 26, 2012 at 11:30 PM

Well, please don't try the "fix" above.  It does not actually solve the problem as the sort order will be a bit crazy.  I am still not thinking something is right. I have added the following code to make things work as I expect but possibly I am missing something as something still does not seem right:

for(int i=0; i< Math.Min(xPath.Length, yPath.Length); i++) {
    // EMS CHANGE start
    xFullPath = xPath[i];
    yFullPath = yPath[i];

    // Original
    //xFullPath += xPath[i];
    //yFullPath += yPath[i];
    // EMS CHANGE end

    if(!xFullPath.Equals(yFullPath,StringComparison.OrdinalIgnoreCase)) {
        // EMS CHANGE start
        xFullPath = "/" + xFullPath;
        yFullPath = "/" + yFullPath;

        try {
            var xParent = _index[xFullPath];
            var yParent = _index[yFullPath];

            return Compare(xParent, yParent);
        }
        catch { }
                        
        // Original Code
        //var xParent = _index[xFullPath];
        //var yParent = _index[yFullPath];

        //return Compare(xParent, yParent);

        // EMS CHANGE end
    }
}

At this point, the catch is still being hit and I feel it shouldn't be. I hope to look at this in a couple of days but if anyone else has solved this issue (or if the issue lies elsewhere I would love to hear about it.

 

Jun 4, 2012 at 11:51 AM
Edited Jun 4, 2012 at 11:52 AM

There is a small bug how xFullPath and yFullPath is build. I marked my changes with //FIX comment.

            public int Compare(TermPart x, TermPart y) {

                // if two nodes have the same parent, then compare by weight, then by path 
                // /1/2/3 vs /1/2/4 => 3 vs 4
                if (x.Path == y.Path) {
                    var weight = y.Weight.CompareTo(x.Weight);

                    if (weight != 0) {
                        return weight;
                    }

                    // if same parent path and same weight, compare by name
                    return String.CompareOrdinal(x.Name, y.Name);
                } 

                // if two nodes have different parents

                //    if the two nodes have the same root, the deeper is after (i.e. one starts with the other)
                //    /1/2 vs /1/2/3 => /1/2 first

                if (x.FullPath.StartsWith(y.FullPath, StringComparison.OrdinalIgnoreCase)) {
                    return 1;
                }

                if (y.FullPath.StartsWith(x.FullPath, StringComparison.OrdinalIgnoreCase)) {
                    return -1;
                }

                //    otherwise compare first none matching parent
                //    /1/2 vs /1/3 => 2 vs 3
                //    /2/3 vs /4 => 2 vs 4

                var xPath = x.FullPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                var yPath = y.FullPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                //FIX
                string xFullPath = string.Empty;
                string yFullPath = string.Empty;

                for(int i=0; i< Math.Min(xPath.Length, yPath.Length); i++) {
                    //FIX
                    xFullPath += "/" + xPath[i];
                    yFullPath += "/" + yPath[i];

                    if(!xFullPath.Equals(yFullPath,StringComparison.OrdinalIgnoreCase)) {
                        var xParent = _index[xFullPath];
                        var yParent = _index[yFullPath];
                        
                        return Compare(xParent, yParent);
                    }
                }

                return 0;
            }

 

Aug 14, 2012 at 11:13 AM

I have also had the problem where GetTermsForContentItem is being called on the TaxonomyService, and this in tern calls the Sort and the Compare.  However the index is not loaded up with all of the terms hierarchy and therefor the xParent and/or yParent is not contained the in the dictionary.  To fix this I have added the following:

 

if (!xFullPath.Equals(yFullPath, StringComparison.OrdinalIgnoreCase))
{
    	// FIX
    	if (!_index.ContainsKey(xFullPath) || !_index.ContainsKey(yFullPath))
    	{
        	// We don't have the full indexed list.
        	return 0;
    	}
	var xParent = _index[xFullPath];
	var yParent = _index[yFullPath];

	return Compare(xParent, yParent);
}

Ideally we want to get the term and send it off to be compared, but that means somehow getting a dependency on TaxonomyService.