Exemple #1
0
        /* Function: PickNewTopics
         * Returns the IDs for a batch of new topics and their shared ending symbol, or false if there aren't any.  This allows you to process
         * new topics that could potentially serve as better definitions to existing links.
         */
        public bool PickNewTopics(out IDObjects.NumberSet topicIDs, out EndingSymbol endingSymbol)
        {
            lock (accessLock)
            {
                if (newTopicIDsByEndingSymbol.Count == 0)
                {
                    topicIDs     = null;
                    endingSymbol = default(EndingSymbol);
                    return(false);
                }
                else
                {
                    // Once links might be resolved we can't allow this optimization anymore.  See the variable's documentation for
                    // the explanation.
                    ignoreNewTopics = false;

                    var enumerator = newTopicIDsByEndingSymbol.GetEnumerator();
                    enumerator.MoveNext();                      // It's not positioned on the first element by default.

                    endingSymbol = enumerator.Current.Key;
                    topicIDs     = enumerator.Current.Value;

                    newTopicIDsByEndingSymbol.Remove(endingSymbol);

                    return(true);
                }
            }
        }
Exemple #2
0
        /* Function: PickEndingSymbolToResolve
         * If <newTopicIDsByEndingSymbol> isn't empty it will remove one from the list and return true.  Otherwise
         * returns false.  Handles locking automatically.
         */
        protected bool PickEndingSymbolToResolve(out EndingSymbol endingSymbol, out NumberSet topicIDs)
        {
            Monitor.Enter(newTopicIDsByEndingSymbol);

            try
            {
                if (newTopicIDsByEndingSymbol.Count == 0)
                {
                    endingSymbol = default(EndingSymbol);
                    topicIDs     = null;
                    return(false);
                }
                else
                {
                    var enumerator = newTopicIDsByEndingSymbol.GetEnumerator();
                    enumerator.MoveNext();                      // It's not positioned on the first element by default.

                    endingSymbol = enumerator.Current.Key;
                    topicIDs     = enumerator.Current.Value;

                    newTopicIDsByEndingSymbol.Remove(endingSymbol);

                    return(true);
                }
            }
            finally
            { Monitor.Exit(newTopicIDsByEndingSymbol); }
        }
Exemple #3
0
 /* Function: FinalizeNewTopics
  * Finalizes processing of a set of new topics and their shared ending symbol.
  */
 protected void FinalizeNewTopics(IDObjects.NumberSet topicIDs, EndingSymbol endingSymbol)
 {
     lock (accessLock)
     {
         // DEPENDENCY: Make sure all changes to changesBeingProcessed match the system used in UnprocessedChanges.Count
         changesBeingProcessed -= topicIDs.Count;
     }
 }
Exemple #4
0
 /* Function: PickNewTopics
  * Returns the IDs for a batch of new topics and their shared ending symbol, or false if there aren't any.  This allows
  * you to process new topics that could potentially serve as better definitions to existing links.  You must pass the values
  * to <FinalizeNewTopics()> after resolving them.
  */
 protected bool PickNewTopics(out IDObjects.NumberSet topicIDs, out EndingSymbol endingSymbol)
 {
     lock (accessLock)
         {
         if (Manager.UnprocessedChanges.PickNewTopics(out topicIDs, out endingSymbol))
             {
             // DEPENDENCY: Make sure all changes to changesBeingProcessed match the system used in UnprocessedChanges.Count
             changesBeingProcessed += topicIDs.Count;
             return true;
             }
         else
             {  return false;  }
         }
 }
Exemple #5
0
        // Group: Functions
        // __________________________________________________________________________


        public Link()
        {
            linkID        = 0;
            type          = LinkType.NaturalDocs;
            textOrSymbol  = null;
            context       = new ContextString();
            contextID     = 0;
            fileID        = 0;
            classString   = new ClassString();
            classID       = 0;
            languageID    = 0;
            endingSymbol  = new EndingSymbol();
            targetTopicID = 0;
            targetClassID = 0;
            targetScore   = 0;

            ignoredFields = IgnoreFields.None;
        }
Exemple #6
0
        /* Function: ResolveNewTopics
         *
         * Goes through the IDs of newly created <Topics> and sees if they serve as better targets for any existing
         * links.
         *
         * Parameters:
         *
         *		topicIDs - The set of IDs to check.  Every <Topic> represented here must have the same <EndingSymbol>.
         *		endingSymbol - The <EndingSymbol> shared by all of the topic IDs.
         *		accessor - The <Accessor> used for the database.
         *
         * Requirements:
         *
         *		- Requires the accessor to have at least a read/possible write lock.  If the link changes it will be upgraded to
         *		  read/write automatically.
         *
         */
        protected void ResolveNewTopics(IDObjects.NumberSet topicIDs, EndingSymbol endingSymbol, Accessor accessor)
        {
            // We only need the body's length, not its contents.
            List <Topic> topics = accessor.GetTopicsByID(topicIDs, Delegates.NeverCancel,
                                                         Accessor.GetTopicFlags.BodyLengthOnly |
                                                         Accessor.GetTopicFlags.DontLookupClasses |
                                                         Accessor.GetTopicFlags.DontLookupContexts);
            List <Link> links = accessor.GetLinksByEndingSymbol(endingSymbol, Delegates.NeverCancel,
                                                                Accessor.GetLinkFlags.DontLookupClasses);

            // Go through each link and see if any of the topics serve as a better target.  It's better for the links to be the outer loop
            // because we can generate alternate interpretations only once per link.

            foreach (Link link in links)
            {
                List <LinkInterpretation> alternateInterpretations = null;

                if (link.Type == LinkType.NaturalDocs)
                {
                    string ignore;
                    alternateInterpretations = EngineInstance.Comments.NaturalDocsParser.LinkInterpretations(link.Text,
                                                                                                             Comments.Parsers.NaturalDocs.LinkInterpretationFlags.FromOriginalText |
                                                                                                             Comments.Parsers.NaturalDocs.LinkInterpretationFlags.AllowNamedLinks |
                                                                                                             Comments.Parsers.NaturalDocs.LinkInterpretationFlags.AllowPluralsAndPossessives,
                                                                                                             out ignore);
                }

                int  bestMatchTopicID = link.TargetTopicID;
                int  bestMatchClassID = link.TargetClassID;
                long bestMatchScore   = link.TargetScore;

                foreach (Topic topic in topics)
                {
                    // No use rescoring the existing target.
                    if (topic.TopicID != link.TargetTopicID)
                    {
                        long score = EngineInstance.Links.Score(link, topic, bestMatchScore, alternateInterpretations);

                        if (score > bestMatchScore)
                        {
                            bestMatchTopicID = topic.TopicID;
                            bestMatchClassID = topic.ClassID;
                            bestMatchScore   = score;
                        }
                    }
                }

                if (bestMatchTopicID != link.TargetTopicID ||
                    bestMatchClassID != link.TargetClassID ||
                    bestMatchScore != link.TargetScore)
                {
                    int oldTargetTopicID = link.TargetTopicID;
                    int oldTargetClassID = link.TargetClassID;

                    link.TargetTopicID = bestMatchTopicID;
                    link.TargetClassID = bestMatchClassID;
                    link.TargetScore   = bestMatchScore;

                    accessor.UpdateLinkTarget(link, oldTargetTopicID, oldTargetClassID);
                }
            }
        }