On Tuesday 04 November 2008 12:13, xor at freenetproject.org wrote:
> Author: xor
> Date: 2008-11-04 12:13:55 +0000 (Tue, 04 Nov 2008)
> New Revision: 23306
>
> Modified:
> trunk/plugins/FMSPlugin/FMS.java
> trunk/plugins/FMSPlugin/FMSBoard.java
> trunk/plugins/FMSPlugin/FMSIdentityManager.java
> trunk/plugins/FMSPlugin/FMSMessage.java
> trunk/plugins/FMSPlugin/FMSMessageManager.java
> trunk/plugins/FMSPlugin/WoT/FMSIdentityManagerWoT.java
> trunk/plugins/FMSPlugin/WoT/FMSMessageManagerWoT.java
> trunk/plugins/FMSPlugin/WoT/FMSMessageWoT.java
> Log:
> Major refactoring: FMS now completely relies on db4o, no more hashtables /
linkedlists - if db4o works well then FMS should scale well. I changed so
much of the code that I cannot split into small commits, sorry.
>
> Modified: trunk/plugins/FMSPlugin/FMS.java
> ===================================================================
> --- trunk/plugins/FMSPlugin/FMS.java 2008-11-04 10:24:00 UTC (rev 23305)
> +++ trunk/plugins/FMSPlugin/FMS.java 2008-11-04 12:13:55 UTC (rev 23306)
> @@ -99,8 +99,11 @@
> Configuration cache_config = Db4o.newConfiguration();
> for(String f : FMSMessage.getIndexedFields())
>
> cache_config.objectClass(FMSMessage.class).objectField(f).indexed(true);
> +
> cache_config.objectClass(FMSMessage.class).cascadeOnUpdate(true);
> + // TODO: decide about cascade on delete.
> for(String f : FMSBoard.getIndexedFields())
>
> cache_config.objectClass(FMSBoard.class).objectField(f).indexed(true);
> +
> db_cache = Db4o.openFile(cache_config, "fms_cache.db4o");
>
> // while develop wipe cache on startup
>
> Modified: trunk/plugins/FMSPlugin/FMSBoard.java
> ===================================================================
> --- trunk/plugins/FMSPlugin/FMSBoard.java 2008-11-04 10:24:00 UTC (rev
23305)
> +++ trunk/plugins/FMSPlugin/FMSBoard.java 2008-11-04 12:13:55 UTC (rev
23306)
> @@ -3,55 +3,33 @@
> * http://www.gnu.org/ for further details of the GPL. */
> package plugins.FMSPlugin;
>
> -import java.util.Collections;
> -import java.util.HashSet;
> -import java.util.Hashtable;
> import java.util.Iterator;
> import java.util.LinkedList;
> -import java.util.ListIterator;
> -import java.util.NoSuchElementException;
>
> import com.db4o.ObjectContainer;
> import com.db4o.ObjectSet;
> import com.db4o.query.Query;
>
> import freenet.keys.FreenetURI;
> -import freenet.support.DoublyLinkedList;
> import freenet.support.IndexableUpdatableSortedLinkedListItem;
> import freenet.support.UpdatableSortedLinkedListItemImpl;
> import freenet.support.UpdatableSortedLinkedListKilledException;
> import freenet.support.UpdatableSortedLinkedListWithForeignIndex;
> -import freenet.support.DoublyLinkedList.Item;
>
> /**
> * @author xor
> *
> */
> -public class FMSBoard extends UpdatableSortedLinkedListItemImpl implements
IndexableUpdatableSortedLinkedListItem {
> -
> - private ObjectContainer db;
> +public class FMSBoard {
>
> - /**
> - * 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 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 transient final ObjectContainer db;
>
> - private final FMSBoard self = this;
> -
> - private final FMSMessageManager mMessageManager;
> -
> + private transient final FMSBoard self = this;
> +
> + private transient final FMSMessageManager mMessageManager;
> +
> private final String mName;
> -
> - private String mDescription;
> -
> +
> /**
> * Get a list of fields which the database should create an index on.
> */
> @@ -59,65 +37,56 @@
> return new String[] {"mName"};
> }
>
> - public FMSBoard(FMSMessageManager newMessageManager, String newName,
String newDescription) {
> + public FMSBoard(ObjectContainer myDB, FMSMessageManager
> newMessageManager,
String newName) {
> if(newName==null || newName.length() == 0)
> throw new IllegalArgumentException("Empty board name.");
> -
> +
> + assert(myDB != null);
> assert(newMessageManager != null);
> +
> + db = myDB;
> mMessageManager = newMessageManager;
> - // FIXME: Remove anything dangerous from name and description.
> + // FIXME: Validate name and description.
> mName = newName;
> - setDescription(newDescription);
> +
> + db.store(this);
> + db.commit();
> }
>
> /**
> - * @return the Description
> + * @return The name.
> */
> - public String getDescription() {
> - return mDescription;
> - }
> -
> - /**
> - * @param description The description to set.
> - */
> - public void setDescription(String newDescription) {
> - //FIXME: Remove anything dangerous from description.
> - mDescription = newDescription!=null ? newDescription : "";
> - }
> -
> - /**
> - * @return The name
> - */
> public String getName() {
> 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(newMessage.isThread()) { /* The message is a thread */
> - mThreads.add(newMessage);
> - }
> - else
> + public synchronized void addMessage(FMSMessage newMessage) throws
UpdatableSortedLinkedListKilledException {
> + db.store(newMessage);
> + db.commit();
> +
> + if(!newMessage.isThread())
> {
> FreenetURI parentURI = newMessage.getParentURI();
> FMSMessage parentMessage =
> mMessageManager.get(parentURI); /* TODO: This
allows crossposting. Figure out whether we need to handle it specially */
> + FMSMessage parentThread = findParentThread(newMessage);
> +
> + if(parentThread != null)
> + newMessage.setThread(parentThread);
> +
> if(parentMessage != null) {
> - parentMessage.addChild(newMessage);
> - db.store(parentMessage);
> + newMessage.setParent(parentMessage);
Are you forgetting to store 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 */
> - db.store(parentThread);
> + newMessage.setParent(parentThread);
> /* 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);
> -
> + else {
> + /* The message is an absolute orphan */
> +
> /*
> * 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.
> @@ -126,70 +95,84 @@
> }
> }
> }
> -
> - db.commit();
> -
> +
> linkOrphansToNewParent(newMessage);
> }
> -
> - private void linkOrphansToNewParent(FMSMessage newMessage) throws
UpdatableSortedLinkedListKilledException {
> +
> + private synchronized 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);
> - mThreads.remove(o);
> - }
> + Iterator<FMSMessage> absoluteOrphans =
absoluteOrphanIterator(newMessage.getURI());
> + while(absoluteOrphans.hasNext()){ /* Search in
> the absolute orphans for
messages which belong to this thread */
> + FMSMessage orphan = absoluteOrphans.next();
> + orphan.setParent(newMessage);
> }
> }
> else {
> - FMSMessage parentThread =
(FMSMessage)mThreads.get(newMessage.getParentThreadURI());
> + FMSMessage parentThread = newMessage.getThread();
> if(parentThread != null) { /* Search in its parent
> thread for its
children */
> - Iterator<FMSMessage> iter =
> parentThread.childrenIterator();
> + Iterator<FMSMessage> iter =
> parentThread.childrenIterator(this);
> 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);
> +
> parentThreadChild.setParent(newMessage); /* It's a child of the
newMessage, not of the parentThread */
> }
> }
> - db.store(parentThread);
> - } 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);
> - }
> + }
> + else { /* The new message is an absolute orphan, find
> its children
amongst the other absolute orphans */
> + Iterator<FMSMessage> absoluteOrphans =
absoluteOrphanIterator(newMessage.getURI());
> + while(absoluteOrphans.hasNext()){ /*
> Search in the orphans for messages
which belong to this message */
> + FMSMessage orphan =
> absoluteOrphans.next();
> + /*
> + * The following if() could be joined
> into the db4o query in
absoluteOrphanIterator(). I did not do it because we could
> + * cache the list of absolute orphans
> locally.
> + */
> +
> if(orphan.getParentURI().equals(newMessage.getURI()))
> + orphan.setParent(newMessage);
> }
> }
> }
> + }
> +
> + protected synchronized FMSMessage findParentThread(FMSMessage m) {
> + Query q = db.query();
> + q.constrain(FMSMessage.class);
> + /* FIXME: I assume that db4o is configured to keep an URI index
> per
board. We still have to ensure in FMS.java that it is configured to do so.
> + * If my second assumption - that the descend() statements are
> evaluated
in the specified order - is true, then it might be faste because the
> + * URI index is smaller per board than the global URI index. */
> + q.descend("mBoards").constrain(mName);
> + q.descend("mURI").constrain(m.getParentThreadURI());
You might need to do and() here, according to the api docs:
q.descend("mBoards").constain(mName).and(q.descend("mURI").constrain(m.getParentThreadURI());
> + ObjectSet<FMSMessage> parents = q.execute();
>
> - db.store(newMessage);
> - db.commit();
> + assert(parents.size() <= 1);
> +
> + return (parents.size() != 0 ? parents.next() : null);
> }
>
>
> /**
> - * Get all messages in the board. The view is specified to the
FMSOwnIdentity displaying it, therefore you have to pass one as parameter.
> + * Get all threads in the board. The view is specified to the
FMSOwnIdentity displaying it, therefore you have to pass one as parameter.
> * @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> threadIterator(final
FMSOwnIdentity identity) {
> return new Iterator<FMSMessage>() {
> private final FMSOwnIdentity mIdentity = identity;
> - private final ObjectSet<FMSMessage> mMessages;
> private final Iterator<FMSMessage> iter;
> private FMSMessage next;
>
> {
> + /* FIXME: If db4o supports precompiled queries,
> this one should be
stored precompiled.
> + * Reason: We sort the threads by date.
> + * Maybe we can just keep the Query-object and
> call q.execute() as many
times as we like to?
> + * Or somehow tell db4o to keep a per-board
> thread index which is
sorted by Date? - This would be the best solution */
Recommend you make a tag object which is only created for top level threads,
then this becomes reasonably easy ...
> Query q = db.query();
> q.constrain(FMSMessage.class);
> q.descend("mBoards").constrain(mName); /*
> FIXME: mBoards is an array.
Does constrain() check whether it contains the element mName? */
> - q.descend("mParentURI").constrain(null);
> - q.orderDescending();
> - mMessages = q.execute();
> - iter = mMessages.iterator();
> + q.descend("mThread").constrain(null);
> + q.descend("mDate").orderDescending();
> +
> + iter = q.execute().iterator();
> next = iter.hasNext() ? iter.next() : null;
> }
>
> @@ -214,19 +197,38 @@
>
> };
> }
> -
> - /* (non-Javadoc)
> - * @see
freenet.support.IndexableUpdatableSortedLinkedListItem#indexValue()
> +
> + /**
> + * Get an iterator over messages for which the parent thread with the
given URI was not known.
> */
> - public Object indexValue() {
> - return mName;
> - }
> + public synchronized Iterator<FMSMessage> absoluteOrphanIterator(final
FreenetURI thread) {
> + return new Iterator<FMSMessage>() {
> + private final ObjectSet<FMSMessage> mMessages;
> + private final Iterator<FMSMessage> iter;
>
> - /* (non-Javadoc)
> - * @see java.lang.Comparable#compareTo(java.lang.Object)
> - */
> - public int compareTo(Object o) {
> - FMSBoard b = (FMSBoard)o;
> - return mName.compareTo(b.getName());
> + {
> + /* FIXME: This query should be accelerated. The
> amount of absolute
orphans is very small usually, so we should configure db4o
> + * to keep a separate list of those. */
Again use a tag object.
> + Query q = db.query();
> + q.constrain(FMSMessage.class);
> + q.descend("mBoards").constrain(mName); /*
> FIXME: mBoards is an array.
Does constrain() check whether it contains the element mName? */
> + q.descend("mThreadURI").constrain(thread);
> + q.descend("mThread").constrain(null);
> + mMessages = q.execute();
> + iter = mMessages.iterator();
> + }
> +
> + public boolean hasNext() {
> + return mMessages.hasNext();
> + }
> +
> + public FMSMessage next() {
> + return mMessages.next();
> + }
> +
> + public void remove() {
> + throw new UnsupportedOperationException();
> + }
> + };
> }
> }
>
> Modified: trunk/plugins/FMSPlugin/FMSIdentityManager.java
> ===================================================================
> --- trunk/plugins/FMSPlugin/FMSIdentityManager.java 2008-11-04 10:24:00 UTC
(rev 23305)
> +++ trunk/plugins/FMSPlugin/FMSIdentityManager.java 2008-11-04 12:13:55 UTC
(rev 23306)
> @@ -3,21 +3,51 @@
> * http://www.gnu.org/ for further details of the GPL. */
> package plugins.FMSPlugin;
>
> +import java.util.Iterator;
> import java.util.Set;
>
> +import com.db4o.ObjectContainer;
> +import com.db4o.ObjectSet;
> +
> +import plugins.FMSPlugin.WoT.FMSIdentityWoT;
> +import plugins.FMSPlugin.WoT.FMSOwnIdentityWoT;
> +
> import freenet.support.Executor;
>
> /**
> * @author saces, xor
> - *
> + *
> */
> -public abstract class FMSIdentityManager {
> +public abstract class FMSIdentityManager implements Iterable<FMSIdentity> {
>
> - private final Executor mExecutor;
> + protected final ObjectContainer db;
>
> - public FMSIdentityManager(Executor newExecutor) {
> + protected final Executor mExecutor;
> +
> + public FMSIdentityManager(ObjectContainer myDB, Executor newExecutor) {
> + db = myDB;
> mExecutor = newExecutor;
> + }
>
> + public synchronized Iterator<FMSIdentity> iterator() {
> + ObjectSet<FMSIdentity> ids = db.query(FMSIdentity.class);
> + return ids.iterator();
> }
>
> + public synchronized Iterator<FMSOwnIdentity> ownIdentityIterator() {
> + ObjectSet<FMSOwnIdentity> oids = db.query(FMSOwnIdentity.class);
> + return oids.iterator();
> + }
> +
> + public synchronized boolean anyOwnIdentityWantsMessagesFrom(FMSIdentity
identity) {
> + Iterator<FMSOwnIdentity> iter = ownIdentityIterator();
> +
> + while (iter.hasNext()) {
> + FMSOwnIdentity oid = iter.next();
> + if (oid.wantsMessagesFrom(identity))
> + return true;
> + }
> +
> + return false;
> + }
> }
>
> Modified: trunk/plugins/FMSPlugin/FMSMessage.java
> ===================================================================
> --- trunk/plugins/FMSPlugin/FMSMessage.java 2008-11-04 10:24:00 UTC (rev
23305)
> +++ trunk/plugins/FMSPlugin/FMSMessage.java 2008-11-04 12:13:55 UTC (rev
23306)
> @@ -5,10 +5,14 @@
>
> import java.util.Arrays;
> import java.util.Date;
> +import java.util.HashSet;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Set;
>
> +import com.db4o.ObjectContainer;
> +import com.db4o.query.Query;
> +
> import freenet.keys.FreenetURI;
> import freenet.support.IndexableUpdatableSortedLinkedListItem;
> import freenet.support.UpdatableSortedLinkedList;
> @@ -19,8 +23,10 @@
> * @author saces, xor
> *
> */
> -public abstract class FMSMessage extends UpdatableSortedLinkedListItemImpl
implements IndexableUpdatableSortedLinkedListItem {
> +public abstract class FMSMessage {
>
> + protected ObjectContainer db;
> +
You cannot rely on db being kept up to date.
> /**
> * The URI of this message.
> */
> @@ -63,18 +69,23 @@
> private final FreenetURI[] mAttachments;
>
> /**
> - * The replies to this messages.
> + * The thread to which this message is a reply.
> */
> - private UpdatableSortedLinkedList mChildren = new
UpdatableSortedLinkedList();
> + private FMSMessage mThread = null;
>
> /**
> + * The message to which this message is a reply.
> + */
> + private FMSMessage mParent = null;
> +
> + /**
> * Get a list of fields which the database should create an index on.
> */
> public static String[] getIndexedFields() {
> - return new String[] { "mURI", "mBoards" };
> + return new String[] { "mURI", "mThreadURI", "mBoards"};
> }
>
> - public FMSMessage(FreenetURI newURI, FreenetURI newThreadURI,
> FreenetURI
newParentURI, Set<FMSBoard> newBoards, FMSIdentity newAuthor, String
newTitle, Date newDate, String newText, List<FreenetURI> newAttachments) {
> + public FMSMessage(ObjectContainer db, FreenetURI newURI, FreenetURI
newThreadURI, FreenetURI newParentURI, Set<FMSBoard> newBoards, FMSIdentity
newAuthor, String newTitle, Date newDate, String newText, List<FreenetURI>
newAttachments) {
> if (newURI == null || newBoards == null || newAuthor == null)
> throw new IllegalArgumentException();
>
> @@ -167,40 +178,64 @@
> return mAttachments;
> }
>
> - public synchronized void addChild(FMSMessage newChild) throws
UpdatableSortedLinkedListKilledException {
> - if(mChildren.contains(newChild)) {
> - assert(false); // TODO: check whether this should be
> allowed to happen.
> - return;
> - }
> -
> - mChildren.add(newChild);
> + public synchronized FMSMessage getThread() {
> + return mThread;
> }
>
> - public synchronized Iterator<FMSMessage> childrenIterator() {
> - return mChildren.iterator();
> + public synchronized void setThread(FMSMessage newParentThread) {
> + assert(mThread == null);
> + assert(mThreadURI == null);
> + mThread = newParentThread;
> + db.store(this);
> + db.commit();
> }
>
> - /**
> - * Compare by Date to the other FMSMessage.
> - * @param o An object of type FMSMessage
> - */
> - public int compareTo(Object o) {
> - FMSMessage m = (FMSMessage)o;
> - return mDate.compareTo(m.getDate());
> + public synchronized FMSMessage getParent() {
> + return mParent;
> }
> +
> + public synchronized void setParent(FMSMessage newParent) throws
UpdatableSortedLinkedListKilledException {
> + /* TODO: assert(newParent contains at least one board which
> mBoards
contains) */
Does that have to be true? In NNTP, the user can reply to any board he wants
to reply to ...
> + mParent = newParent;
> + db.store(this);
> + db.commit();
> + }
>
> - /**
> - * Get the index value for IndexableUpdatableSortedLinkedListItem.
> - */
> - public Object indexValue() {
> - return mURI;
> + public synchronized Iterator<FMSMessage> childrenIterator(final
> FMSBoard
board) {
> + return new Iterator<FMSMessage>() {
> + private Iterator<FMSMessage> iter;
> +
> + {
> + /* TODO: Accelerate this query: configure db4o
> to keep a per-message
date-sorted index of children.
> + * - Not very important for now since threads
> are usually small. */
I don't think that's possible. But as you said, it should be small, so
grabbing all the children from an index (as below) and then sorting by date
is not a big deal.
> + Query q = db.query();
> + q.constrain(FMSMessage.class);
> + q.descend("mBoard").constrain(board.getName());
> + q.descend("mParent").constrain(this);
> + q.descend("mDate").orderDescending();
> +
> + iter = q.execute().iterator();
> + }
> +
> + public boolean hasNext() {
> + return iter.hasNext();
> + }
> +
> + public FMSMessage next() {
> + return iter.next();
> + }
> +
> + public void remove() {
> + throw new UnsupportedOperationException("Use
> child.setParent(null)
instead.");
> + }
> + };
> }
>
> /**
> * Checks whether the title of the message is valid. Validity
> conditions:
> * - ...
> */
> - static boolean isTitleValid(String title) {
> + static public boolean isTitleValid(String title) {
> // FIXME: Implement.
> return true;
> }
> @@ -209,7 +244,7 @@
> * Checks whether the text of the message is valid. Validity conditions:
> * - ...
> */
> - static boolean isTextValid(String text) {
> + static public boolean isTextValid(String text) {
> // FIXME: Implement.
> return true;
> }
> @@ -218,7 +253,7 @@
> * Makes the passed title valid in means of <code>isTitleValid()</code>
> * @see isTitleValid
> */
> - static String makeTitleValid(String title) {
> + static public String makeTitleValid(String title) {
> // FIXME: Implement.
> return title;
> }
> @@ -227,7 +262,7 @@
> * Makes the passed text valid in means of <code>isTextValid()</code>
> * @see isTextValid
> */
> - static String makeTextValid(String text) {
> + static public String makeTextValid(String text) {
> // FIXME: Implement.
> return text;
> }
>
> Modified: trunk/plugins/FMSPlugin/FMSMessageManager.java
> ===================================================================
> --- trunk/plugins/FMSPlugin/FMSMessageManager.java 2008-11-04 10:24:00 UTC
(rev 23305)
> +++ trunk/plugins/FMSPlugin/FMSMessageManager.java 2008-11-04 12:13:55 UTC
(rev 23306)
> @@ -17,43 +17,59 @@
> *
> */
> public abstract class FMSMessageManager {
> -
> +
> protected ObjectContainer db;
> -
> - /**
> - * Contains all boards which where found in a message. References to
> all
messages of a board are stored in
> - * the board. Adding a newly downloaded message therefore is done by
searching its board and calling
> - * <code>addMessage()</code> on that board. Further, the message is
> also
added to mMessages, see below.
> - */
> - protected UpdatableSortedLinkedListWithForeignIndex mBoards = new
UpdatableSortedLinkedListWithForeignIndex();
> -
> +
> + protected FMSIdentityManager mIdentityManager;
> +
> + public FMSMessageManager(ObjectContainer myDB, FMSIdentityManager
myIdentityManager) {
> + assert(myDB != null);
> + assert(myIdentityManager != null);
> +
> + db = myDB;
> + mIdentityManager = myIdentityManager;
> + }
> +
> public synchronized FMSMessage get(FreenetURI uri) {
> Query query = db.query();
> query.constrain(FMSMessage.class);
> query.descend("mURI").constrain(uri);
> ObjectSet<FMSMessage> result = query.execute();
> -
> +
> + assert(result.size() <= 1);
> +
> return (result.size() == 0) ? null : result.next();
> }
> -
> +
> public synchronized FMSBoard getBoardByName(String name) {
> - return (FMSBoard)mBoards.get(name);
> + Query query = db.query();
> + query.constrain(FMSBoard.class);
> + query.descend("mName").constrain(name);
> + ObjectSet<FMSBoard> result = query.execute();
> +
> + assert(result.size() <= 1);
> +
> + return (result.size() == 0) ? null : result.next();
> }
> -
> +
> /**
> - * Get an iterator of boards which the identity could subscribe to.
> - * @param identity
> - * @return
> + * Get an iterator of all boards.
> */
> - public synchronized Iterator<FMSBoard> boardIterator(FMSOwnIdentity
identity) {
> - return (Iterator<FMSBoard>)mBoards.iterator();
> + public synchronized Iterator<FMSBoard> boardIterator() {
> + /* FIXME: Accelerate this query. db4o should be configured to
> keep an
alphabetic index of boards */
No problem, just create the index...
> + Query query = db.query();
> + query.constrain(FMSBoard.class);
> + query.descend("mName").orderDescending();
Why backwards?
> +
> + ObjectSet<FMSBoard> result = query.execute();
> +
> + return result.iterator();
> }
> -
>
> /**
> * Returns true if the message was not downloaded yet and any of the
FMSOwnIdentity wants the message.
> - * @param uri
> - * @return
> */
> - protected abstract boolean shouldDownloadMessage(FreenetURI uri);
> + protected synchronized boolean shouldDownloadMessage(FreenetURI uri,
FMSIdentity author) {
> + return (get(uri) != null) ||
mIdentityManager.anyOwnIdentityWantsMessagesFrom(author);
Why do we return true here if we already have the message?
> + }
> }
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: not available
URL:
<https://emu.freenetproject.org/pipermail/devl/attachments/20081111/799454fd/attachment.pgp>