text: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * Copyright 2012 The MITRE Corporation                                      *
   *                                                                           *
   * Licensed under the Apache License, Version 2.0 (the "License");           *
   * you may not use this file except in compliance with the License.          *
   * You may obtain a copy of the License at                                   *
   *                                                                           *
   *     http://www.apache.org/licenses/LICENSE-2.0                            *
   *                                                                           *
   * Unless required by applicable law or agreed to in writing, software       *
   * distributed under the License is distributed on an "AS IS" BASIS,         *
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
   * See the License for the specific language governing permissions and       *
   * limitations under the License.                                            *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  
  #include <openbr/plugins/openbr_internal.h>
  
  namespace br
  {
  
  /*!
   * \ingroup transforms
   * \brief Caches Transform::project() results.
   * \author Josh Klontz \cite jklontz
   */
  class CacheTransform : public MetaTransform
  {
      Q_OBJECT
      Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
      BR_PROPERTY(br::Transform*, transform, NULL)
  
      static QHash<QString, Template> cache;
      static QMutex cacheLock;
  
  public:
      ~CacheTransform()
      {
          if (cache.isEmpty()) return;
  
          // Write to cache
          QFile file("Cache");
          if (!file.open(QFile::WriteOnly))
              qFatal("Unable to open %s for writing.", qPrintable(file.fileName()));
          QDataStream stream(&file);
          stream << cache;
          file.close();
      }
  
  private:
      void init()
      {
          if (!transform) return;
  
          trainable = transform->trainable;
          if (!cache.isEmpty()) return;
  
          // Read from cache
          QFile file("Cache");
          if (file.exists()) {
              if (!file.open(QFile::ReadOnly))
                  qFatal("Unable to open %s for reading.", qPrintable(file.fileName()));
              QDataStream stream(&file);
              stream >> cache;
              file.close();
          }
      }
  
      void train(const QList<TemplateList> &data)
      {
          transform->train(data);
      }
  
      void project(const Template &src, Template &dst) const
      {
          const QString &file = src.file;
          if (cache.contains(file)) {
              dst = cache[file];
          } else {
              transform->project(src, dst);
              cacheLock.lock();
              cache[file] = dst;
              cacheLock.unlock();
          }
      }
  };
  
  QHash<QString, Template> CacheTransform::cache;
  QMutex CacheTransform::cacheLock;
  
  BR_REGISTER(Transform, CacheTransform)
  
  } // namespace br
  
  #include "core/cache.moc"
  