<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2015
Raffaello D. Di Napoli

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade 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. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#include <abaclade.hxx>
#include <abaclade/collections/detail/trie_ordered_multimap_impl.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////

namespace abc { namespace collections { namespace detail {

void scalar_keyed_trie_ordered_multimap_impl::list_node::unlink_and_destruct(
   type_void_adapter const & type
) const {
   if (m_plnNext) {
      m_plnNext->m_plnPrev = m_plnPrev;
   }
   if (m_plnPrev) {
      m_plnPrev->m_plnNext = m_plnNext;
   }
   type.destruct(value_ptr(type));
   memory::_raw_free(this);
}

void * scalar_keyed_trie_ordered_multimap_impl::list_node::value_ptr(
   type_void_adapter const & type
) const {
   return type.align_pointer(&m_plnPrev + 1);
}

scalar_keyed_trie_ordered_multimap_impl::scalar_keyed_trie_ordered_multimap_impl(
   scalar_keyed_trie_ordered_multimap_impl && tommi
) :
   m_pnRoot(tommi.m_pnRoot),
   m_cValues(tommi.m_cValues),
   mc_iTreeAnchorsLevel(tommi.mc_iTreeAnchorsLevel) {
   tommi.m_pnRoot = nullptr;
   tommi.m_cValues = 0;
}

scalar_keyed_trie_ordered_multimap_impl::list_node * scalar_keyed_trie_ordered_multimap_impl::add(
   type_void_adapter const & typeValue, std::uintmax_t iKey, void const * pValue, bool bMove
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, iKey, pValue, bMove);

   tree_node * ptnParent;
   unsigned iBitsPermutation;

   // Descend into the tree, creating nodes as necessary until the path for iKey is complete.
   {
      // ppnChildInParent points to *ptnParent’s parent’s pointer to *ptnParent.
      node ** ppnChildInParent = &m_pnRoot;
      std::uintmax_t iKeyRemaining = iKey;
      std::size_t iLevel = 0;
      do {
         ptnParent = static_cast<tree_node *>(*ppnChildInParent);
         if (!ptnParent) {
            ptnParent = (iLevel == mc_iTreeAnchorsLevel ? new anchor_node() : new tree_node());
            *ppnChildInParent = ptnParent;
         }
         iBitsPermutation = static_cast<unsigned>(
            iKeyRemaining & (smc_cBitPermutationsPerLevel - 1)
         );
         iKeyRemaining >>= smc_cBitsPerLevel;
         ppnChildInParent = &ptnParent->m_apnChildren[iBitsPermutation];
      } while (++iLevel <= mc_iTreeAnchorsLevel);
   }

   // We got here, so *ptnParent is actually an anchor_node.
   anchor_node * panParent = static_cast<anchor_node *>(ptnParent);
   /* To calculate the node size, add typeValue.size() bytes to the offset of the value in a node at
   address 0. This allows packing the node optimally even if the unpadded node size is e.g. 6
   (sizeof will return 8 for that) and typeValue.size() is 2, giving 8 instead of 10 (which would
   really mean at least 12 bytes, a 50% waste of memory). */
   std::unique_ptr<list_node, memory::freeing_deleter> pln(static_cast<list_node *>(
      memory::_raw_alloc(reinterpret_cast<std::size_t>(
         static_cast<list_node *>(0)->value_ptr(typeValue)
      ) + typeValue.size())
   ));
   void * pDst = pln->value_ptr(typeValue);
   if (bMove) {
      typeValue.move_construct(pDst, const_cast<void *>(pValue));
   } else {
      typeValue.copy_construct(pDst, pValue);
   }
   list_node * plnRet = pln.get(), * plnPrev = panParent->m_aplnChildrenLasts[iBitsPermutation];
   pln->m_plnPrev = plnPrev;
   pln->m_plnNext = nullptr;
   panParent->m_aplnChildrenLasts[iBitsPermutation] = plnRet;
   if (!panParent->m_apnChildren[iBitsPermutation]) {
      panParent->m_apnChildren[iBitsPermutation] = plnRet;
   }
   if (plnPrev) {
      plnPrev->m_plnNext = plnRet;
   }
   // Transfer ownership of the list_node to the list.
   pln.release();
   ++m_cValues;
   return plnRet;
}

void scalar_keyed_trie_ordered_multimap_impl::clear(type_void_adapter const & typeValue) {
   ABC_TRACE_FUNC(this/*, typeValue*/);

   if (m_pnRoot) {
      destruct_tree_node(typeValue, static_cast<tree_node *>(m_pnRoot), 0);
      m_pnRoot = nullptr;
      m_cValues = 0;
   }
}

scalar_keyed_trie_ordered_multimap_impl::indexed_anchor
scalar_keyed_trie_ordered_multimap_impl::descend_to_anchor(std::uintmax_t iKey) const {
   ABC_TRACE_FUNC(this, iKey);

   std::uintmax_t iKeyRemaining = iKey;
   tree_node * ptnParent = static_cast<tree_node *>(m_pnRoot);
   std::size_t iLevel = 0;
   for (;;) {
      unsigned iBitsPermutation = static_cast<unsigned>(
         iKeyRemaining & (smc_cBitPermutationsPerLevel - 1)
      );
      if (iLevel == mc_iTreeAnchorsLevel) {
         // At this level, *ptnParent is an anchor.
         return indexed_anchor(static_cast<anchor_node *>(ptnParent), iBitsPermutation);
      } else if (!ptnParent) {
         return indexed_anchor(nullptr, 0);
      }
      iKeyRemaining >>= smc_cBitsPerLevel;
      ptnParent = static_cast<tree_node *>(ptnParent->m_apnChildren[iBitsPermutation]);
      ++iLevel;
   }

}

void scalar_keyed_trie_ordered_multimap_impl::destruct_list(
   type_void_adapter const & type, list_node * pln
) {
   ABC_TRACE_FUNC(this/*, type*/, pln);

   while (pln) {
      list_node * plnNext = pln->m_plnNext;
      type.destruct(pln->value_ptr(type));
      memory::_raw_free(pln);
      pln = plnNext;
   }
}

void scalar_keyed_trie_ordered_multimap_impl::destruct_anchor_node(
   type_void_adapter const & typeValue, anchor_node * pan
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, pan);

   unsigned iBitsPermutation = 0;
   do {
      if (list_node * pln = static_cast<list_node *>(pan->m_apnChildren[iBitsPermutation])) {
         destruct_list(typeValue, pln);
      }
   } while (++iBitsPermutation < smc_cBitPermutationsPerLevel);
   delete pan;
}

void scalar_keyed_trie_ordered_multimap_impl::destruct_tree_node(
   type_void_adapter const & typeValue, tree_node * ptn, unsigned iLevel
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, ptn, iLevel);

   ++iLevel;
   unsigned iBitsPermutation = 0;
   do {
      if (node * pn = ptn->m_apnChildren[iBitsPermutation]) {
         if (iLevel == mc_iTreeAnchorsLevel) {
            destruct_anchor_node(typeValue, static_cast<anchor_node *>(pn));
         } else {
            destruct_tree_node(typeValue, static_cast<tree_node *>(pn), iLevel);
         }
      }
   } while (++iBitsPermutation < smc_cBitPermutationsPerLevel);
   delete ptn;
}

scalar_keyed_trie_ordered_multimap_impl::list_node * scalar_keyed_trie_ordered_multimap_impl::find(
   std::uintmax_t iKey
) {
   ABC_TRACE_FUNC(this, iKey);

   indexed_anchor ia(descend_to_anchor(iKey));
   return ia.pan ? static_cast<list_node *>(ia.pan->m_apnChildren[ia.iBitsPermutation]) : nullptr;
}

scalar_keyed_trie_ordered_multimap_impl::key_value_pair
scalar_keyed_trie_ordered_multimap_impl::front() {
   ABC_TRACE_FUNC(this);

   node * pnChild;
   std::uintmax_t iKey = 0;

   // Descend into the tree.
   tree_node * ptnParent = static_cast<tree_node *>(m_pnRoot);
   std::size_t iLevel = 0;
   unsigned cNextLevelBitsShift = 0;
   do {
      if (!ptnParent) {
         return key_value_pair(0, nullptr);
      }
      // Look for the left-most branch to descend into.
      unsigned iBitsPermutation = 0;
      do {
         pnChild = ptnParent->m_apnChildren[iBitsPermutation];
         if (pnChild) {
            // Prepend the selected bit permutation to the key.
            iKey |= static_cast<std::uintmax_t>(iBitsPermutation) << cNextLevelBitsShift;
            cNextLevelBitsShift += smc_cBitsPerLevel;
            break;
         }
      } while (++iBitsPermutation < smc_cBitPermutationsPerLevel);
      ptnParent = static_cast<tree_node *>(pnChild);
   } while (++iLevel <= mc_iTreeAnchorsLevel);

   /* We got here, so *pnChild is actually a value list’s first node, though pnChild might be
   nullptr. */
   return key_value_pair(iKey, static_cast<list_node *>(pnChild));
}

void scalar_keyed_trie_ordered_multimap_impl::remove_value(
   type_void_adapter const & typeValue, std::uintmax_t iKey, list_node * pln
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, iKey, pln);

   if (!pln->m_plnNext || !pln->m_plnPrev) {
      // *pln is the first or the last node in its list, so we need to update the anchor.
      indexed_anchor ia(descend_to_anchor(iKey));
      if (!ia.pan) {
         // TODO: throw invalid_iterator.
         ABC_THROW(generic_error, ());
      }
      if (!pln->m_plnNext) {
         ia.pan->m_aplnChildrenLasts[ia.iBitsPermutation] = nullptr;
      }
      if (!pln->m_plnPrev) {
         ia.pan->m_apnChildren[ia.iBitsPermutation] = nullptr;
      }
   }
   pln->unlink_and_destruct(typeValue);
   --m_cValues;
}

}}} //namespace abc::collections::detail
<commit_msg>Fix unlinking list nodes from anchors<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2015
Raffaello D. Di Napoli

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade 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. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#include <abaclade.hxx>
#include <abaclade/collections/detail/trie_ordered_multimap_impl.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////

namespace abc { namespace collections { namespace detail {

void scalar_keyed_trie_ordered_multimap_impl::list_node::unlink_and_destruct(
   type_void_adapter const & type
) const {
   if (m_plnNext) {
      m_plnNext->m_plnPrev = m_plnPrev;
   }
   if (m_plnPrev) {
      m_plnPrev->m_plnNext = m_plnNext;
   }
   type.destruct(value_ptr(type));
   memory::_raw_free(this);
}

void * scalar_keyed_trie_ordered_multimap_impl::list_node::value_ptr(
   type_void_adapter const & type
) const {
   return type.align_pointer(&m_plnPrev + 1);
}

scalar_keyed_trie_ordered_multimap_impl::scalar_keyed_trie_ordered_multimap_impl(
   scalar_keyed_trie_ordered_multimap_impl && tommi
) :
   m_pnRoot(tommi.m_pnRoot),
   m_cValues(tommi.m_cValues),
   mc_iTreeAnchorsLevel(tommi.mc_iTreeAnchorsLevel) {
   tommi.m_pnRoot = nullptr;
   tommi.m_cValues = 0;
}

scalar_keyed_trie_ordered_multimap_impl::list_node * scalar_keyed_trie_ordered_multimap_impl::add(
   type_void_adapter const & typeValue, std::uintmax_t iKey, void const * pValue, bool bMove
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, iKey, pValue, bMove);

