Neighbours.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 CSIRO ICT Centre
00003  *
00004  * $Id: Neighbours.cpp 587 2004-12-03 15:06:33Z nch $
00005  */
00006 
00007 #include "String.h"
00008 
00009 #include "ActiveList.h"
00010 #include "ActiveObject.h"
00011 #include "Neighbours.h"
00012 #include "Object.h"
00013 #include "ObjectConsumer.h"
00014 #include "ObjectPairConsumer.h"
00015 #include "ObjectProducer.h"
00016 #include "Profiler.h"
00017 #include "Matcher.h"
00018 
00019 
00020 String const Neighbours::s_name("Neighbours");
00021 
00022 
00023 Neighbours::Neighbours(ObjectProducer * prod,
00024                        ActiveList * aList,
00025                        ObjectPairConsumer * pairCons,
00026                        ObjectConsumer * uCons,
00027                        double maxD)
00028     : Matcher(pairCons, true),
00029       producer(prod),
00030       uConsumer(uCons),
00031       activeList(aList),
00032       testActive(0),
00033       testObj(0),
00034       testMatchedPreviously(false),
00035       currentObj(0),
00036       maxDistance(maxD)
00037 {
00038 }
00039 
00040 Neighbours::~Neighbours()
00041 {
00042   delete producer;
00043   delete activeList;
00044 }
00045 
00046 void Neighbours::getReady()
00047 {
00048   Matcher::getReady();
00049 
00050 #ifdef PROFILE
00051 #ifdef PROFILE_ACTIVE_LIST
00052   activeList->setProfiler(profiler);
00053 #endif // PROFILE_ACTIVE_LIST
00054 #endif // PROFILE
00055 }
00056 
00057 void Neighbours::finished()
00058 {
00059   /* the active list will be empty, so no need to call it's finished method */
00060 
00061   uConsumer->finished();
00062 
00063   Matcher::finished();
00064 }
00065 
00066 void Neighbours::doFilter()
00067 {
00068   Object const * testObject = nextObject(producer);
00069 
00070   while (testObject != 0)
00071   {
00072     double lowerBound = getLowerBound(testObject);
00073 
00074     activeList->deletePriorObjects(lowerBound, uConsumer);
00075     bool matched = activeList->testObject(testObject, maxDistance, pairCons);
00076     activeList->pushBack(testObject, matched);
00077 
00078     testObject = nextObject(producer);
00079   }
00080 
00081   // no more test objects, but there may still be some in the active list
00082   activeList->clear(uConsumer);
00083 }
00084 
00085 Object const * Neighbours::nextActiveObject()
00086 {
00087   // Remember the active object. It may also be the test object!
00088 
00089   currentObj = nextObject(producer);
00090 
00091   return currentObj;
00092 }
00093 
00094 Object const * Neighbours::nextTestObject()
00095 {
00096   if (!activeList->isEmpty())
00097   {
00098     testActive = activeList->popFront();
00099     testObj = testActive->getObject();
00100     testMatchedPreviously = testActive->isMatched();
00101   }
00102   else if (currentObj == 0)
00103   {
00104     // we are finished the producer - or not yet started!
00105     testActive = 0;
00106     testObj = nextObject(producer);
00107     testMatchedPreviously = false;
00108   }
00109   else
00110   {
00111     testActive = 0;
00112     testObj = currentObj;
00113     testMatchedPreviously = false;
00114   }
00115 
00116   return testObj;
00117 }
00118 
00119 double Neighbours::getLowerBound(Object const * testObject)
00120 {
00121   return testObject->getDec() - maxDistance;
00122 }
00123 
00124 double Neighbours::getUpperBound(Object const * testObject)
00125 {
00126   return testObject->getDec() + maxDistance;
00127 }
00128 
00129 void Neighbours::addActiveObject(Object const * activeObject)
00130 {
00131   // be careful not to put the test object in!
00132   if (activeObject != testObj)
00133   {
00134     activeList->pushBack(activeObject);
00135   }
00136 }
00137 
00138 void Neighbours::reportActiveNoMatch(Object const * activeObj)
00139 {
00140   std::cout << "This should not happen!" << std::endl;
00141 
00142   std::cout << "test: ";
00143   if (currentObj == 0)
00144     std::cout << "null";
00145   else
00146     std::cout << *currentObj;
00147   std::cout << std::endl;
00148   std::cout << "active: " << *activeObj << std::endl;
00149 
00150   uConsumer->report(activeObj);
00151 }
00152 
00153 void Neighbours::reportTestNoMatch(Object const * activeObj)
00154 {
00155   uConsumer->report(activeObj);
00156 }
00157 
00158 bool Neighbours::test(Object const * testObject,
00159                       Object const * activeObject)
00160 {
00161   // first check they are not the same object
00162   return testObject != activeObject && Matcher::test(testObject, activeObject);
00163 }
00164 
00165 void Neighbours::test(Object const * testObj)
00166 {
00167   /* test this object against the active list. */
00168 
00169   bool matched = activeList->testObject(testObj, maxDistance, pairCons);
00170 
00171   if (!matched && !testMatchedPreviously)
00172   {
00173     uConsumer->report(testObj);
00174   }
00175   delete testObj;
00176 
00177   if (testActive != 0)
00178   {
00179     delete testActive;
00180     testActive = 0;
00181   }
00182 }
00183 
00184 void Neighbours::flushActiveObjects(double)
00185 {
00186   // nothing to do
00187 }
00188 
00189 void Neighbours::flushActiveObjects(Object const * activeObject)
00190 {
00191   if (activeObject != 0)
00192     addActiveObject(activeObject);
00193   while (!activeList->isEmpty())
00194   {
00195     ActiveObject * ao = activeList->popFront();
00196     Object const * testObj = ao->getObject();
00197     if (!activeList->testObject(testObj, maxDistance, pairCons) && !ao->isMatched())
00198     {
00199       uConsumer->report(testObj);
00200     }
00201     delete testObj;
00202     delete ao;
00203   }
00204 }
Generated on Mon Oct 4 10:39:55 2010 for Matching.kdevelop by  doxygen 1.6.3