<commit_before>/* Copyright (c) 2008-2017 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * MRtrix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * For more details, see http://www.mrtrix.org/.
 */


#ifndef __gt_particlepool_h__
#define __gt_particlepool_h__

#include <deque>
#include <stack>
#include <mutex>

#include "math/rng.h"

#include "dwi/tractography/GT/particle.h"

namespace MR {
  namespace DWI {
    namespace Tractography {
      namespace GT {
        
        /**
         * @brief ParticlePool manages creation and deletion of particles,
         *        minimizing the no. calls to new/delete.
         */
        class ParticlePool
        { MEMALIGN(ParticlePool)
        public:
          ParticlePool() { }
          
          ParticlePool(const ParticlePool&) = delete;
          ParticlePool& operator=(const ParticlePool&) = delete;
          ~ParticlePool() { }
          
          /**
           * @brief Creates a new particle and returns a pointer to its address.
           */
          Particle* create(const Point_t& pos, const Point_t& dir)
          {
            std::lock_guard<std::mutex> lock (mutex);
            if (avail.empty()) {
              pool.emplace_back(pos, dir);
              return &pool.back();
            } else {
              Particle* p = avail.top();
              p->init(pos, dir);
              avail.pop();
              return p;
            }
          }
          
          /**
           * @brief Destroys the particle at pointer p.
           */
          void destroy(Particle* p) {
            std::lock_guard<std::mutex> lock (mutex);
            p->finalize();
            avail.push(p);
          }
          
          /**
           * @brief Return number of Particles in the pool.
           */
          inline size_t size() const {
            return pool.size() - avail.size();
          }
          
          /**
           * @brief Select random particle from the pool (uniformly).
           */
          Particle* random() {
            std::lock_guard<std::mutex> lock (mutex);
            if (pool.size() > avail.size())
            {
              std::uniform_int_distribution<size_t> dist(0, pool.size()-1);
              for (int k = 0; k != 5; ++k) {
                Particle* p = &pool[dist(rng)];
                if (p->isAlive())
                  return p;
              }
            }
            return nullptr;
          }
          
          /**
           * @brief Clear pool.
           */
          void clear() {
            std::lock_guard<std::mutex> lock (mutex);
            pool.clear();
            std::stack<Particle*> e {};
            avail.swap(e);
          }
          
        protected:
          std::mutex mutex;
          std::deque<Particle> pool;
          std::stack<Particle*> avail;
          Math::RNG rng;
        };<commit_msg>tckglobal: Fix memory alignment in deque and stack.<commit_after>/* Copyright (c) 2008-2017 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * MRtrix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * For more details, see http://www.mrtrix.org/.
 */


#ifndef __gt_particlepool_h__
#define __gt_particlepool_h__

#include <deque>
#include <stack>
#include <mutex>

#include "math/rng.h"

#include "dwi/tractography/GT/particle.h"

namespace MR {
  namespace DWI {
    namespace Tractography {
      namespace GT {
        
        /**
         * @brief ParticlePool manages creation and deletion of particles,
         *        minimizing the no. calls to new/delete.
         */
        class ParticlePool
        { MEMALIGN(ParticlePool)
        public:
          ParticlePool() { }
          
          ParticlePool(const ParticlePool&) = delete;
          ParticlePool& operator=(const ParticlePool&) = delete;
          ~ParticlePool() { }
          
          /**
           * @brief Creates a new particle and returns a pointer to its address.
           */
          Particle* create(const Point_t& pos, const Point_t& dir)
          {
            std::lock_guard<std::mutex> lock (mutex);
            if (avail.empty()) {
              pool.emplace_back(pos, dir);
              return &pool.back();
            } else {
              Particle* p = avail.top();
              p->init(pos, dir);
              avail.pop();
              return p;
            }
          }
          
          /**
           * @brief Destroys the particle at pointer p.
           */
          void destroy(Particle* p) {
            std::lock_guard<std::mutex> lock (mutex);
            p->finalize();
            avail.push(p);
          }
          
          /**
           * @brief Return number of Particles in the pool.
           */
          inline size_t size() const {
            return pool.size() - avail.size();
          }
          
          /**
           * @brief Select random particle from the pool (uniformly).
           */
          Particle* random() {
            std::lock_guard<std::mutex> lock (mutex);
            if (pool.size() > avail.size())
            {
              std::uniform_int_distribution<size_t> dist(0, pool.size()-1);
              for (int k = 0; k != 5; ++k) {
                Particle* p = &pool[dist(rng)];
                if (p->isAlive())
                  return p;
              }
            }
            return nullptr;
          }
          
          /**
           * @brief Clear pool.
           */
          void clear() {
            std::lock_guard<std::mutex> lock (mutex);
            pool.clear();
            std::stack<Particle*, vector<Particle*> > e {};
            avail.swap(e);
          }
          
        protected:
          std::mutex mutex;
          std::deque<Particle, Eigen::aligned_allocator<Particle> > pool;
          std::stack<Particle*, vector<Particle*> > avail;
          Math::RNG rng;
        };
{'fraction_non_alphanumeric': 0.11117964533538936, 'fraction_numerical': 0.005242868157286045, 'mean_word_length': 1.4708571428571429, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '916822', 'n_tokens_mistral': 1832, 'n_tokens_neox': 1776, 'n_words': 502}