   tree_node * ptnParent;
   unsigned iBitsPermutation;

   // Descend into the tree, creating nodes as necessary until the path for iKey is complete.
   {
      // ppnChildInParent points to *ptnParent’s parent’s pointer to *ptnParent.
      node ** ppnChildInParent = &m_pnRoot;
      std::uintmax_t iKeyRemaining = iKey;
      std::size_t iLevel = 0;
      do {
         ptnParent = static_cast<tree_node *>(*ppnChildInParent);
         if (!ptnParent) {
            ptnParent = (iLevel == mc_iTreeAnchorsLevel ? new anchor_node() : new tree_node());
            *ppnChildInParent = ptnParent;
         }
         iBitsPermutation = static_cast<unsigned>(
            iKeyRemaining & (smc_cBitPermutationsPerLevel - 1)
         );
         iKeyRemaining >>= smc_cBitsPerLevel;
         ppnChildInParent = &ptnParent->m_apnChildren[iBitsPermutation];
      } while (++iLevel <= mc_iTreeAnchorsLevel);
   }

   // We got here, so *ptnParent is actually an anchor_node.
   anchor_node * panParent = static_cast<anchor_node *>(ptnParent);
   /* To calculate the node size, add typeValue.size() bytes to the offset of the value in a node at
   address 0. This allows packing the node optimally even if the unpadded node size is e.g. 6
   (sizeof will return 8 for that) and typeValue.size() is 2, giving 8 instead of 10 (which would
   really mean at least 12 bytes, a 50% waste of memory). */
   std::unique_ptr<list_node, memory::freeing_deleter> pln(static_cast<list_node *>(
      memory::_raw_alloc(reinterpret_cast<std::size_t>(
         static_cast<list_node *>(0)->value_ptr(typeValue)
      ) + typeValue.size())
   ));
   void * pDst = pln->value_ptr(typeValue);
   if (bMove) {
      typeValue.move_construct(pDst, const_cast<void *>(pValue));
   } else {
      typeValue.copy_construct(pDst, pValue);
   }
   list_node * plnRet = pln.get(), * plnPrev = panParent->m_aplnChildrenLasts[iBitsPermutation];
   pln->m_plnPrev = plnPrev;
   pln->m_plnNext = nullptr;
   panParent->m_aplnChildrenLasts[iBitsPermutation] = plnRet;
   if (!panParent->m_apnChildren[iBitsPermutation]) {
      panParent->m_apnChildren[iBitsPermutation] = plnRet;
   }
   if (plnPrev) {
      plnPrev->m_plnNext = plnRet;
   }
   // Transfer ownership of the list_node to the list.
   pln.release();
   ++m_cValues;
   return plnRet;
}

void scalar_keyed_trie_ordered_multimap_impl::clear(type_void_adapter const & typeValue) {
   ABC_TRACE_FUNC(this/*, typeValue*/);

   if (m_pnRoot) {
      destruct_tree_node(typeValue, static_cast<tree_node *>(m_pnRoot), 0);
      m_pnRoot = nullptr;
      m_cValues = 0;
   }
}

scalar_keyed_trie_ordered_multimap_impl::indexed_anchor
scalar_keyed_trie_ordered_multimap_impl::descend_to_anchor(std::uintmax_t iKey) const {
   ABC_TRACE_FUNC(this, iKey);

   std::uintmax_t iKeyRemaining = iKey;
   tree_node * ptnParent = static_cast<tree_node *>(m_pnRoot);
   std::size_t iLevel = 0;
   for (;;) {
      unsigned iBitsPermutation = static_cast<unsigned>(
         iKeyRemaining & (smc_cBitPermutationsPerLevel - 1)
      );
      if (iLevel == mc_iTreeAnchorsLevel) {
         // At this level, *ptnParent is an anchor.
         return indexed_anchor(static_cast<anchor_node *>(ptnParent), iBitsPermutation);
      } else if (!ptnParent) {
         return indexed_anchor(nullptr, 0);
      }
      iKeyRemaining >>= smc_cBitsPerLevel;
      ptnParent = static_cast<tree_node *>(ptnParent->m_apnChildren[iBitsPermutation]);
      ++iLevel;
   }

}

void scalar_keyed_trie_ordered_multimap_impl::destruct_list(
   type_void_adapter const & type, list_node * pln
) {
   ABC_TRACE_FUNC(this/*, type*/, pln);

   while (pln) {
      list_node * plnNext = pln->m_plnNext;
      type.destruct(pln->value_ptr(type));
      memory::_raw_free(pln);
      pln = plnNext;
   }
}

void scalar_keyed_trie_ordered_multimap_impl::destruct_anchor_node(
   type_void_adapter const & typeValue, anchor_node * pan
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, pan);

   unsigned iBitsPermutation = 0;
   do {
      if (list_node * pln = static_cast<list_node *>(pan->m_apnChildren[iBitsPermutation])) {
         destruct_list(typeValue, pln);
      }
   } while (++iBitsPermutation < smc_cBitPermutationsPerLevel);
   delete pan;
}

void scalar_keyed_trie_ordered_multimap_impl::destruct_tree_node(
   type_void_adapter const & typeValue, tree_node * ptn, unsigned iLevel
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, ptn, iLevel);

   ++iLevel;
   unsigned iBitsPermutation = 0;
   do {
      if (node * pn = ptn->m_apnChildren[iBitsPermutation]) {
         if (iLevel == mc_iTreeAnchorsLevel) {
            destruct_anchor_node(typeValue, static_cast<anchor_node *>(pn));
         } else {
            destruct_tree_node(typeValue, static_cast<tree_node *>(pn), iLevel);
         }
      }
   } while (++iBitsPermutation < smc_cBitPermutationsPerLevel);
   delete ptn;
}

scalar_keyed_trie_ordered_multimap_impl::list_node * scalar_keyed_trie_ordered_multimap_impl::find(
   std::uintmax_t iKey
) {
   ABC_TRACE_FUNC(this, iKey);

   indexed_anchor ia(descend_to_anchor(iKey));
   return ia.pan ? static_cast<list_node *>(ia.pan->m_apnChildren[ia.iBitsPermutation]) : nullptr;
}

scalar_keyed_trie_ordered_multimap_impl::key_value_pair
scalar_keyed_trie_ordered_multimap_impl::front() {
   ABC_TRACE_FUNC(this);

   node * pnChild;
   std::uintmax_t iKey = 0;

   // Descend into the tree.
   tree_node * ptnParent = static_cast<tree_node *>(m_pnRoot);
   std::size_t iLevel = 0;
   unsigned cNextLevelBitsShift = 0;
   do {
      if (!ptnParent) {
         return key_value_pair(0, nullptr);
      }
      // Look for the left-most branch to descend into.
      unsigned iBitsPermutation = 0;
      do {
         pnChild = ptnParent->m_apnChildren[iBitsPermutation];
         if (pnChild) {
            // Prepend the selected bit permutation to the key.
            iKey |= static_cast<std::uintmax_t>(iBitsPermutation) << cNextLevelBitsShift;
            cNextLevelBitsShift += smc_cBitsPerLevel;
            break;
         }
      } while (++iBitsPermutation < smc_cBitPermutationsPerLevel);
      ptnParent = static_cast<tree_node *>(pnChild);
   } while (++iLevel <= mc_iTreeAnchorsLevel);

   /* We got here, so *pnChild is actually a value list’s first node, though pnChild might be
   nullptr. */
   return key_value_pair(iKey, static_cast<list_node *>(pnChild));
}

void scalar_keyed_trie_ordered_multimap_impl::remove_value(
   type_void_adapter const & typeValue, std::uintmax_t iKey, list_node * pln
) {
   ABC_TRACE_FUNC(this/*, typeValue*/, iKey, pln);

   if (!pln->m_plnNext || !pln->m_plnPrev) {
      // *pln is the first or the last node in its list, so we need to update the anchor.
      indexed_anchor ia(descend_to_anchor(iKey));
      if (!ia.pan) {
         // TODO: throw invalid_iterator.
         ABC_THROW(generic_error, ());
      }
      if (!pln->m_plnNext) {
         ia.pan->m_aplnChildrenLasts[ia.iBitsPermutation] = pln->m_plnPrev;
      }
      if (!pln->m_plnPrev) {
         ia.pan->m_apnChildren[ia.iBitsPermutation] = pln->m_plnNext;
      }
   }
   pln->unlink_and_destruct(typeValue);
   --m_cValues;
}

}}} //namespace abc::collections::detail
<|endoftext|>


<commit_before>#include "bloomierHash.h"
#include <set>
#include <bitset>
BloomierHash::BloomierHash(size_t pModulo,size_t pNumberOfElements, size_t pBitVectorSize, size_t pHashSeed) {
	mModulo = pModulo;
	mNumberOfElements = pNumberOfElements;
	// mQ = pQ;
	mHash = new Hash();
	mBitVectorSize = pBitVectorSize;
	mHashSeed = pHashSeed + 5;

};
BloomierHash::~BloomierHash() {

};
bitVector* BloomierHash::getMask(size_t pKey) {
	bitVector* mask = new bitVector(mBitVectorSize);
    char foo;
	srand(mHashSeed*pKey);
	size_t randValue = rand();// % (255*mBitVectorSize);
	// std::cout << "randValue: " << randValue << std::endl;
	for (size_t i = 0; i < mBitVectorSize; ++i) {
		(*mask)[i] =  static_cast<unsigned char>((randValue >> (8*i))& 0b00000000000000000000000011111111);
        // (*mask)[i] = (*m
        // foo = static_cast<char>( randValue >> (8*i));
        // std::bitset<8> peter((*mask)[i]);
        // std::cout << "peter: " << peter << std::endl;
		// std::cout << "randValue2: " << std::bitset<bits>(*mask)[i]) << std::endl;
		// std::cout << "randValueFoo: " << static_cast<size_t>((*mask)[i]) << std::endl;
        // std::cout << "sizeofMASK: " << sizeof((*mask)[i]) << std::endl;

        // std::cout << "sizeofFOO: " << sizeof(foo) << std::endl;

	}

	return mask;
};
vsize_t* BloomierHash::getKNeighbors(size_t pElement, size_t pSeed) {
    size_t seedValue = pSeed;
    if (seedValue == 0) {
        seedValue = mHashSeed;
    }
	vsize_t* kNeighbors = new vsize_t(mNumberOfElements);
	std::set<size_t>* setOfNeighbors = new std::set<size_t>();
	// srand(pElement);
    size_t seedChange = 1;
	for (size_t i = 0; i < mNumberOfElements; ++i) {
        // size_t neighbor = mHash->hash_cpp_lib(pElement+1, mHashSeed*seedValue, mModulo);
		size_t neighbor = mHash->hash(pElement+1, mHashSeed+seedValue, mModulo);
        size_t size = setOfNeighbors->size();
        setOfNeighbors->insert(neighbor);
        while (size == setOfNeighbors->size()) {
            // std::cout << "neighbor: " << neighbor << std::endl;
            neighbor = mHash->hash(pElement+1, (mHashSeed+seedChange)*(mHashSeed+seedChange), mModulo);
            setOfNeighbors->insert(neighbor);
            // std::cout << "neighbor2: " << neighbor << std::endl;

            ++seedChange;
        }
        seedChange = 1;
		// std::cout << "pElement+1: " <<  pElement+1 << " mHashSeed: " << mHashSeed*mHashSeed << std::endl;
		// std::cout << "neighbors: " << neighbor << std::endl;
		(*kNeighbors)[i] = neighbor;
		++pElement;

	}
	// delete setOfNeighbors;
	return kNeighbors;
};

