text: /*****************************************************************************
  *
  * Copyright (c) 2000 - 2014, Lawrence Livermore National Security, LLC
  * Produced at the Lawrence Livermore National Laboratory
  * LLNL-CODE-442911
  * All rights reserved.
  *
  * This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
  * full copyright notice is contained in the file COPYRIGHT located at the root
  * of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
  *
  * Redistribution  and  use  in  source  and  binary  forms,  with  or  without
  * modification, are permitted provided that the following conditions are met:
  *
  *  - Redistributions of  source code must  retain the above  copyright notice,
  *    this list of conditions and the disclaimer below.
  *  - Redistributions in binary form must reproduce the above copyright notice,
  *    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
  *    documentation and/or other materials provided with the distribution.
  *  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
  *    be used to endorse or promote products derived from this software without
  *    specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
  * ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
  * LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
  * DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
  * CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
  * LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
  * OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  *
  *****************************************************************************/
  
  // ************************************************************************* //
  //                        avtDatasetOnDemandFilter.h                         //
  // ************************************************************************* //
  
  #ifndef AVT_DATASET_ON_DEMAND_FILTER_H
  #define AVT_DATASET_ON_DEMAND_FILTER_H
  
  #include <filters_exports.h>
  
  #include <avtDatasetToDataObjectFilter.h>
  #include <list>
  
  #include <vtkDataSet.h>
  #include <vtkVisItCellLocator.h>
  
  class  avtExtents;
  
  // ****************************************************************************
  //  Class: avtDatasetOnDemandFilter
  //
  //  Purpose:
  //     Helper class for list of entries 
  //
  //  Programmer: Hank Childs
  //  Creation:   March 1, 2008
  //
  //  Modifications:
  //    Gunther H. Weber, Fri Apr  3 17:32:29 PDT 2009
  //    Added visitCellLocator entry and a constructor that ensures that it
  //    is set to 0 (because if the value is different from 0 the destructor
  //    of avtDatasetOnDemandFilter will call Delete() on it.
  //
  //    Hank Childs, Sat Apr 11 23:26:01 CDT 2009
  //    Overhaul how reference counting is done to fix a memory leak with caching.
  //
  // **************************************************************************** 
  
  struct DomainCacheEntry
  {
      vtkDataSet *ds;
      int domainID, timeStep;
      vtkVisItCellLocator* cl;
  
      DomainCacheEntry() : ds(0), timeStep(-1), cl(0) {}
      ~DomainCacheEntry() 
             { if (ds != NULL) ds->Delete(); if (cl!= NULL) cl->Delete(); };
      DomainCacheEntry(const DomainCacheEntry &dce) 
             { ds = dce.ds; if (ds!=NULL) ds->Register(NULL);
               cl = dce.cl; if (cl!=NULL) cl->Register(NULL);
               domainID = dce.domainID; timeStep = dce.timeStep; };
      DomainCacheEntry       &operator=(const DomainCacheEntry &dce) 
             {  if (ds != NULL) ds->Delete(); 
                if (cl != NULL) cl->Delete(); 
                ds = dce.ds; if (ds!=NULL) ds->Register(NULL);
                cl = dce.cl; if (cl!=NULL) cl->Register(NULL);
                domainID = dce.domainID; timeStep = dce.timeStep; 
                return *this; 
             };
  };
  
  
  // ****************************************************************************
  //  Class: avtDatasetOnDemandFilter
  //
  //  Purpose:
  //      A derived type of avtDatasetToDatasetFilter.  This will pull in chunks
  //      of a larger data set on demand.
  //
  //  Programmer: Hank Childs
  //  Creation:   March 1, 2008
  //
  //  Modifications:
  //
  //    Hank Childs, Sun Mar  9 07:47:05 PST 2008
  //    Add UpdateDataObjectInfo.
  //
  //    Dave Pugmire, Thu Mar 13 08:44:18 EDT 2008
  //    Added DomainLoaded query function.
  //    Added ability to control the number of cached domains.
  //
  //    Hank Childs, Thu Jun 12 15:39:13 PDT 2008
  //    Added support for preventing on demand operation.
  //
  //    Dave Pugmire, Mon Jan 26 13:04:56 EST 2009
  //    Added purgeDSCount and access function.
  //
  //    Dave Pugmire, Tue Feb  3 11:05:24 EST 2009
  //    Added loadDSCount and access function
  //
  //    Dave Pugmire, Tue Mar 10 12:41:11 EDT 2009
  //    Added support for time/domain.
  //
  //    Hank Childs, Sun Mar 22 13:31:08 CDT 2009
  //    Add support for getting data around a point.
  //
  //    Dave Pugmire, Wed Mar 25 09:15:23 EDT 2009
  //    Add domain caching for point decomposed domains.
  //
  //    Dave Pugmire, Sat Mar 28 09:42:15 EDT 2009
  //    Counter to keep track of how many times a domain is loaded.
  //
  //    Gunther H. Weber, Fri Apr  3 17:40:05 PDT 2009
  //    Removed map from domain id to cell locator since we currently
  //    use the same domain id for all point based data load operations.
  //
  //    Hank Childs, Mon Apr 20 08:40:07 PDT 2009
  //    Change inheritance so that output can be non-datasets.
  //
  //    David Camp, Tue May  3 06:51:37 PDT 2011
  //    Added virtual function PurgeDomain() to let the PICs filter delete the
  //    cell locator and any other resoures to do this a dataset.
  //
  // **************************************************************************** 
  
  class AVTFILTERS_API avtDatasetOnDemandFilter : virtual public 
                                                     avtDatasetToDataObjectFilter
  {
    public:
                                   avtDatasetOnDemandFilter();
       virtual                    ~avtDatasetOnDemandFilter();
  
       void                        CopyCache(avtDatasetOnDemandFilter *);
  
    protected:
      virtual bool                 DomainLoaded(int, int) const;
      void                         GetLoadedDomains(std::vector<std::vector<int> > &domains);
      void                         SetMaxQueueLength(int len) { maxQueueLength = len; }
      virtual vtkDataSet           *GetDomain(int, int);
      virtual vtkDataSet           *GetDataAroundPoint(double, double, double, int);
      avtContract_p                ModifyContract(avtContract_p);
      virtual void                 UpdateDataObjectInfo(void);
  
      // Note: this method only produces valid results *after* ModifyContract
      // is called.
      virtual bool                 OperatingOnDemand(void) const { return operatingOnDemand; }
      virtual bool                 CheckOnDemandViability(void) { return true; }
  
      // This needs to do something else......
      void                         SetOperatingOnDemand( bool v ) { operatingOnDemand = v; }
  
      virtual void                 PurgeDomain( const int domain, const int timeStep ) = 0;
      void                         EmptyQueue();
  
  protected:
      int                          GetPurgeDSCount() const { return purgeDSCount; }
      int                          GetLoadDSCount() const { return loadDSCount; }
  
      std::map<unsigned long, int>           domainLoadCount;
  
    private:
      std::list<DomainCacheEntry>  domainQueue;
      int                          maxQueueLength;
      avtContract_p                firstContract;
      avtContract_p                lastUsedContract;
      bool                         operatingOnDemand;
      int                          purgeDSCount, loadDSCount;
  };
  
  #endif
  
  