Author: xor
Date: 2008-10-29 22:50:08 +0000 (Wed, 29 Oct 2008)
New Revision: 23208

Modified:
   trunk/plugins/FMSPlugin/FMSBoard.java
Log:
Finish the thread assembly algorithm. PLEASE REVIEW! I have not tested it and I 
might have forgotten special cases.

Modified: trunk/plugins/FMSPlugin/FMSBoard.java
===================================================================
--- trunk/plugins/FMSPlugin/FMSBoard.java       2008-10-29 22:46:28 UTC (rev 
23207)
+++ trunk/plugins/FMSPlugin/FMSBoard.java       2008-10-29 22:50:08 UTC (rev 
23208)
@@ -4,6 +4,7 @@
 package plugins.FMSPlugin;

 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -23,16 +24,29 @@
  *
  */
 public class FMSBoard extends UpdatableSortedLinkedListItemImpl implements 
IndexableUpdatableSortedLinkedListItem {
+       

-       private final FMSBoard self = this;
+       /**
+        * Contains all messages in this board.
+        * TODO: Figure out whether we really need this or should just use the 
global message hashtable of the FMSMessageManager.
+        */
+       private Hashtable<FreenetURI, FMSMessage> mAllMessages = new 
Hashtable<FreenetURI, FMSMessage>();

        /**
-        * Contains all messages in this board, both as a Hashmap and as a 
linked list which is sorted by date.
+        * Contains all threads in this board, both as a Hashmap and as a 
linked list which is sorted by date.
         * The hashmap is useful for checking whether a message was already 
stored.
         * The linked list allows fast displaying of all messages.
         */
-       private final UpdatableSortedLinkedListWithForeignIndex mMessages = new 
UpdatableSortedLinkedListWithForeignIndex();
+       private UpdatableSortedLinkedListWithForeignIndex mThreads = new 
UpdatableSortedLinkedListWithForeignIndex();

+       /**
+        * Contains orphans for which even the parent thread did not exist. 
They are currently listed in the threads list and have to be removed
+        * from it if their thread is found.
+        */
+       private LinkedList<FMSMessage> mAbsoluteOrphans = new 
LinkedList<FMSMessage>(); 
+
+       private final FMSBoard self = this;
+       
        private final FMSMessageManager mMessageManager;

        private final String mName;
@@ -72,32 +86,80 @@
                return mName;
        }

+       /**
+        * Called by the <code>FMSMessageManager</code> to add a just received 
message to the board.
+        * The job for this function is to find the right place in the 
thread-tree for the new message and to move around older messages
+        * if a parent message of them is received.
+        */
        public void addMessage(FMSMessage newMessage) throws 
UpdatableSortedLinkedListKilledException {
-               if(mMessages.containsKey(newMessage)) {
+               if(mAllMessages.containsKey(newMessage)) {
                        /* The message was already stored */
                        assert(false); /* TODO: Add logging. I don't know 
whether this should happen. */
                        return;
                }
+               mAllMessages.put(newMessage.getURI(), newMessage);

-               if(newMessage.getParentURI() == null) {
-                       mMessages.add(newMessage);
-                       // FIXME: link children to the thread
+               if(newMessage.isThread()) {     /* The message is a thread */
+                       mThreads.add(newMessage);
                }
                else
                {
                        FreenetURI parentURI = newMessage.getParentURI();
-                       FMSMessage parentMessage = 
mMessageManager.get(parentURI);
-                       if(parentMessage == null) {
-                               mMessages.add(newMessage);
-                               /* FIXME: The MessageManager should try to 
download the parent message if it's poster has enough trust.
-                                * If it is programmed to do that, it will 
check its Hashtable whether the parent message already exists.
-                                * We also do that here, therefore, when 
implementing parent message downloading, please do the Hashtable checking only 
once. 
-                                */
-                               return;
-                       } else {
+                       FMSMessage parentMessage = 
mMessageManager.get(parentURI); /* TODO: This allows crossposting. Figure out 
whether we need to handle it specially */
+                       if(parentMessage != null) {
                                parentMessage.addChild(newMessage);
+                       } else { /* The message is an orphan */
+                               FMSMessage parentThread = 
mMessageManager.get(newMessage.getParentThreadURI());
+                               if(parentThread != null) {
+                                       parentThread.addChild(newMessage);      
/* We found its parent thread so just stick it in there for now */
+                               }
+                               else { /* The message is an absolute orphan */
+                                       mThreads.add(newMessage); /* TODO: 
Instead of hiding the message completely, we make it look like a thread. 
Reconsider this. */
+                                       mAbsoluteOrphans.add(newMessage);
+                                       
+                                       /* 
+                                        * FIXME: The MessageManager should try 
to download the parent message if it's poster has enough trust.
+                                        * If it is programmed to do that, it 
will check its Hashtable whether the parent message already exists.
+                                        * We also do that here, therefore, 
when implementing parent message downloading, please do the Hashtable checking 
only once. 
+                                        */
+                               }
+                       } 
+               }
+               
+               linkOrphansToNewParent(newMessage);
+       }
+       
+       private void linkOrphansToNewParent(FMSMessage newMessage) throws 
UpdatableSortedLinkedListKilledException {
+               if(newMessage.isThread()) {
+                       for(FMSMessage o : mAbsoluteOrphans) {  /* Search in 
the orphans for messages which belong to this thread */
+                               
if(o.getParentThreadURI().equals(newMessage.getURI())) {
+                                       newMessage.addChild(o);
+                                       mAbsoluteOrphans.remove(o);
+                               }
                        }
                }
+               else {
+                       FMSMessage parentThread = 
(FMSMessage)mThreads.get(newMessage.getParentThreadURI());
+                       if(parentThread != null) {      /* Search in its parent 
thread for its children */
+                               Iterator<FMSMessage> iter = 
parentThread.childrenIterator();
+                               while(iter.hasNext()) {
+                                       FMSMessage parentThreadChild = 
iter.next();
+                                       
+                                       
if(parentThreadChild.getParentURI().equals(newMessage.getURI())) { /* We found 
its parent, yeah! */
+                                               iter.remove();  /* It's a child 
of the newMessage, not of the parentThread */
+                                               
newMessage.addChild(parentThreadChild);
+                                       }
+                               }
+                       } else { /* The new message is an absolute orphan, find 
its children amongst the other absolute orphans */
+                               for(FMSMessage o : mAbsoluteOrphans) {
+                                       
if(o.getParentURI().equals(newMessage.getURI())) {
+                                               newMessage.addChild(o);
+                                               mAbsoluteOrphans.remove(o);
+                                       }
+                               }
+                       }
+               }
+               
        }


@@ -106,10 +168,10 @@
         * @param identity The identity viewing the board.
         * @return An iterator of the message which the identity will see 
(based on its trust levels).
         */
-       public synchronized Iterator<FMSMessage> messageIterator(final 
FMSOwnIdentity identity) {
+       public synchronized Iterator<FMSMessage> threadIterator(final 
FMSOwnIdentity identity) {
                return new Iterator<FMSMessage>() {
                        private final FMSOwnIdentity mIdentity = identity;
-                       private Iterator<FMSMessage> iter = 
self.mMessages.iterator();
+                       private Iterator<FMSMessage> iter = 
self.mThreads.iterator();
                        private FMSMessage next = iter.hasNext() ? iter.next() 
: null;

                        public boolean hasNext() {


Reply via email to