size_t BloomierHash::getHashSeed() {
	return mHashSeed;
};

void BloomierHash::setHashSeed(size_t pHashSeed) {
	mHashSeed = pHashSeed;
}<commit_msg>Bug fixing<commit_after>#include "bloomierHash.h"
#include <set>
#include <bitset>
BloomierHash::BloomierHash(size_t pModulo,size_t pNumberOfElements, size_t pBitVectorSize, size_t pHashSeed) {
	mModulo = pModulo;
	mNumberOfElements = pNumberOfElements;
	// mQ = pQ;
	mHash = new Hash();
	mBitVectorSize = pBitVectorSize;
	mHashSeed = pHashSeed;

};
BloomierHash::~BloomierHash() {

};
bitVector* BloomierHash::getMask(size_t pKey) {
	bitVector* mask = new bitVector(mBitVectorSize);
    char foo;
	srand(mHashSeed*pKey);
	size_t randValue = rand();// % (255*mBitVectorSize);
	// std::cout << "randValue: " << randValue << std::endl;
	for (size_t i = 0; i < mBitVectorSize; ++i) {
		(*mask)[i] =  static_cast<unsigned char>((randValue >> (8*i))& 0b00000000000000000000000011111111);
        // (*mask)[i] = (*m
        // foo = static_cast<char>( randValue >> (8*i));
        // std::bitset<8> peter((*mask)[i]);
        // std::cout << "peter: " << peter << std::endl;
		// std::cout << "randValue2: " << std::bitset<bits>(*mask)[i]) << std::endl;
		// std::cout << "randValueFoo: " << static_cast<size_t>((*mask)[i]) << std::endl;
        // std::cout << "sizeofMASK: " << sizeof((*mask)[i]) << std::endl;

        // std::cout << "sizeofFOO: " << sizeof(foo) << std::endl;

	}

	return mask;
};
vsize_t* BloomierHash::getKNeighbors(size_t pElement, size_t pSeed) {
    size_t seedValue = pSeed;
    if (seedValue == 0) {
        seedValue = mHashSeed;
    }
	vsize_t* kNeighbors = new vsize_t(mNumberOfElements);
	std::set<size_t>* setOfNeighbors = new std::set<size_t>();
	// srand(pElement);
    size_t seedChange = 1;
	for (size_t i = 0; i < mNumberOfElements; ++i) {
        // size_t neighbor = mHash->hash_cpp_lib(pElement+1, mHashSeed*seedValue, mModulo);
		size_t neighbor = mHash->hash(pElement+1, seedValue+seedChange, mModulo);
        size_t size = setOfNeighbors->size();
        setOfNeighbors->insert(neighbor);
        while (size == setOfNeighbors->size()) {
            // std::cout << "neighbor: " << neighbor << std::endl;
            neighbor = mHash->hash(pElement+1, (seedValue+seedChange)*(seedValue+seedChange), mModulo);
            setOfNeighbors->insert(neighbor);
            // std::cout << "neighbor2: " << neighbor << std::endl;

            ++seedChange;
        }
        seedChange = 1;
		// std::cout << "pElement+1: " <<  pElement+1 << " mHashSeed: " << mHashSeed*mHashSeed << std::endl;
		// std::cout << "neighbors: " << neighbor << std::endl;
		(*kNeighbors)[i] = neighbor;
		++pElement;

	}
	// delete setOfNeighbors;
	return kNeighbors;
};

size_t BloomierHash::getHashSeed() {
	return mHashSeed;
};

void BloomierHash::setHashSeed(size_t pHashSeed) {
	mHashSeed = pHashSeed;
}<|endoftext|>


<commit_before>/*
 * Copyright 2013 Matthew Harvey
 *
 * 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.
 */

/**
 * Generates source code by performing transformations on one or more
 * input files. Directory in which to write generated files is passed
 * as sole command line argument.
 */

// TODO HIGH PRIORITY Use this instead of the Tcl script for generating
// "make_currencies_inc.hpp". Incorporate compilation of this into the
// prebuild step. This is desirable because it removes a dependency on
// Tcl.

#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <jewel/assert.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using std::cerr;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::getline;
using std::string;
using std::vector;
namespace algorithm = boost::algorithm;
namespace filesystem = boost::filesystem;

int main(int argc, char** argv)
{
	// process command line arguments
	if (argc != 2)
	{
		cerr << "Wrong number of command line parameters passed to "
		     << "prebuild program."
			 << endl;
		return 1;
	}
	JEWEL_HARD_ASSERT (argc >= 2);
	string const out_directory = argv[1];

	// construct input and output objects
	vector<string> row;
	ifstream infile("currencies.csv");
	filesystem::path const outfile_path =
		out_directory / "include" / "make_currencies_inc.hpp";
	ofstream outfile(outfile_path.string());

	// discard first line of input (column headers)
	if (!getline(infile, line))
	{
		cerr << "Error parsing CSV file in prebuild: too few rows." << endl;
		return 1;
	}
	JEWEL_HARD_ASSERT(line == "Currency,Symbol,Precision");

	// generate C++ code on the basis of CSV contents
	for (string line; getline(infile, line); )
	{
		algorithm::split(row, line, [](char c){ return c == ','; });
		for (auto& cell: row) algorithm::trim(cell);
		string const& name = row.at(0);
		string const& abbreviation = row.at(1);
		string const& precision = row.at(2);
		outfile << "\t\tvec.push_back(make_currency(dbc, "
		        << "L\"" << name << "\""
				<< "\"" << abbreviation << "\""
				<< precision
				<< "));";
	}
	return 0;
}
<commit_msg>Improved error handling in "prebuild.cpp".<commit_after>/*
 * Copyright 2013 Matthew Harvey
 *
 * 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.
 */

/**
 * Generates source code by performing transformations on one or more
 * input files. Directory in which to write generated files is passed
 * as sole command line argument.
 */

// TODO HIGH PRIORITY Use this instead of the Tcl script for generating
// "make_currencies_inc.hpp". Incorporate compilation of this into the
// prebuild step. This is desirable because it removes a dependency on
// Tcl.

#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <jewel/assert.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using std::cerr;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::getline;
using std::string;
using std::vector;
namespace algorithm = boost::algorithm;
namespace filesystem = boost::filesystem;

int main(int argc, char** argv)
{
	// process command line arguments
	if (argc != 2)
	{
		cerr << "Wrong number of command line parameters passed to "
		     << "prebuild program."
			 << endl;
		return 1;
	}
	JEWEL_HARD_ASSERT (argc >= 2);
	string const out_directory = argv[1];

	// construct input and output objects
	vector<string> row;
	ifstream infile("currencies.csv");
	filesystem::path const outfile_path =
		out_directory / "include" / "make_currencies_inc.hpp";
	ofstream outfile(outfile_path.string());

	// discard first line of input (column headers)
	if (!getline(infile, line))
	{
		cerr << "Error parsing CSV file in prebuild: too few rows." << endl;
		return 1;
	}
	if (line != "Currency,Symbol,Precision")
	{
		cerr << "Unexpected input from CSV file in prebuild: unexpected "
		     << "column headers"
			 << endl;
		return 1;
	}

	// generate C++ code on the basis of CSV contents
	for (string line; getline(infile, line); )
	{
		algorithm::split(row, line, [](char c){ return c == ','; });
		string::size_type const expected_num_columns = 3;
		if (line.size() != expected_num_columns)
		{
			cerr << "Unexpected input from CSV file in prebuild: unexpected "
			     << "number of columns in record ("
				 << "expected " << expected_num_columns
				 << " but found" << line.size() ")."
				 << endl;
			return 1;
		}
		for (auto& cell: row) algorithm::trim(cell);
		string const& name = row.at(0);
		string const& abbreviation = row.at(1);
		string const& precision = row.at(2);
		outfile << "\t\tvec.push_back(make_currency(dbc, "
		        << "L\"" << name << "\""
				<< "\"" << abbreviation << "\""
				<< precision
				<< "));";
	}

	return 0;
}
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2015 Virgil Security Inc.
 *
 * Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     (1) Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *     (2) Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *     (3) Neither the name of the copyright holder 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 AUTHOR ''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 THE AUTHOR 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.
 */

#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

#include <tclap/CmdLine.h>

#include <cli/ConfigFile.h>

#include <cli/version.h>
#include <cli/pair.h>
#include <cli/util.h>

namespace vsdk = virgil::sdk;
namespace vcli = virgil::cli;

#ifdef SPLIT_CLI
#define MAIN main
#else
#define MAIN config_main
#endif

int MAIN(int argc, char** argv) {
    try {
        std::string description = "Get information about Virgil CLI configuration file.\n\n";

        std::vector<std::string> examples;
        examples.push_back("Show path to the configuration file applied for all users:\n"
                           "virgil config --global\n\n");

        examples.push_back("Show path to the configuration file applied for current user:\n"
                           "virgil config --local\n\n");

        examples.push_back("Show configuration file template:\n"
                           "virgil config --template\n\n");

        std::string descriptionMessage = virgil::cli::getDescriptionMessage(description, examples);

        // Parse arguments.
        TCLAP::CmdLine cmd(descriptionMessage, ' ', virgil::cli_version());

        TCLAP::ValueArg<std::string> outArg("o", "out", "If omitted, stdout is used.\n", false, "", "file");

        TCLAP::SwitchArg showGlobalConfigFilePathArg(
            "g", "global", "Show path to the configuration file applied for all users.", false);

        TCLAP::SwitchArg showLocalConfigFilePathArg(
            "l", "local", "Show path to the configuration file applied for current user.", false);

        TCLAP::SwitchArg showTemplateArg("t", "template", "Show configuration file template.", false);

        cmd.add(showTemplateArg);
        cmd.add(showLocalConfigFilePathArg);
        cmd.add(showGlobalConfigFilePathArg);
        cmd.add(outArg);
        cmd.parse(argc, argv);

        std::string configFileName =
#if defined(WIN32)
            "\\virgil-cli.ini";
#else
            "/virgil-cli.conf";
#endif

        const bool showAll = !showGlobalConfigFilePathArg.getValue() && !showLocalConfigFilePathArg.getValue() &&
                             !showTemplateArg.getValue();

        const bool isMultipleInfo = showAll ||
                                    (showGlobalConfigFilePathArg.getValue() && showLocalConfigFilePathArg.getValue()) ||
                                    (showGlobalConfigFilePathArg.getValue() && showTemplateArg.getValue()) ||
                                    (showLocalConfigFilePathArg.getValue() && showTemplateArg.getValue());

        std::string data;
        if (showGlobalConfigFilePathArg.getValue() || showAll) {
            std::string pathGlobalConfigFile = get_all_user_config_folder("virgil-cli") + configFileName;
            data += (isMultipleInfo ? "> Global configuration file path: " : "") + pathGlobalConfigFile + "\n";
        }

        if (showLocalConfigFilePathArg.getValue() || showAll) {
            std::string pathLocalConfigFile = get_user_config_folder("virgil-cli") + configFileName;
            data += (isMultipleInfo ? "> Local configuration file path: " : "") + pathLocalConfigFile + "\n";
        }

        if (showTemplateArg.getValue() || showAll) {
            vcli::ConfigFile defaultConfig;
            std::string config = isMultipleInfo ? "> Configuration file template:\n" : "";
            config +=
                "; First, you must create a free Virgil Security developer's account by signing up\n"
                "; here - https://developer.virgilsecurity.com/account/signup. Once you have your\n"
                "; account you can sign in and generate an access token for your application.\n"
                ";\n"
                "; The access token provides authenticated secure access to Virgil Keys Services and is passed with\n"
                "; every API call. The access token also allows the API to associate your app’s requests with your\n"
                "; Virgil Security developer's account.\n\n"

                "[Virgil Access Token]\n";

            config += "token=<VIRGIL_ACCESS_TOKEN>\n\n";

            config += "; This class provide base URIs for the Virgil Security services\n"
                      "[URI]\n\n"

                      "; Base URI of the Virgil Identity Service\n"
                      "identity-service=";

            config += defaultConfig.serviceUri.getIdentityService() + "\n\n";

            config += "; base URI of the Virgil Keys Service\n"
                      "public-key-service=";

            config += defaultConfig.serviceUri.getPublicKeyService() + "\n\n";

            config += "; base URI of the Virgil Private Service\n"
                      "private-key-service=";

            config += defaultConfig.serviceUri.getPrivateKeyService() + "\n";

            data += config;
        }

        vcli::writeOutput(outArg.getValue(), data);

    } catch (TCLAP::ArgException& exception) {
        std::cerr << "config. Error: " << exception.error() << " for arg " << exception.argId() << std::endl;
        return EXIT_FAILURE;
    } catch (std::exception& exception) {
        std::cerr << "config. Error: " << exception.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<commit_msg>[CLI-84] Add improvement to the virgil config<commit_after>/**
 * Copyright (C) 2015 Virgil Security Inc.
 *
 * Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     (1) Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *     (2) Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *     (3) Neither the name of the copyright holder 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 AUTHOR ''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 THE AUTHOR 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.
 */

#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

#include <tclap/CmdLine.h>

#include <cli/ConfigFile.h>

#include <cli/version.h>
#include <cli/pair.h>
#include <cli/util.h>

namespace vsdk = virgil::sdk;
namespace vcli = virgil::cli;

#ifdef SPLIT_CLI
#define MAIN main
#else
#define MAIN config_main
#endif

static std::string configFileName =
#if defined(WIN32)
    "\\virgil-cli.ini";
#else
    "/virgil-cli.conf";
#endif

static std::string getTemplateConfig();

static void createGlobalConfigFile(const bool verbose);

static void createLocalConfigFile(const bool verbose);

static std::string readGlobalConfigFile(const bool verbose);

static std::string readLocalConfigFile(const bool verbose);

int MAIN(int argc, char** argv) {
    try {
        std::string description = "Get information about Virgil CLI configuration file.\n\n";

        std::vector<std::string> examples;
        examples.push_back("Show path to the configuration file applied for all users:\n"
                           "virgil config --global --path\n\n");

        examples.push_back("Show path to the configuration file applied for current user:\n"
                           "virgil config --local --path\n\n");

        examples.push_back("Show configuration file template:\n"
                           "virgil config --template\n\n");

        examples.push_back("Create a global configuration file from template:\n"
                           "virgil config --global --create\n\n");

        examples.push_back("Create a local configuration file from template:\n"
                           "virgil config --local --create\n\n");

        examples.push_back("Show the global configuration file:\n"
                           "virgil config --global --list\n\n");

        examples.push_back("Show the local configuration file:\n"
                           "virgil config --local --list\n\n");

        std::string descriptionMessage = virgil::cli::getDescriptionMessage(description, examples);

        // Parse arguments.
        TCLAP::CmdLine cmd(descriptionMessage, ' ', virgil::cli_version());

        TCLAP::SwitchArg isGlobalConfigFileArg("g", "global", "The configuration file applied for all users.", false);

        TCLAP::SwitchArg isLocalConfigFileArg("l", "local", "The configuration file applied for current user.", false);

        TCLAP::SwitchArg showTemplateArg("t", "template", "Show configuration file template.", false);

        TCLAP::SwitchArg createConfigFileArg("c", "create", "Create a configuration file from template.", false);

        TCLAP::SwitchArg showConfigFileArg("", "list", "Show the configuration file.", false);

        TCLAP::SwitchArg showPathConfigFileArg("p", "path", "Show path to the configuration file.", false);

        TCLAP::SwitchArg verboseArg("V", "VERBOSE", "Shows detailed information.", false);

        cmd.add(verboseArg);
        cmd.add(showPathConfigFileArg);
        cmd.add(showConfigFileArg);
        cmd.add(createConfigFileArg);
        cmd.add(showTemplateArg);
        cmd.add(isLocalConfigFileArg);
        cmd.add(isGlobalConfigFileArg);
        cmd.parse(argc, argv);

        const bool all = isLocalConfigFileArg.getValue() && isGlobalConfigFileArg.getValue();

        if (showPathConfigFileArg.getValue()) {
            std::string pathLocalConfigFile = get_user_config_folder("virgil-cli") + configFileName;
            std::string pathGlobalConfigFile = get_all_user_config_folder("virgil-cli") + configFileName;

            if (all) {
                std::cout << "> Local configuration file path: " << pathLocalConfigFile << "\n";
                std::cout << "> Global configuration file path: " << pathGlobalConfigFile << "\n";
            } else if (isLocalConfigFileArg.getValue()) {
                std::cout << pathLocalConfigFile << "\n";
            } else {
                // isGlobalConfigFileArg
                std::cout << pathGlobalConfigFile << "\n";
            }
        }

        if (createConfigFileArg.getValue()) {
            if (all) {
                createLocalConfigFile(verboseArg.getValue());
                createGlobalConfigFile(verboseArg.getValue());
            } else if (isLocalConfigFileArg.getValue()) {
                createLocalConfigFile(verboseArg.getValue());
            } else {
                // isGlobalConfigFileArg
                createGlobalConfigFile(verboseArg.getValue());
            }
        }

        if (showConfigFileArg.getValue()) {
            if (all) {
                std::cout << readLocalConfigFile(verboseArg.getValue());
                std::cout << readGlobalConfigFile(verboseArg.getValue());
            } else if (isLocalConfigFileArg.getValue()) {
                std::cout << readLocalConfigFile(verboseArg.getValue());
            } else {
                // isGlobalConfigFileArg
                std::cout << readGlobalConfigFile(verboseArg.getValue());
            }
        }

        if (showTemplateArg.getValue()) {
            std::cout << getTemplateConfig();
        }

    } catch (TCLAP::ArgException& exception) {
        std::cerr << "config. Error: " << exception.error() << " for arg " << exception.argId() << std::endl;
        return EXIT_FAILURE;
    } catch (std::exception& exception) {
        std::cerr << "config. Error: " << exception.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

std::string getTemplateConfig() {
    vcli::ConfigFile defaultConfig;
    std::string config;
    config += "; First, you must create a free Virgil Security developer's account by signing up\n"
              "; here - https://developer.virgilsecurity.com/account/signup. Once you have your\n"
              "; account you can sign in and generate an access token for your application.\n"
              ";\n"
              "; The access token provides authenticated secure access to Virgil Keys Services and is passed with\n"
              "; every API call. The access token also allows the API to associate your app’s requests with your\n"
              "; Virgil Security developer's account.\n\n"

              "[Virgil Access Token]\n";
    config += "token=<VIRGIL_ACCESS_TOKEN>\n\n";

    config += "; This class provide base URIs for the Virgil Security services\n"
              "[URI]\n\n"

              "; Base URI of the Virgil Identity Service\n"
              "identity-service=";
    config += defaultConfig.serviceUri.getIdentityService() + "\n\n";

    config += "; base URI of the Virgil Keys Service\n"
              "public-key-service=";
    config += defaultConfig.serviceUri.getPublicKeyService() + "\n\n";

    config += "; base URI of the Virgil Private Service\n"
              "private-key-service=";
    config += defaultConfig.serviceUri.getPrivateKeyService() + "\n";

    return config;
}

void createGlobalConfigFile(const bool verbose) {
    std::string pathGlobalConfigFile = get_all_user_config_folder("virgil-cli") + configFileName;
    vcli::writeOutput(pathGlobalConfigFile, getTemplateConfig());
    if (verbose) {
        std::cout << "Create a global configuration file from template by path:" + pathGlobalConfigFile << "\n";
    }
}

void createLocalConfigFile(const bool verbose) {
    std::string pathLocalConfigFile = get_user_config_folder("virgil-cli") + configFileName;
    vcli::writeOutput(pathLocalConfigFile, getTemplateConfig());
    if (verbose) {
        std::cout << "Create a local configuration file from template by path:" + pathLocalConfigFile << "\n";
    }
}

std::string readGlobalConfigFile(const bool verbose) {
    std::string pathGlobalConfigFile = get_all_user_config_folder("virgil-cli") + configFileName;
    std::ifstream inGlobalConfigFile(pathGlobalConfigFile, std::ios::in | std::ios::binary);
    if (!inGlobalConfigFile) {
        throw std::invalid_argument("Can't read a global configuration file by path:" + pathGlobalConfigFile);
    }
    if (verbose) {
        std::cout << "Read a global config file"
                  << "\n";
    }
    return std::string((std::istreambuf_iterator<char>(inGlobalConfigFile)), std::istreambuf_iterator<char>());
}

std::string readLocalConfigFile(const bool verbose) {
    std::string pathLocalConfigFile = get_user_config_folder("virgil-cli") + configFileName;
    std::ifstream inLocalConfigFile(pathLocalConfigFile, std::ios::in | std::ios::binary);
    if (!inLocalConfigFile) {
        throw std::invalid_argument("Can't read a local configuration file by path:" + pathLocalConfigFile);
    }
    if (verbose) {
        std::cout << "Read a local configuration file"
                  << "\n";
    }
    return std::string((std::istreambuf_iterator<char>(inLocalConfigFile)), std::istreambuf_iterator<char>());
}
<|endoftext|>


<commit_before>#include "fish_detector/common/species_dialog.h"
#include "ui_species_dialog.h"

namespace fish_detector {

SpeciesDialog::SpeciesDialog(QWidget *parent)
  : QDialog(parent)
  , ui_(new Ui::SpeciesDialog) {
  ui_->setupUi(this);
}

void SpeciesDialog::on_ok_clicked() {
}

void SpeciesDialog::on_cancel_clicked() {
}

void SpeciesDialog::on_removeSubspecies_clicked() {
}

void SpeciesDialog::on_addSubspecies_clicked() {
}

Species SpeciesDialog::getSpecies() {
  Species species;
  return species;
}

#include "../../include/fish_detector/common/moc_species_dialog.cpp"

} // namespace fish_detector
<commit_msg>Add implementation for adding/removing subspecies functions<commit_after>#include "fish_detector/common/species_dialog.h"
#include "ui_species_dialog.h"

namespace fish_detector {

SpeciesDialog::SpeciesDialog(QWidget *parent)
  : QDialog(parent)
  , ui_(new Ui::SpeciesDialog) {
  ui_->setupUi(this);
}

void SpeciesDialog::on_ok_clicked() {
  accept();
}

void SpeciesDialog::on_cancel_clicked() {
  reject();
}

void SpeciesDialog::on_removeSubspecies_clicked() {
  QListWidgetItem *current = ui_->subspeciesList->currentItem();
  if(current != nullptr) {
    delete current;
  }
}

void SpeciesDialog::on_addSubspecies_clicked() {
  QListWidgetItem *item = new QListWidgetItem("New subspecies");
  item->setFlags(item->flags() | Qt::ItemIsEditable);
  ui_->subspeciesList->addItem(item);
  ui_->subspeciesList->editItem(item);
}

Species SpeciesDialog::getSpecies() {
  Species species;
  return species;
}

#include "../../include/fish_detector/common/moc_species_dialog.cpp"

} // namespace fish_detector
<|endoftext|>


<commit_before>/* **********************************************************
 * Copyright (c) 2018 Google LLC  All rights reserved.
 * **********************************************************/

/*
 * 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 following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Google, Inc. 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 GOOGLE LLC 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.
 */

/* This microbenchmark suffers from a significant number of last-level cache
 * (LLC) misses. SW prefetching can significantly improve its performance.
 *
 * The cache miss analyzer can be used to identify the load instruction that
 * is suffering from most of the LLC misses in this microbenchmark. The analyzer
 * can also produce prefetching hints for this microbenchmark. To run the
 * analyzer on this microbenchmark and write the prefetching hints in a text
 * file called "rec.csv", perform the following:
 * * Compile the microbenchmark. Assuming g++ is the compiler being used:
 *   $ g++ -O3 -o stride_benchmark stride_benchmark.cpp
 * * Run the the analyzer:
 *   $ bin64/drrun -t drcachesim -simulator_type miss_analyzer -LL_miss_file rec.csv -- \
 *     stride_benchmark
 *
 */

#include <stdint.h>
#include <string.h>
#include <iostream>

#define MEM_BARRIER() __asm__ __volatile__("" ::: "memory")

int
main(int argc, const char *argv[])
{
    // Cache line size in bytes.
    const int kLineSize = 64;
    // Number of cache lines skipped by the stream every iteration.
    const int kStride = 7;
    // Number of 1-byte elements in the array.
    // (200+ MiB to guarantee the array doesn't fit in Skylake caches)
    const size_t kArraySize = 256 * 1024 * 1024;
    // Number of iterations in the main loop.
    const int kIterations = 1000000;
    // The main vector/array used for emulating pointer chasing.
    unsigned char *buffer = new unsigned char[kArraySize];
    memset(buffer, kStride, kArraySize);

    // Add a memory barrier so the call doesn't get optimized away or
    // reordered with respect to callers.
    MEM_BARRIER();

    int position = 0;

    // Here the code will pointer chase through the array skipping forward
    // kStride cache lines at a time. Since kStride is an odd number, the main
    // loop will touch different cache lines as it wraps around.
    for (int loop = 0; loop < kIterations; ++loop) {
        // This prefetching instruction results in a speedup of >2x
        // on a Skylake machine running Linux when compiled with g++ -O3.
        // const int prefetch_distance = 5 * kStride * kLineSize;
        // __builtin_prefetch(&buffer[position + prefetch_distance], 0, 0);

        position += (buffer[position] * kLineSize);
        position &= (kArraySize - 1);
    }

    // Add a memory barrier so the call doesn't get optimized away or
    // reordered with respect to callers.
    MEM_BARRIER();

    std::cerr << "Value = " << position << std::endl;

    return 0;
}
<commit_msg>i#3485: Cut down runtime of tool.drcachesim.miss_analyzer. (#3490)<commit_after>/* **********************************************************
 * Copyright (c) 2018 Google LLC  All rights reserved.
 * **********************************************************/

/*
 * 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 following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Google, Inc. 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 GOOGLE LLC 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.
 */

/* This microbenchmark suffers from a significant number of last-level cache
 * (LLC) misses. SW prefetching can significantly improve its performance.
 *
 * The cache miss analyzer can be used to identify the load instruction that
 * is suffering from most of the LLC misses in this microbenchmark. The analyzer
 * can also produce prefetching hints for this microbenchmark. To run the
 * analyzer on this microbenchmark and write the prefetching hints in a text
 * file called "rec.csv", perform the following:
 * * Compile the microbenchmark. Assuming g++ is the compiler being used:
 *   $ g++ -O3 -o stride_benchmark stride_benchmark.cpp
 * * Run the the analyzer:
 *   $ bin64/drrun -t drcachesim -simulator_type miss_analyzer -LL_miss_file rec.csv -- \
 *     stride_benchmark
 *
 */

#include <stdint.h>
#include <string.h>
#include <iostream>

#define MEM_BARRIER() __asm__ __volatile__("" ::: "memory")

int
main(int argc, const char *argv[])
{
    // Cache line size in bytes.
    const int kLineSize = 64;
    // Number of cache lines skipped by the stream every iteration.
    const int kStride = 7;
    // Number of 1-byte elements in the array.
    // (200+ MiB to guarantee the array doesn't fit in Skylake caches)
    const size_t kArraySize = 64 * 1024 * 1024;
    // Number of iterations in the main loop.
    const int kIterations = 100000;
    // The main vector/array used for emulating pointer chasing.
    unsigned char *buffer = new unsigned char[kArraySize];
    memset(buffer, kStride, kArraySize);

    // Add a memory barrier so the call doesn't get optimized away or
    // reordered with respect to callers.
    MEM_BARRIER();

    int position = 0;

    // Here the code will pointer chase through the array skipping forward
    // kStride cache lines at a time. Since kStride is an odd number, the main
    // loop will touch different cache lines as it wraps around.
    for (int loop = 0; loop < kIterations; ++loop) {
        // This prefetching instruction results in a speedup of >2x
        // on a Skylake machine running Linux when compiled with g++ -O3.
        // const int prefetch_distance = 5 * kStride * kLineSize;
        // __builtin_prefetch(&buffer[position + prefetch_distance], 0, 0);

        position += (buffer[position] * kLineSize);
        position &= (kArraySize - 1);
    }

    // Add a memory barrier so the call doesn't get optimized away or
    // reordered with respect to callers.
    MEM_BARRIER();

    std::cerr << "Value = " << position << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>#include <cassert>

#include <cstddef>

#include <cstdint>

#include <type_traits>

#include <utility>

#include <new>

namespace generic
{

template<typename F>
class forwarder;

template<typename R, typename ...A>
class forwarder<R (A...)>
{
public:
  forwarder() = default;

  template<typename T>
  forwarder(T&& f) noexcept :
    stub_(new (&store_) handler<T>(::std::forward<T>(f)), handler<T>::invoke)
  {
    static_assert(sizeof(T) <= sizeof(store_), "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
  }

  forwarder& operator=(forwarder const&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f) noexcept
  {
    static_assert(sizeof(T) <= sizeof(store_), "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));

    stub_ = handler<T>::invoke;

    return *this;
  }

  R operator() (A... args)
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward<A>(args)...);
  }

private:
  template<typename T>
  struct handler
  {
    handler(T&& f) noexcept : f_(::std::forward<T>(f))
    {
    }

    static R invoke(void* ptr, A&&... args)
    {
      return static_cast<handler<T>*>(ptr)->f_(::std::forward<A>(args)...);
    }

    T f_;
  };

#if defined(__clang__)
  using max_align_type = long double;
#elif defined(__GNUC__)
  using max_align_type = ::max_align_t;
#else
  using max_align_type = ::std::max_align_t;
#endif

  alignas(max_align_type) ::std::uintptr_t store_;

  R (*stub_)(void*, A&&...){};
};

}
<commit_msg>smoe fixes<commit_after>#include <cassert>

#include <cstddef>

#include <cstdint>

#include <type_traits>

#include <utility>

#include <new>

namespace generic
{

template<typename F>
class forwarder;

template<typename R, typename ...A>
class forwarder<R (A...)>
{
public:
  forwarder() = default;

  template<typename T>
  forwarder(T&& f) noexcept : stub_(handler<T>::invoke)
  {
    static_assert(sizeof(T) <= sizeof(store_), "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));
  }

  forwarder& operator=(forwarder const&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f) noexcept
  {
    static_assert(sizeof(T) <= sizeof(store_), "functor too large");
    static_assert(::std::is_trivially_destructible<T>::value,
      "functor not trivially destructible");
    new (&store_) handler<T>(::std::forward<T>(f));

    stub_ = handler<T>::invoke;

    return *this;
  }

  R operator() (A... args)
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward<A>(args)...);
  }

private:
  template<typename T>
  struct handler
  {
    handler(T&& f) noexcept : f_(::std::forward<T>(f))
    {
    }

    static R invoke(void* ptr, A&&... args)
    {
      return static_cast<handler<T>*>(ptr)->f_(::std::forward<A>(args)...);
    }

    T f_;
  };

#if defined(__clang__)
  using max_align_type = long double;
#elif defined(__GNUC__)
  using max_align_type = ::max_align_t;
#else
  using max_align_type = ::std::max_align_t;
#endif

  alignas(max_align_type) ::std::uintptr_t store_;

  R (*stub_)(void*, A&&...){};
};

}
<|endoftext|>


<commit_before>class Solution {
    public:
        string convert(string s, int nRows)
        {
            if(nRows == 1) return s;
            string result;
            result.reserve(s.size());
            int index = 0;
            while(index < s.size()){
                result.push_back(s[index]);
                index += (nRows+nRows-2);
            }

            for(int i = 1; i != nRows-1; ++i){
                index = i;
                while(index < s.size()){
                    result.push_back(s[index]);
                    int tmpIndex = index + (2*(nRows-i-1));
                    if(tmpIndex < s.size())
                        result.push_back(s[tmpIndex]);
                    index += (nRows+nRows-2);
                }
            }

            index = nRows - 1;
            while(index < s.size()){
                result.push_back(s[index]);
                index += (nRows+nRows-2);
            }
            return result;
        }
};
<commit_msg>simplified code, but same idea<commit_after>class Solution {
    public:
        string convert(string s, int nRows)
        {
            if(nRows == 1) return s;
            string result;
            result.reserve(s.size());
            for(int i = 0; i != nRows; ++i){
                int index = i;
                while(index < s.size()){
                    result.push_back(s[index]);
                    if(i != 0 && i != nRows-1){
                        int tmpIndex = index + (2*(nRows-i-1));
                        if(tmpIndex < s.size())
                            result.push_back(s[tmpIndex]);
                    }
                    index += (nRows+nRows-2);
                }
            }
            return result;
        }
};
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file assert.hpp
 * \brief Contains C++ assert utilities.
 */

#ifndef CPP_UTILS_ASSERT_HPP
#define CPP_UTILS_ASSERT_HPP

#include <iostream>

#ifdef CPP_UTILS_ASSERT_EXCEPTION
#include <stdexcept>
#endif

#include "likely.hpp"

#define cpp_unused(x) ((void)(x))

#ifdef NDEBUG

#define cpp_assert(condition, message) ((void)0)

#if defined __clang__

#if __has_builtin(__builtin_unreachable)
#define cpp_unreachable(message) __builtin_unreachable();
#else
#define cpp_unreachable(message) ((void)0)
#endif //__has_builtin(__builtin_unreachable)

#elif defined __GNUC__

#define cpp_unreachable(message) __builtin_unreachable();

#endif //__clang__

#else

#ifdef CPP_UTILS_ASSERT_EXCEPTION

#define cpp_assert(condition, message) \
    if (cpp_likely(condition))         \
        ((void)0);                     \
    else                               \
        throw std::runtime_error("Assertion failed");

#else

#define cpp_assert(condition, message) (cpp_likely(condition)                                                     \
                                            ? ((void)0)                                                           \
                                            : ::cpp::assertion::detail::assertion_failed_msg(#condition, message, \
                                                                                __PRETTY_FUNCTION__, __FILE__, __LINE__))

#endif

#if defined __clang__

#if __has_builtin(__builtin_unreachable)
#define cpp_unreachable(message) \
    cpp_assert(false, message);  \
    __builtin_unreachable();
#else
#define cpp_unreachable(message) cpp_assert(false, message);
#endif //__has_builtin(__builtin_unreachable)

#elif defined __GNUC__

#define cpp_unreachable(message) \
    cpp_assert(false, message);  \
    __builtin_unreachable();

#endif //__clang__

#endif //NDEBUG

namespace cpp {
namespace assertion {
namespace detail {

/*!
 * \brief Function call when an assertion failed
 */
template <typename CharT>
void assertion_failed_msg(const CharT* expr, const char* msg, const char* function, const char* file, long line) {
    std::cerr
        << "***** Internal Program Error - assertion (" << expr << ") failed in "
        << function << ":\n"
        << file << '(' << line << "): " << msg << std::endl;
    std::abort();
}

} // end of detail namespace
} // end of assertion namespace
} // end of cpp namespace

#endif //CPP_UTILS_ASSERT_HPP
<commit_msg>Use size_t in place of long for line<commit_after>//=======================================================================
// Copyright (c) 2013-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file assert.hpp
 * \brief Contains C++ assert utilities.
 */

#ifndef CPP_UTILS_ASSERT_HPP
#define CPP_UTILS_ASSERT_HPP

#include <iostream>

#ifdef CPP_UTILS_ASSERT_EXCEPTION
#include <stdexcept>
#endif

#include "likely.hpp"

#define cpp_unused(x) ((void)(x))

#ifdef NDEBUG

#define cpp_assert(condition, message) ((void)0)

#if defined __clang__

#if __has_builtin(__builtin_unreachable)
#define cpp_unreachable(message) __builtin_unreachable();
#else
#define cpp_unreachable(message) ((void)0)
#endif //__has_builtin(__builtin_unreachable)

#elif defined __GNUC__

#define cpp_unreachable(message) __builtin_unreachable();

#endif //__clang__

#else

#ifdef CPP_UTILS_ASSERT_EXCEPTION

#define cpp_assert(condition, message) \
    if (cpp_likely(condition))         \
        ((void)0);                     \
    else                               \
        throw std::runtime_error("Assertion failed");

#else

#define cpp_assert(condition, message) (cpp_likely(condition)                                                     \
                                            ? ((void)0)                                                           \
                                            : ::cpp::assertion::detail::assertion_failed_msg(#condition, message, \
                                                                                __PRETTY_FUNCTION__, __FILE__, __LINE__))

#endif

#if defined __clang__

#if __has_builtin(__builtin_unreachable)
#define cpp_unreachable(message) \
    cpp_assert(false, message);  \
    __builtin_unreachable();
#else
#define cpp_unreachable(message) cpp_assert(false, message);
#endif //__has_builtin(__builtin_unreachable)

#elif defined __GNUC__

#define cpp_unreachable(message) \
    cpp_assert(false, message);  \
    __builtin_unreachable();

#endif //__clang__

#endif //NDEBUG

namespace cpp {
namespace assertion {
namespace detail {

/*!
 * \brief Function call when an assertion failed
 */
template <typename CharT>
void assertion_failed_msg(const CharT* expr, const char* msg, const char* function, const char* file, size_t line) {
    std::cerr
        << "***** Internal Program Error - assertion (" << expr << ") failed in "
        << function << ":\n"
        << file << '(' << line << "): " << msg << std::endl;
    std::abort();
}

} // end of detail namespace
} // end of assertion namespace
} // end of cpp namespace

#endif //CPP_UTILS_ASSERT_HPP
<|endoftext|>


<commit_before>/****************************************************************************
 * Copyright (c) 2012-2017 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 ****************************************************************************/

#include <details/DTK_DetailsDistributedSearchTreeImpl.hpp>

#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_UnitTestHarness.hpp>
#include <Tpetra_Distributor.hpp>

#include <algorithm>
#include <bitset>
#include <iostream>
#include <random>
#include <tuple>

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl, recv_from,
                                   DeviceType )
{
    // Checking that it is not necessary to send ranks because it can be
    // inferred from getProcsFrom() and getLengthsFrom().
    Teuchos::RCP<const Teuchos::Comm<int>> comm =
        Teuchos::DefaultComm<int>::getComm();
    int const comm_rank = comm->getRank();
    int const comm_size = comm->getSize();

    std::vector<int> tn( comm_size + 1 );
    for ( int i = 0; i < comm_size + 1; ++i )
        tn[i] = i * ( i - 1 ) / 2;

    // First use send buffer to set up the communication plan.  Sending 0
    // packet to rank 1, 1 packet to rank 1, 2 packets to rank 2, etc.
    int const n_exports = tn[comm_size];
    std::vector<int> exports( n_exports );
    for ( int i = 0; i < comm_size; ++i )
        for ( int j = tn[i]; j < tn[i + 1]; ++j )
            exports[j] = i;

    Tpetra::Distributor distributor( comm );
    int const n_imports = distributor.createFromSends(
        Teuchos::ArrayView<int>( exports.data(), exports.size() ) );
    TEUCHOS_ASSERT_EQUALITY( n_imports, comm_rank * comm_size );

    std::vector<int> imports( n_imports );
    distributor.doPostsAndWaits(
        Teuchos::ArrayView<int const>( exports.data(), exports.size() ), 1,
        Teuchos::ArrayView<int>( imports.data(), imports.size() ) );

    TEST_COMPARE_ARRAYS( imports, std::vector<int>( n_imports, comm_rank ) );

    // Then fill buffer with rank of the process that is sending packets.
    std::fill( exports.begin(), exports.end(), comm_rank );
    distributor.doPostsAndWaits(
        Teuchos::ArrayView<int const>( exports.data(), exports.size() ), 1,
        Teuchos::ArrayView<int>( imports.data(), imports.size() ) );

    auto procs_from = distributor.getProcsFrom();
    auto lengths_form = distributor.getLengthsFrom();
    TEST_EQUALITY( procs_from.size(), lengths_form.size() );
    std::vector<int> recv_from( n_imports, -1 );
    int count = 0;
    for ( auto i = 0; i < procs_from.size(); ++i )
        for ( auto j = 0; j < lengths_form[i]; ++j )
            recv_from[count++] = procs_from[i];
    TEST_EQUALITY( count, n_imports );
    TEST_COMPARE_ARRAYS( imports, recv_from );
}

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl,
                                   sort_results, DeviceType )
{
    std::vector<int> ids_ = {4, 3, 2, 1, 4, 3, 2, 4, 3, 4};
    std::vector<int> sorted_ids = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
    std::vector<int> offset = {0, 1, 3, 6, 10};
    int const n = 10;
    int const m = 4;
    TEST_EQUALITY( ids_.size(), n );
    TEST_EQUALITY( sorted_ids.size(), n );
    TEST_EQUALITY( offset.size(), m + 1 );
    std::vector<int> results_ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::vector<std::set<int>> sorted_results = {
        {3}, {6, 2}, {8, 5, 1}, {9, 7, 4, 0},
    };
    std::vector<int> ranks_ = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
    std::vector<std::set<int>> sorted_ranks = {
        {13}, {16, 12}, {18, 15, 11}, {19, 17, 14, 10},
    };
    TEST_EQUALITY( results_.size(), n );
    TEST_EQUALITY( ranks_.size(), n );

    Kokkos::View<int *, DeviceType> ids( "query_ids", n );
    auto ids_host = Kokkos::create_mirror_view( ids );
    for ( int i = 0; i < n; ++i )
        ids_host( i ) = ids_[i];
    Kokkos::deep_copy( ids, ids_host );

    Kokkos::View<int *, DeviceType> results( "results", n );
    auto results_host = Kokkos::create_mirror_view( results );
    for ( int i = 0; i < n; ++i )
        results_host( i ) = results_[i];
    Kokkos::deep_copy( results, results_host );

    Kokkos::View<int *, DeviceType> ranks( "ranks", n );
    auto ranks_host = Kokkos::create_mirror_view( ranks );
    for ( int i = 0; i < n; ++i )
        ranks_host( i ) = ranks_[i];
    Kokkos::deep_copy( ranks, ranks_host );

    DataTransferKit::DistributedSearchTreeImpl<DeviceType>::sort_results(
        ids, results, ranks );

    // COMMENT: ids are untouched
    Kokkos::deep_copy( ids_host, ids );
    TEST_COMPARE_ARRAYS( ids_host, ids_ );

    Kokkos::deep_copy( results_host, results );
    Kokkos::deep_copy( ranks_host, ranks );
    for ( int q = 0; q < m; ++q )
        for ( int i = offset[q]; i < offset[q + 1]; ++i )
        {
            TEST_EQUALITY( sorted_results[q].count( results_host[i] ), 1 );
            TEST_EQUALITY( sorted_ranks[q].count( ranks_host[i] ), 1 );
        }
}

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl,
                                   count_results, DeviceType )
{
    std::vector<int> ids_ref = {4, 3, 2, 1, 4, 3, 2, 4, 3, 4};
    std::vector<int> offset_ref = {
        0, 0, 1, 3, 6, 10,
    };
    int const m = 5;
    int const nnz = 10;
    TEST_EQUALITY( ids_ref.size(), nnz );
    TEST_EQUALITY( offset_ref.size(), m + 1 );

    Kokkos::View<int *, DeviceType> ids( "query_ids", nnz );
    auto ids_host = Kokkos::create_mirror_view( ids );
    for ( int i = 0; i < nnz; ++i )
        ids_host( i ) = ids_ref[i];
    Kokkos::deep_copy( ids, ids_host );

    Kokkos::View<int *, DeviceType> offset( "offset" );

    DataTransferKit::DistributedSearchTreeImpl<DeviceType>::count_results(
        m, ids, offset );

    auto offset_host = Kokkos::create_mirror_view( offset );
    Kokkos::deep_copy( offset_host, offset );
    TEST_COMPARE_ARRAYS( offset_host, offset_ref );
}

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl,
                                   tpetra_fixme, DeviceType )
{
    Teuchos::RCP<const Teuchos::Comm<int>> comm =
        Teuchos::DefaultComm<int>::getComm();
    int const comm_rank = comm->getRank();
    int const comm_size = comm->getSize();

    Tpetra::Distributor distributor( comm );
    int const n = 3 * comm_size;
    Kokkos::View<int *, DeviceType> proc_ids( "proc_ids", n );
    int const n_exports = proc_ids.extent( 0 );
    using ExecutionSpace = typename DeviceType::execution_space;
    Kokkos::parallel_for(
        "fill_proc_ids", Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
        KOKKOS_LAMBDA( int i ) { proc_ids( i ) = i % comm_size; } );
    Kokkos::fence();
    auto proc_ids_host = Kokkos::create_mirror_view( proc_ids );
    Kokkos::deep_copy( proc_ids_host, proc_ids );
    int const n_imports = distributor.createFromSends(
        Teuchos::ArrayView<int const>( proc_ids_host.data(), n_exports ) );
    Kokkos::View<int *, DeviceType> exports( "exports", n_exports );
    Kokkos::parallel_for(
        "fill_exports", Kokkos::RangePolicy<ExecutionSpace>( 0, n_exports ),
        KOKKOS_LAMBDA( int i ) { exports( i ) = comm_rank; } );
    Kokkos::fence();

    Kokkos::View<int *, DeviceType> imports( "imports", n_imports );
// See https://github.com/trilinos/Trilinos/issues/1454
// The code compiles with the patch that was submitted.  Sticking with the
// workaround for now until we figure out what version of Trilinos goes into out
// Docker image.
#define WORKAROUND 1
#ifndef WORKAROUND
    distributor.doPostsAndWaits( exports, 1, imports );
    auto imports_host = Kokkos::create_mirror_view( imports );
    Kokkos::deep_copy( imports_host, imports );
#else
    auto exports_host = Kokkos::create_mirror_view( exports );
    Kokkos::deep_copy( exports_host, exports );
    auto imports_host = Kokkos::create_mirror_view( imports );
    distributor.doPostsAndWaits(
        Teuchos::ArrayView<int const>( exports_host.data(), n_exports ), 1,
        Teuchos::ArrayView<int>( imports_host.data(), n_imports ) );
    Kokkos::deep_copy( imports, imports_host );
#endif

    for ( int i = 0; i < n_imports; ++i )
        TEUCHOS_ASSERT_EQUALITY( imports_host( i ), i / 3 );
}

// Include the test macros.
#include "DataTransferKitSearch_ETIHelperMacros.h"

// Create the test group
#define UNIT_TEST_GROUP( NODE )                                                \
    using DeviceType##NODE = typename NODE::device_type;                       \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          recv_from, DeviceType##NODE )        \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          sort_results, DeviceType##NODE )     \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          count_results, DeviceType##NODE )    \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          tpetra_fixme, DeviceType##NODE )

// Demangle the types
DTK_ETI_MANGLING_TYPEDEFS()

// Instantiate the tests
DTK_INSTANTIATE_N( UNIT_TEST_GROUP )
<commit_msg>Get rid of "comparison between signed and unsigned integer expressions" warning that slipped into last PR<commit_after>/****************************************************************************
 * Copyright (c) 2012-2017 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 ****************************************************************************/

#include <details/DTK_DetailsDistributedSearchTreeImpl.hpp>

#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_UnitTestHarness.hpp>
#include <Tpetra_Distributor.hpp>

#include <algorithm>
#include <bitset>
#include <iostream>
#include <random>
#include <tuple>

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl, recv_from,
                                   DeviceType )
{
    // Checking that it is not necessary to send ranks because it can be
    // inferred from getProcsFrom() and getLengthsFrom().
    Teuchos::RCP<const Teuchos::Comm<int>> comm =
        Teuchos::DefaultComm<int>::getComm();
    int const comm_rank = comm->getRank();
    int const comm_size = comm->getSize();

    std::vector<int> tn( comm_size + 1 );
    for ( int i = 0; i < comm_size + 1; ++i )
        tn[i] = i * ( i - 1 ) / 2;

    // First use send buffer to set up the communication plan.  Sending 0
    // packet to rank 1, 1 packet to rank 1, 2 packets to rank 2, etc.
    int const n_exports = tn[comm_size];
    std::vector<int> exports( n_exports );
    for ( int i = 0; i < comm_size; ++i )
        for ( int j = tn[i]; j < tn[i + 1]; ++j )
            exports[j] = i;

    Tpetra::Distributor distributor( comm );
    int const n_imports = distributor.createFromSends(
        Teuchos::ArrayView<int>( exports.data(), exports.size() ) );
    TEUCHOS_ASSERT_EQUALITY( n_imports, comm_rank * comm_size );

    std::vector<int> imports( n_imports );
    distributor.doPostsAndWaits(
        Teuchos::ArrayView<int const>( exports.data(), exports.size() ), 1,
        Teuchos::ArrayView<int>( imports.data(), imports.size() ) );

    TEST_COMPARE_ARRAYS( imports, std::vector<int>( n_imports, comm_rank ) );

    // Then fill buffer with rank of the process that is sending packets.
    std::fill( exports.begin(), exports.end(), comm_rank );
    distributor.doPostsAndWaits(
        Teuchos::ArrayView<int const>( exports.data(), exports.size() ), 1,
        Teuchos::ArrayView<int>( imports.data(), imports.size() ) );

    auto procs_from = distributor.getProcsFrom();
    auto lengths_form = distributor.getLengthsFrom();
    TEST_EQUALITY( procs_from.size(), lengths_form.size() );
    std::vector<int> recv_from( n_imports, -1 );
    int count = 0;
    for ( auto i = 0; i < procs_from.size(); ++i )
        for ( size_t j = 0; j < lengths_form[i]; ++j )
            recv_from[count++] = procs_from[i];
    TEST_EQUALITY( count, n_imports );
    TEST_COMPARE_ARRAYS( imports, recv_from );
}

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl,
                                   sort_results, DeviceType )
{
    std::vector<int> ids_ = {4, 3, 2, 1, 4, 3, 2, 4, 3, 4};
    std::vector<int> sorted_ids = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
    std::vector<int> offset = {0, 1, 3, 6, 10};
    int const n = 10;
    int const m = 4;
    TEST_EQUALITY( ids_.size(), n );
    TEST_EQUALITY( sorted_ids.size(), n );
    TEST_EQUALITY( offset.size(), m + 1 );
    std::vector<int> results_ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::vector<std::set<int>> sorted_results = {
        {3}, {6, 2}, {8, 5, 1}, {9, 7, 4, 0},
    };
    std::vector<int> ranks_ = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
    std::vector<std::set<int>> sorted_ranks = {
        {13}, {16, 12}, {18, 15, 11}, {19, 17, 14, 10},
    };
    TEST_EQUALITY( results_.size(), n );
    TEST_EQUALITY( ranks_.size(), n );

    Kokkos::View<int *, DeviceType> ids( "query_ids", n );
    auto ids_host = Kokkos::create_mirror_view( ids );
    for ( int i = 0; i < n; ++i )
        ids_host( i ) = ids_[i];
    Kokkos::deep_copy( ids, ids_host );

    Kokkos::View<int *, DeviceType> results( "results", n );
    auto results_host = Kokkos::create_mirror_view( results );
    for ( int i = 0; i < n; ++i )
        results_host( i ) = results_[i];
    Kokkos::deep_copy( results, results_host );

    Kokkos::View<int *, DeviceType> ranks( "ranks", n );
    auto ranks_host = Kokkos::create_mirror_view( ranks );
    for ( int i = 0; i < n; ++i )
        ranks_host( i ) = ranks_[i];
    Kokkos::deep_copy( ranks, ranks_host );

    DataTransferKit::DistributedSearchTreeImpl<DeviceType>::sort_results(
        ids, results, ranks );

    // COMMENT: ids are untouched
    Kokkos::deep_copy( ids_host, ids );
    TEST_COMPARE_ARRAYS( ids_host, ids_ );

    Kokkos::deep_copy( results_host, results );
    Kokkos::deep_copy( ranks_host, ranks );
    for ( int q = 0; q < m; ++q )
        for ( int i = offset[q]; i < offset[q + 1]; ++i )
        {
            TEST_EQUALITY( sorted_results[q].count( results_host[i] ), 1 );
            TEST_EQUALITY( sorted_ranks[q].count( ranks_host[i] ), 1 );
        }
}

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl,
                                   count_results, DeviceType )
{
    std::vector<int> ids_ref = {4, 3, 2, 1, 4, 3, 2, 4, 3, 4};
    std::vector<int> offset_ref = {
        0, 0, 1, 3, 6, 10,
    };
    int const m = 5;
    int const nnz = 10;
    TEST_EQUALITY( ids_ref.size(), nnz );
    TEST_EQUALITY( offset_ref.size(), m + 1 );

    Kokkos::View<int *, DeviceType> ids( "query_ids", nnz );
    auto ids_host = Kokkos::create_mirror_view( ids );
    for ( int i = 0; i < nnz; ++i )
        ids_host( i ) = ids_ref[i];
    Kokkos::deep_copy( ids, ids_host );

    Kokkos::View<int *, DeviceType> offset( "offset" );

    DataTransferKit::DistributedSearchTreeImpl<DeviceType>::count_results(
        m, ids, offset );

    auto offset_host = Kokkos::create_mirror_view( offset );
    Kokkos::deep_copy( offset_host, offset );
    TEST_COMPARE_ARRAYS( offset_host, offset_ref );
}

TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DetailsDistributedSearchTreeImpl,
                                   tpetra_fixme, DeviceType )
{
    Teuchos::RCP<const Teuchos::Comm<int>> comm =
        Teuchos::DefaultComm<int>::getComm();
    int const comm_rank = comm->getRank();
    int const comm_size = comm->getSize();

    Tpetra::Distributor distributor( comm );
    int const n = 3 * comm_size;
    Kokkos::View<int *, DeviceType> proc_ids( "proc_ids", n );
    int const n_exports = proc_ids.extent( 0 );
    using ExecutionSpace = typename DeviceType::execution_space;
    Kokkos::parallel_for(
        "fill_proc_ids", Kokkos::RangePolicy<ExecutionSpace>( 0, n ),
        KOKKOS_LAMBDA( int i ) { proc_ids( i ) = i % comm_size; } );
    Kokkos::fence();
    auto proc_ids_host = Kokkos::create_mirror_view( proc_ids );
    Kokkos::deep_copy( proc_ids_host, proc_ids );
    int const n_imports = distributor.createFromSends(
        Teuchos::ArrayView<int const>( proc_ids_host.data(), n_exports ) );
    Kokkos::View<int *, DeviceType> exports( "exports", n_exports );
    Kokkos::parallel_for(
        "fill_exports", Kokkos::RangePolicy<ExecutionSpace>( 0, n_exports ),
        KOKKOS_LAMBDA( int i ) { exports( i ) = comm_rank; } );
    Kokkos::fence();

    Kokkos::View<int *, DeviceType> imports( "imports", n_imports );
// See https://github.com/trilinos/Trilinos/issues/1454
// The code compiles with the patch that was submitted.  Sticking with the
// workaround for now until we figure out what version of Trilinos goes into out
// Docker image.
#define WORKAROUND 1
#ifndef WORKAROUND
    distributor.doPostsAndWaits( exports, 1, imports );
    auto imports_host = Kokkos::create_mirror_view( imports );
    Kokkos::deep_copy( imports_host, imports );
#else
    auto exports_host = Kokkos::create_mirror_view( exports );
    Kokkos::deep_copy( exports_host, exports );
    auto imports_host = Kokkos::create_mirror_view( imports );
    distributor.doPostsAndWaits(
        Teuchos::ArrayView<int const>( exports_host.data(), n_exports ), 1,
        Teuchos::ArrayView<int>( imports_host.data(), n_imports ) );
    Kokkos::deep_copy( imports, imports_host );
#endif

    for ( int i = 0; i < n_imports; ++i )
        TEUCHOS_ASSERT_EQUALITY( imports_host( i ), i / 3 );
}

// Include the test macros.
#include "DataTransferKitSearch_ETIHelperMacros.h"

// Create the test group
#define UNIT_TEST_GROUP( NODE )                                                \
    using DeviceType##NODE = typename NODE::device_type;                       \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          recv_from, DeviceType##NODE )        \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          sort_results, DeviceType##NODE )     \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          count_results, DeviceType##NODE )    \
    TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DetailsDistributedSearchTreeImpl,    \
                                          tpetra_fixme, DeviceType##NODE )

// Demangle the types
DTK_ETI_MANGLING_TYPEDEFS()

// Instantiate the tests
DTK_INSTANTIATE_N( UNIT_TEST_GROUP )
<|endoftext|>


<commit_before>//
//  ResonantLowPassFilter.cpp
//  AudioKit Core
//
//  Created by Shane Dunne
//  Copyright © 2018 AudioKit and Apple.
//
// ResonantLowPassFilter implements a simple digital low-pass filter with dynamically
// adjustable cutoff frequency and resonance.

#include "ResonantLowPassFilter.hpp"
#include "FunctionTable.hpp"
#include <math.h>

namespace AudioKitCore
{
    // To avoid having to call sin() and cos() in setParams() (whenever filter parameters
    // are changed), we maintain this static sine lookup table.
    static FunctionTable sineTable;
    static float Sine(float phase) { return sineTable.interp_cyclic(phase); }
    static float Cosine(float phase) { return sineTable.interp_cyclic(phase + 0.25f); }

    static const float kMinCutoffHz = 12.0f;
    static const float kMinResLinear = 0.1f;
    static const float kMaxResLinear = 10.0f;

    ResonantLowPassFilter::ResonantLowPassFilter()
    {
        init(44100.0);  // sensible guess, will be overridden by init() call anyway

        if (sineTable.pWaveTable == 0)  // build sine table only once
        {
            sineTable.init(2048);
            sineTable.sinusoid();
        }
    }

    void ResonantLowPassFilter::init(double sampleRateHz)
    {
        this->sampleRateHz = sampleRateHz;
        x1 = x2 = y1 = y1 = 0.0;
        mLastCutoffHz = mLastResLinear = -1.0;  // force recalc of coefficients
    }

    void ResonantLowPassFilter::setParams(double newCutoffHz, double newResLinear)
    {
        // only calculate the filter coefficients if the parameters have changed from last time
        if (newCutoffHz == mLastCutoffHz && newResLinear == mLastResLinear) return;

        if (newCutoffHz < kMinCutoffHz) newCutoffHz = kMinCutoffHz;
        if (newResLinear < kMinResLinear ) newResLinear = kMinResLinear;
        if (newResLinear > kMaxResLinear ) newResLinear = kMaxResLinear;

        // convert cutoff from Hz to 0->1 normalized frequency
        double cutoff = 2.0 * newCutoffHz / sampleRateHz;
        if (cutoff > 0.99) cutoff = 0.99;   // clip

        mLastCutoffHz = newCutoffHz;
        mLastResLinear = newResLinear;

        double k = 0.5 * newResLinear * Sine(0.5 * cutoff);
        double c1 = 0.5 * (1.0 - k) / (1.0 + k);
        double c2 = (0.5 + c1) * Cosine(0.5 * cutoff);
        double c3 = (0.5 + c1 - c2) * 0.25;

        a0 = 2.0 * c3;
        a1 = 2.0 * 2.0 * c3;
        a2 = 2.0 * c3;
        b1 = 2.0 * -c2;
        b2 = 2.0 * c1;
    }

    void ResonantLowPassFilter::process(const float *sourceP, float *destP, int inFramesToProcess)
    {
        while (inFramesToProcess--)
        {
            float inputSample = *sourceP++;
            float outputSample = (float)(a0*inputSample + a1*x1 + a2*x2 - b1*y1 - b2*y2);
            if (!isnormal(outputSample))
                outputSample = 0.0f;

            x2 = x1;
            x1 = inputSample;
            y2 = y1;
            y1 = outputSample;

            *destP++ = outputSample;
        }
    }

    float ResonantLowPassFilter::process(float inputSample)
    {
        float outputSample = (float)(a0*inputSample + a1*x1 + a2*x2 - b1*y1 - b2*y2);
        if (!isnormal(outputSample))
            outputSample = 0.0f;

        x2 = x1;
        x1 = inputSample;
        y2 = y1;
        y1 = outputSample;

        return outputSample;
    }

}
<commit_msg>AudioKitCore::ResonantLowPassFilter CRITICAL BUG FIX<commit_after>//
//  ResonantLowPassFilter.cpp
//  AudioKit Core
//
//  Created by Shane Dunne
//  Copyright © 2018 AudioKit and Apple.
//
// ResonantLowPassFilter implements a simple digital low-pass filter with dynamically
// adjustable cutoff frequency and resonance.

#include "ResonantLowPassFilter.hpp"
#include "FunctionTable.hpp"
#include <math.h>

namespace AudioKitCore
{
    // To avoid having to call sin() and cos() in setParams() (whenever filter parameters
    // are changed), we maintain this static sine lookup table.
    static FunctionTable sineTable;
    static float Sine(float phase) { return sineTable.interp_cyclic(phase); }
    static float Cosine(float phase) { return sineTable.interp_cyclic(phase + 0.25f); }

    static const float kMinCutoffHz = 12.0f;
    static const float kMinResLinear = 0.1f;
    static const float kMaxResLinear = 10.0f;

    ResonantLowPassFilter::ResonantLowPassFilter()
    {
        init(44100.0);  // sensible guess, will be overridden by init() call anyway

        if (sineTable.pWaveTable == 0)  // build sine table only once
        {
            sineTable.init(2048);
            sineTable.sinusoid();
        }
    }

    void ResonantLowPassFilter::init(double sampleRateHz)
    {
        this->sampleRateHz = sampleRateHz;
        x1 = x2 = y1 = y2 = 0.0;
        mLastCutoffHz = mLastResLinear = -1.0;  // force recalc of coefficients
    }

    void ResonantLowPassFilter::setParams(double newCutoffHz, double newResLinear)
    {
        // only calculate the filter coefficients if the parameters have changed from last time
        if (newCutoffHz == mLastCutoffHz && newResLinear == mLastResLinear) return;

        if (newCutoffHz < kMinCutoffHz) newCutoffHz = kMinCutoffHz;
        if (newResLinear < kMinResLinear ) newResLinear = kMinResLinear;
        if (newResLinear > kMaxResLinear ) newResLinear = kMaxResLinear;

        // convert cutoff from Hz to 0->1 normalized frequency
        double cutoff = 2.0 * newCutoffHz / sampleRateHz;
        if (cutoff > 0.99) cutoff = 0.99;   // clip

        mLastCutoffHz = newCutoffHz;
        mLastResLinear = newResLinear;

        double k = 0.5 * newResLinear * Sine(0.5 * cutoff);
        double c1 = 0.5 * (1.0 - k) / (1.0 + k);
        double c2 = (0.5 + c1) * Cosine(0.5 * cutoff);
        double c3 = (0.5 + c1 - c2) * 0.25;

        a0 = 2.0 * c3;
        a1 = 2.0 * 2.0 * c3;
        a2 = 2.0 * c3;
        b1 = 2.0 * -c2;
        b2 = 2.0 * c1;
    }

    void ResonantLowPassFilter::process(const float *sourceP, float *destP, int inFramesToProcess)
    {
        while (inFramesToProcess--)
        {
            float inputSample = *sourceP++;
            float outputSample = (float)(a0*inputSample + a1*x1 + a2*x2 - b1*y1 - b2*y2);
            if (!isnormal(outputSample))
                outputSample = 0.0f;

            x2 = x1;
            x1 = inputSample;
            y2 = y1;
            y1 = outputSample;

            *destP++ = outputSample;
        }
    }

    float ResonantLowPassFilter::process(float inputSample)
    {
        float outputSample = (float)(a0*inputSample + a1*x1 + a2*x2 - b1*y1 - b2*y2);
        if (!isnormal(outputSample))
            outputSample = 0.0f;

        x2 = x1;
        x1 = inputSample;
        y2 = y1;
        y1 = outputSample;

        return outputSample;
    }

}
<|endoftext|>


<commit_before><commit_msg>Bugfix: added missing `#include` line.<commit_after><|endoftext|>