<commit_before>/*
 * Copyright 2008 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "condor_common.h"

#include "LoadPlugins.h"

#include "condor_config.h"
#include "directory.h"
#include "simplelist.h"

#ifndef WIN32
	#include <dlfcn.h>
#endif

const char * getErrorString()
{
	static std::string szError;

    #ifdef WIN32
        LPVOID lpMsgBuf;
		DWORD iErrCode = GetLastError();

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            (DWORD)iErrCode,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );

        szError =  (char *) lpMsgBuf;
		LocalFree(lpMsgBuf);

    #else
        szError = dlerror();
    #endif

    return szError.c_str();
}

void
LoadPlugins()
{
	static bool skip = false;

	const char *error;
	StringList plugins;
	char *plugin_files;
	MyString plugin_dir;
	const char *plugin_file;

		// Only initialize once /*, except for when we are force'd.*/
	if (skip /*&& !force*/) {
		return;
	}
	skip = true;

		// Setup the plugins StringList to contain the filenames for
		// dlopen. Either a PLUGINS config option is used, preferrably
		// setup as SUBSYSTEM.PLUGINS, or, in the absense of PLUGINS,
		// a PLUGINS_DIR config option is used, also
		// recommended SUBSYSTEM.PLUGINS_DIR.

	dprintf(D_FULLDEBUG, "Checking for PLUGINS config option\n");
	plugin_files = param("PLUGINS");
	if (!plugin_files) {
		char *tmp;
		dprintf(D_FULLDEBUG, "No PLUGINS config option, trying PLUGIN_DIR option\n");
		tmp = param("PLUGIN_DIR");
		if (!tmp) {
			dprintf(D_FULLDEBUG, "No PLUGIN_DIR config option, no plugins loaded\n");

			return;
		} else {
			plugin_dir = tmp;
			free(tmp); tmp = NULL;
			Directory directory(plugin_dir.Value());
			while (NULL != (plugin_file = directory.Next())) {
					// NOTE: This should eventually support .dll for
					// Windows, .dylib for Darwin, .sl for HPUX, etc
				if (0 == strcmp(".so", plugin_file + strlen(plugin_file) - 3)) {
					dprintf(D_FULLDEBUG,
							"PLUGIN_DIR, found: %s\n",
							plugin_file);
					plugins.append((plugin_dir + DIR_DELIM_STRING + plugin_file).Value());
				} else {
					dprintf(D_FULLDEBUG,
							"PLUGIN_DIR, ignoring: %s\n",
							plugin_file);
				}
			}
		}
	} else {
		plugins.initializeFromString(plugin_files);
		free(plugin_files); plugin_files = NULL;
	}

#ifndef WIN32
	dlerror(); // Clear error
#endif

	plugins.rewind();
	while (NULL != (plugin_file = plugins.next())) {
			// The plugin has a way to automatically register itself
			// when loaded.
			// XXX: When Jim's safe path checking code is available
			//      more generally in Condor the path to the
			//      plugin_file here MUST be checked!
#ifdef WIN32
        if( NULL == LoadLibrary(plugin_file) ) {
#else
		if (!dlopen(plugin_file, RTLD_NOW)) {
#endif
			error = getErrorString();
			if (error) {
				dprintf(D_ALWAYS,
						"Failed to load plugin: %s reason: %s\n",
						plugin_file,
						error);
			} else {
				dprintf(D_ALWAYS,
						"Unknown error while loading plugin: %s\n",
						plugin_file);
			}
		} else {
			dprintf(D_ALWAYS, "Successfully loaded plugin: %s\n", plugin_file);
		}
	}

		// NOTE: The handle returned is currently ignored,
		// which means closing is not possible.  This is due in part
		// to the uber scary nature of the linkage to daemon-core
}
<commit_msg>(#6343) Load plugins with global scope<commit_after>/*
 * Copyright 2008 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "condor_common.h"

#include "LoadPlugins.h"

#include "condor_config.h"
#include "directory.h"
#include "simplelist.h"

#ifndef WIN32
	#include <dlfcn.h>
#endif

const char * getErrorString()
{
	static std::string szError;

    #ifdef WIN32
        LPVOID lpMsgBuf;
		DWORD iErrCode = GetLastError();

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            (DWORD)iErrCode,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );

        szError =  (char *) lpMsgBuf;
		LocalFree(lpMsgBuf);

    #else
        szError = dlerror();
    #endif

    return szError.c_str();
}

void
LoadPlugins()
{
	static bool skip = false;

	const char *error;
	StringList plugins;
	char *plugin_files;
	MyString plugin_dir;
	const char *plugin_file;

		// Only initialize once /*, except for when we are force'd.*/
	if (skip /*&& !force*/) {
		return;
	}
	skip = true;

		// Setup the plugins StringList to contain the filenames for
		// dlopen. Either a PLUGINS config option is used, preferrably
		// setup as SUBSYSTEM.PLUGINS, or, in the absense of PLUGINS,
		// a PLUGINS_DIR config option is used, also
		// recommended SUBSYSTEM.PLUGINS_DIR.

	dprintf(D_FULLDEBUG, "Checking for PLUGINS config option\n");
	plugin_files = param("PLUGINS");
	if (!plugin_files) {
		char *tmp;
		dprintf(D_FULLDEBUG, "No PLUGINS config option, trying PLUGIN_DIR option\n");
		tmp = param("PLUGIN_DIR");
		if (!tmp) {
			dprintf(D_FULLDEBUG, "No PLUGIN_DIR config option, no plugins loaded\n");

			return;
		} else {
			plugin_dir = tmp;
			free(tmp); tmp = NULL;
			Directory directory(plugin_dir.Value());
			while (NULL != (plugin_file = directory.Next())) {
					// NOTE: This should eventually support .dll for
					// Windows, .dylib for Darwin, .sl for HPUX, etc
				if (0 == strcmp(".so", plugin_file + strlen(plugin_file) - 3)) {
					dprintf(D_FULLDEBUG,
							"PLUGIN_DIR, found: %s\n",
							plugin_file);
					plugins.append((plugin_dir + DIR_DELIM_STRING + plugin_file).Value());
				} else {
					dprintf(D_FULLDEBUG,
							"PLUGIN_DIR, ignoring: %s\n",
							plugin_file);
				}
			}
		}
	} else {
		plugins.initializeFromString(plugin_files);
		free(plugin_files); plugin_files = NULL;
	}

#ifndef WIN32
	dlerror(); // Clear error
#endif

	plugins.rewind();
	while (NULL != (plugin_file = plugins.next())) {
			// The plugin has a way to automatically register itself
			// when loaded.
			// XXX: When Jim's safe path checking code is available
			//      more generally in Condor the path to the
			//      plugin_file here MUST be checked!
#ifdef WIN32
        if( NULL == LoadLibrary(plugin_file) ) {
#else
		if (!dlopen(plugin_file, RTLD_NOW | RTLD_GLOBAL)) {
#endif
			error = getErrorString();
			if (error) {
				dprintf(D_ALWAYS,
						"Failed to load plugin: %s reason: %s\n",
						plugin_file,
						error);
			} else {
				dprintf(D_ALWAYS,
						"Unknown error while loading plugin: %s\n",
						plugin_file);
			}
		} else {
			dprintf(D_ALWAYS, "Successfully loaded plugin: %s\n", plugin_file);
		}
	}

		// NOTE: The handle returned is currently ignored,
		// which means closing is not possible.  This is due in part
		// to the uber scary nature of the linkage to daemon-core
}
<|endoftext|>


<commit_before>#ifndef CONTAINERS_BACKINDEX_BAG_HPP_
#define CONTAINERS_BACKINDEX_BAG_HPP_

#include <limits>

#include "containers/segmented_vector.hpp"

class backindex_bag_index_t {
public:
    backindex_bag_index_t()
        : index_(NOT_IN_A_BAG)
#ifndef NDEBUG
        , owner_(NULL)
#endif
    { }

    ~backindex_bag_index_t() {
        guarantee(index_ == NOT_IN_A_BAG);
    }

private:
    template <class T>
    friend class backindex_bag_t;

    static const size_t NOT_IN_A_BAG = std::numeric_limits<size_t>::max();

    // The item's index into a (specific) backindex_bag_t, or NOT_IN_A_BAG if it
    // doesn't belong to the backindex_bag_t.
    size_t index_;
#ifndef NDEBUG
    // RSI: Remove this?
    void *owner_;
#endif
    DISABLE_COPYING(backindex_bag_index_t);
};

// A bag of elements that it _does not own_.
template <class T>
class backindex_bag_t {
public:
    typedef backindex_bag_index_t *(*backindex_bag_index_accessor_t)(T);

    explicit backindex_bag_t(backindex_bag_index_accessor_t accessor)
        : accessor_(accessor) { }

    ~backindex_bag_t() {
        // Another way to implement this would be to simply remove all its elements.
        guarantee(vector_.size() == 0);
    }

    // Retruns true if the potential element of this container is in fact an element
    // of this container.  The idea behind this function is that some value of type T
    // could be a member of one of several backindex_bag_t's (or none).  We see if
    // it's a memory of this one.
    bool has_element(T potential_element) const {
        const backindex_bag_index_t *const backindex = accessor_(potential_element);
        bool ret = backindex->index_ < vector_.size()
            && vector_[backindex->index_] == potential_element;
        rassert(!ret || backindex->owner_ == this);
        return ret;
    }

    // Removes the element from the bag.
    void remove(T element) {
        backindex_bag_index_t *const backindex = accessor_(element);
        rassert(backindex->index_ != backindex_bag_index_t::NOT_IN_A_BAG);
        rassert(backindex->owner_ == this);
        guarantee(backindex->index_ < vector_.size(),
                  "early index has wrong value: index=%zu, size=%zu",
                  backindex->index_, vector_.size());

        const size_t index = backindex->index_;

        // Move the element in the last position to the removed element's position.
        // The code here feels weird when back_element == element (i.e. when
        // backindex->index_ == back_element_backindex->index_) but it works (I
        // hope).
        const T back_element = vector_.back();
        backindex_bag_index_t *const back_element_backindex = accessor_(back_element);

        rassert(back_element_backindex->owner_ == this);
        rassert(back_element_backindex->index_ == vector_.size() - 1,
                "index has wrong value: index=%zu, size=%zu",
                back_element_backindex->index_, vector_.size());

        back_element_backindex->index_ = index;
        vector_[index] = back_element;

        vector_.pop_back();

        backindex->index_ = backindex_bag_index_t::NOT_IN_A_BAG;
#ifndef NDEBUG
        backindex->owner_ = NULL;
#endif
    }

    // Adds the element to the bag.
    void add(T element) {
        backindex_bag_index_t *const backindex = accessor_(element);
        rassert(backindex->owner_ == NULL);
        guarantee(backindex->index_ == backindex_bag_index_t::NOT_IN_A_BAG);

        backindex->index_ = vector_.size();
#ifndef NDEBUG
        backindex->owner_ = this;
#endif
        vector_.push_back(element);
    }

    size_t size() const {
        return vector_.size();
    }

    // Accesses an element by index.  This is called "access random" because
    // hopefully the index was randomly generated.  There are no guarantees about the
    // ordering of elements in this bag.
    T access_random(size_t index) const {
        rassert(index != backindex_bag_index_t::NOT_IN_A_BAG);
        guarantee(index < vector_.size());
        return vector_[index];
    }

private:
    const backindex_bag_index_accessor_t accessor_;

    // RSP: Huge block size, shitty data structure for a bag.
    segmented_vector_t<T> vector_;

    DISABLE_COPYING(backindex_bag_t);
};

#endif  // CONTAINERS_BACKINDEX_BAG_HPP_
<commit_msg>Some debugfs and guarantees in backindex_bag.<commit_after>#ifndef CONTAINERS_BACKINDEX_BAG_HPP_
#define CONTAINERS_BACKINDEX_BAG_HPP_

#include <limits>

#include "containers/segmented_vector.hpp"

class backindex_bag_index_t {
public:
    backindex_bag_index_t()
        : index_(NOT_IN_A_BAG)
#ifndef NDEBUG
        , owner_(NULL)
#endif
    {
        debugf("index %p create\n", this);
    }

    ~backindex_bag_index_t() {
        debugf("index %p destroy\n", this);
        guarantee(index_ == NOT_IN_A_BAG);
    }

private:
    template <class T>
    friend class backindex_bag_t;

    static const size_t NOT_IN_A_BAG = std::numeric_limits<size_t>::max();

    // The item's index into a (specific) backindex_bag_t, or NOT_IN_A_BAG if it
    // doesn't belong to the backindex_bag_t.
    size_t index_;
#ifndef NDEBUG
    // RSI: Remove this?
    void *owner_;
#endif
    DISABLE_COPYING(backindex_bag_index_t);
};

// A bag of elements that it _does not own_.
template <class T>
class backindex_bag_t {
public:
    typedef backindex_bag_index_t *(*backindex_bag_index_accessor_t)(T);

    explicit backindex_bag_t(backindex_bag_index_accessor_t accessor)
        : accessor_(accessor) {
        debugf("bag %p create\n", this);
    }

    ~backindex_bag_t() {
        debugf("bag %p destroy\n", this);
        // Another way to implement this would be to simply remove all its elements.
        guarantee(vector_.size() == 0);
    }

    // Retruns true if the potential element of this container is in fact an element
    // of this container.  The idea behind this function is that some value of type T
    // could be a member of one of several backindex_bag_t's (or none).  We see if
    // it's a memory of this one.
    bool has_element(T potential_element) const {
        const backindex_bag_index_t *const backindex = accessor_(potential_element);
        bool ret = backindex->index_ < vector_.size()
            && vector_[backindex->index_] == potential_element;
        debugf("bag %p has_element index %p (index_ = %zu, ret = %d)\n",
               this, backindex, backindex->index_, static_cast<int>(ret));
        rassert(!ret || backindex->owner_ == this);
        return ret;
    }

    // Removes the element from the bag.
    void remove(T element) {
        backindex_bag_index_t *const backindex = accessor_(element);
        debugf("bag %p remove index %p (index_ = %zu)\n",
               this, backindex, backindex->index_);
        rassert(backindex->index_ != backindex_bag_index_t::NOT_IN_A_BAG);
        rassert(backindex->owner_ == this);
        guarantee(backindex->index_ < vector_.size(),
                  "early index has wrong value: index=%zu, size=%zu",
                  backindex->index_, vector_.size());

        const size_t index = backindex->index_;

        // Move the element in the last position to the removed element's position.
        // The code here feels weird when back_element == element (i.e. when
        // backindex->index_ == back_element_backindex->index_) but it works (I
        // hope).
        const T back_element = vector_.back();
        backindex_bag_index_t *const back_element_backindex = accessor_(back_element);

        debugf("bag %p remove.. move index %p (index_ = %zu) from %zu to new index_ = %zu\n",
               this, back_element_backindex, back_element_backindex->index_,
               vector_.size() - 1, index);
        rassert(back_element_backindex->owner_ == this);
        rassert(back_element_backindex->index_ == vector_.size() - 1,
                "bag %p: index %p has wrong value: index_ = %zu, size = %zu",
                this, back_element_backindex,
                back_element_backindex->index_, vector_.size());

        back_element_backindex->index_ = index;
        vector_[index] = back_element;

        vector_.pop_back();

        backindex->index_ = backindex_bag_index_t::NOT_IN_A_BAG;
#ifndef NDEBUG
        backindex->owner_ = NULL;
#endif
    }

    // Adds the element to the bag.
    void add(T element) {
        backindex_bag_index_t *const backindex = accessor_(element);
        rassert(backindex->owner_ == NULL,
                "bag %p, backindex = %p", this, backindex);
        guarantee(backindex->index_ == backindex_bag_index_t::NOT_IN_A_BAG,
                  "bag %p, backindex = %p", this, backindex);

        backindex->index_ = vector_.size();
        debugf("bag %p add index %p (set index_ = %zu)\n",
               this, backindex, backindex->index_);
#ifndef NDEBUG
        backindex->owner_ = this;
#endif
        vector_.push_back(element);
    }

    size_t size() const {
        return vector_.size();
    }

    // Accesses an element by index.  This is called "access random" because
    // hopefully the index was randomly generated.  There are no guarantees about the
    // ordering of elements in this bag.
    T access_random(size_t index) const {
        rassert(index != backindex_bag_index_t::NOT_IN_A_BAG);
        guarantee(index < vector_.size());
        return vector_[index];
    }

private:
    const backindex_bag_index_accessor_t accessor_;

    // RSP: Huge block size, shitty data structure for a bag.
    segmented_vector_t<T> vector_;

    DISABLE_COPYING(backindex_bag_t);
};

#endif  // CONTAINERS_BACKINDEX_BAG_HPP_
<|endoftext|>


<commit_before>#include "pairwise_clustering.h"

using namespace Pairwise;

void Clustering::initialize(ExpressionMatrix* input)
{
   // pre-allocate workspace
   _workLabels.resize(input->sampleSize());
}

qint8 Clustering::compute(
   const QVector<Vector2>& X,
   int numSamples,
   QVector<qint8>& labels,
   int minSamples,
   qint8 minClusters,
   qint8 maxClusters,
   Criterion criterion,
   bool removePreOutliers,
   bool removePostOutliers)
{
   // remove pre-clustering outliers
   if ( removePreOutliers )
   {
      markOutliers(X, numSamples, 0, labels, 0, -7);
      markOutliers(X, numSamples, 1, labels, 0, -7);
   }

   // perform clustering only if there are enough samples
   qint8 bestK = 0;

   if ( numSamples >= minSamples )
   {
      float bestValue = INFINITY;

      for ( qint8 K = minClusters; K <= maxClusters; ++K )
      {
         // run each clustering model
         bool success = fit(X, numSamples, K, _workLabels);

         if ( !success )
         {
            continue;
         }

         // evaluate model
         float value = INFINITY;

         switch (criterion)
         {
         case Criterion::AIC:
            value = computeAIC(K, 2, logLikelihood());
            break;
         case Criterion::BIC:
            value = computeBIC(K, 2, logLikelihood(), numSamples);
            break;
         case Criterion::ICL:
            value = computeICL(K, 2, logLikelihood(), numSamples, entropy());
            break;
         }

         // save the best model
         if ( value < bestValue )
         {
            bestK = K;
            bestValue = value;

            for ( int i = 0, j = 0; i < numSamples; ++i )
            {
               if ( labels[i] >= 0 )
               {
                  labels[i] = _workLabels[j];
                  ++j;
               }
            }
         }
      }
   }

   if ( bestK > 1 )
   {
      // remove post-clustering outliers
      if ( removePostOutliers )
      {
         for ( qint8 k = 0; k < bestK; ++k )
         {
            markOutliers(X, numSamples, 0, labels, k, -8);
            markOutliers(X, numSamples, 1, labels, k, -8);
         }
      }
   }

   return bestK;
}

void Clustering::markOutliers(const QVector<Vector2>& X, int N, int j, QVector<qint8>& labels, qint8 cluster, qint8 marker)
{
   // compute x_sorted = X[:, j], filtered and sorted
   QVector<float> x_sorted;
   x_sorted.reserve(N);

   for ( int i = 0; i < N; i++ )
   {
      if ( labels[i] == cluster || labels[i] == marker )
      {
         x_sorted.append(X[i].s[j]);
      }
   }

   if ( x_sorted.size() == 0 )
   {
      return;
   }

   std::sort(x_sorted.begin(), x_sorted.end());

   // compute quartiles, interquartile range, upper and lower bounds
   const int n = x_sorted.size();

   float Q1 = x_sorted[n * 1 / 4];
   float Q3 = x_sorted[n * 3 / 4];

   float T_min = Q1 - 1.5f * (Q3 - Q1);
   float T_max = Q3 + 1.5f * (Q3 - Q1);

   // mark outliers
   for ( int i = 0; i < N; ++i )
   {
      if ( labels[i] == cluster && (X[i].s[j] < T_min || T_max < X[i].s[j]) )
      {
         labels[i] = marker;
      }
   }
}

float Clustering::computeAIC(int K, int D, float logL)
{
   int p = K * (1 + D + D * D);

   return 2 * p - 2 * logL;
}

float Clustering::computeBIC(int K, int D, float logL, int N)
{
   int p = K * (1 + D + D * D);

   return log(N) * p - 2 * logL;
}

float Clustering::computeICL(int K, int D, float logL, int N, float E)
{
   int p = K * (1 + D + D * D);

   return log(N) * p - 2 * logL - 2 * E;
}
<commit_msg>Added comments<commit_after>#include "pairwise_clustering.h"

using namespace Pairwise;

void Clustering::initialize(ExpressionMatrix* input)
{
   // pre-allocate workspace
   _workLabels.resize(input->sampleSize());
}

/*!
 * Compute clusters for a given dataset. Several clustering models, each one
 * having a different number of clusters, are fit to the data and the model
 * with the best criterion value is selected.
 *
 * Note that the dataset contains only those samples which were not removed
 * by pre-processing, while the labels contains all samples from the original
 * expression matrix.
 *
 * @param X
 * @param numSamples
 * @param labels
 * @param minSamples
 * @param minSamples
 * @param minClusters
 * @param maxClusters
 * @param criterion
 * @param removePreOutliers
 * @param removePostOutliers
 */
qint8 Clustering::compute(
   const QVector<Vector2>& X,
   int numSamples,
   QVector<qint8>& labels,
   int minSamples,
   qint8 minClusters,
   qint8 maxClusters,
   Criterion criterion,
   bool removePreOutliers,
   bool removePostOutliers)
{
   // remove pre-clustering outliers
   if ( removePreOutliers )
   {
      markOutliers(X, numSamples, 0, labels, 0, -7);
      markOutliers(X, numSamples, 1, labels, 0, -7);
   }

   // perform clustering only if there are enough samples
   qint8 bestK = 0;

   if ( numSamples >= minSamples )
   {
      float bestValue = INFINITY;

      for ( qint8 K = minClusters; K <= maxClusters; ++K )
      {
         // run each clustering model
         bool success = fit(X, numSamples, K, _workLabels);

         if ( !success )
         {
            continue;
         }

         // evaluate model
         float value = INFINITY;

         switch (criterion)
         {
         case Criterion::AIC:
            value = computeAIC(K, 2, logLikelihood());
            break;
         case Criterion::BIC:
            value = computeBIC(K, 2, logLikelihood(), numSamples);
            break;
         case Criterion::ICL:
            value = computeICL(K, 2, logLikelihood(), numSamples, entropy());
            break;
         }

         // save the best model
         if ( value < bestValue )
         {
            bestK = K;
            bestValue = value;

            for ( int i = 0, j = 0; i < numSamples; ++i )
            {
               if ( labels[i] >= 0 )
               {
                  labels[i] = _workLabels[j];
                  ++j;
               }
            }
         }
      }
   }

   if ( bestK > 1 )
   {
      // remove post-clustering outliers
      if ( removePostOutliers )
      {
         for ( qint8 k = 0; k < bestK; ++k )
         {
            markOutliers(X, numSamples, 0, labels, k, -8);
            markOutliers(X, numSamples, 1, labels, k, -8);
         }
      }
   }

   return bestK;
}

void Clustering::markOutliers(const QVector<Vector2>& X, int N, int j, QVector<qint8>& labels, qint8 cluster, qint8 marker)
{
   // compute x_sorted = X[:, j], filtered and sorted
   QVector<float> x_sorted;
   x_sorted.reserve(N);

   for ( int i = 0; i < N; i++ )
   {
      if ( labels[i] == cluster || labels[i] == marker )
      {
         x_sorted.append(X[i].s[j]);
      }
   }

   if ( x_sorted.size() == 0 )
   {
      return;
   }

   std::sort(x_sorted.begin(), x_sorted.end());

   // compute quartiles, interquartile range, upper and lower bounds
   const int n = x_sorted.size();

   float Q1 = x_sorted[n * 1 / 4];
   float Q3 = x_sorted[n * 3 / 4];

   float T_min = Q1 - 1.5f * (Q3 - Q1);
   float T_max = Q3 + 1.5f * (Q3 - Q1);

   // mark outliers
   for ( int i = 0; i < N; ++i )
   {
      if ( labels[i] == cluster && (X[i].s[j] < T_min || T_max < X[i].s[j]) )
      {
         labels[i] = marker;
      }
   }
}

float Clustering::computeAIC(int K, int D, float logL)
{
   int p = K * (1 + D + D * D);

   return 2 * p - 2 * logL;
}

float Clustering::computeBIC(int K, int D, float logL, int N)
{
   int p = K * (1 + D + D * D);

   return log(N) * p - 2 * logL;
}

float Clustering::computeICL(int K, int D, float logL, int N, float E)
{
   int p = K * (1 + D + D * D);

   return log(N) * p - 2 * logL - 2 * E;
}
<|endoftext|>


<commit_before>#include "cmm_thread.h"
#include "debug.h"
#include <stdexcept>
#include <pthread.h>
#include <assert.h>
#include "pthread_util.h"
#include <algorithm>
#include <functional>
using std::for_each; using std::bind2nd;
using std::ptr_fun;

pthread_key_t thread_name_key;
static pthread_once_t key_once = PTHREAD_ONCE_INIT;

pthread_mutex_t CMMThread::joinable_lock = PTHREAD_MUTEX_INITIALIZER;
std::set<pthread_t> CMMThread::joinable_threads;

void
ThreadCleanup(void * arg)
{
    CMMThread *thread = (CMMThread *)arg;
    assert(thread);
    pthread_mutex_lock(&thread->starter_mutex);
    thread->running = false;
    pthread_mutex_unlock(&thread->starter_mutex);

    {
        PthreadScopedLock lock(&CMMThread::joinable_lock);
        CMMThread::joinable_threads.erase(thread->tid);
    }

    thread->Finish();
}

static void delete_name_string(void *arg)
{
    char *name_str = (char*)arg;
    delete [] name_str;
}

static void make_key()
{
    (void)pthread_key_create(&thread_name_key, delete_name_string);
    pthread_setspecific(thread_name_key, NULL);
}

void set_thread_name(const char *name)
{
    (void) pthread_once(&key_once, make_key);

    assert(name);
    char *old_name = (char*)pthread_getspecific(thread_name_key);
    delete [] old_name;

    char *name_str = new char[MAX_NAME_LEN+1];
    memset(name_str, 0, MAX_NAME_LEN+1);
    strncpy(name_str, name, MAX_NAME_LEN);
    pthread_setspecific(thread_name_key, name_str);
}

char * get_thread_name()
{
    (void) pthread_once(&key_once, make_key);

    char * name_str = (char*)pthread_getspecific(thread_name_key);
    if (!name_str) {
        char *name = new char[12];
        sprintf(name, "%08lx", pthread_self());
        pthread_setspecific(thread_name_key, name);
        name_str = name;
    }

    return name_str;
}

void *
ThreadFn(void * arg)
{
    pthread_cleanup_push(ThreadCleanup, arg);

    (void)get_thread_name();

    CMMThread *thread = (CMMThread*)arg;
    assert(thread);
    try {
	pthread_mutex_lock(&thread->starter_mutex);
        thread->running = true;
	pthread_cond_signal(&thread->starter_cv);
	pthread_mutex_unlock(&thread->starter_mutex);

        thread->Run();
	dbgprintf("Thread %08x exited normally.\n", pthread_self());
    } catch(const std::exception& e) {
	dbgprintf("Thread %08x exited: %s\n", pthread_self(), e.what());
    } catch(const CMMThreadFinish& e) {
	dbgprintf("Thread %08x was cancelled via exception.\n", pthread_self());
    }

    pthread_cleanup_pop(1);
    return NULL;
}

int
CMMThread::start()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 1024*1024);

    {
        PthreadScopedLock lock(&joinable_lock);
        int rc = pthread_create(&tid, &attr, ThreadFn, this);
        if (rc != 0) {
            dbgprintf("Failed to create thread! rc=%d\n", rc);
            return rc;
        }
        joinable_threads.insert(tid);
    }

    pthread_mutex_lock(&starter_mutex);
    while (!running) {
	pthread_cond_wait(&starter_cv, &starter_mutex);
    }
    pthread_mutex_unlock(&starter_mutex);

    return 0;
}

CMMThread::CMMThread()
    : tid(0), running(false)
{
    pthread_mutex_init(&starter_mutex, NULL);
    pthread_cond_init(&starter_cv, NULL);
}

CMMThread::~CMMThread()
{
    pthread_mutex_destroy(&starter_mutex);
    pthread_cond_destroy(&starter_cv);
}

void
CMMThread::stop()
{
    PthreadScopedLock lock(&starter_mutex);
    if (running) {
        lock.release();
        if (pthread_cancel(tid) == 0) {
            pthread_join(tid, NULL);
        }
    }
}

void
CMMThread::join()
{
    {
        PthreadScopedLock lock(&starter_mutex);
        if (running) {
            lock.release();
            pthread_join(tid, NULL);
        }
    }

    PthreadScopedLock j_lock(&joinable_lock);
    joinable_threads.erase(tid);
}

void
CMMThread::detach()
{
    assert(tid == pthread_self());
    {
        PthreadScopedLock j_lock(&joinable_lock);
        joinable_threads.erase(tid);
    }

    pthread_detach(tid);
}

void
CMMThread::join_all()
{
    std::set<pthread_t> joinable_threads_private;
    {
        PthreadScopedLock lock(&joinable_lock);
        joinable_threads_private = joinable_threads;
        joinable_threads.clear();
    }
    void **result = NULL;
    for (std::set<pthread_t>::iterator it = joinable_threads_private.begin();
         it != joinable_threads_private.end(); it++) {
        dbgprintf("pthread_join to thread %d\n", *it);
        pthread_join(*it, result);
    }
}
<commit_msg>Trying to figure out why CMMThreads are getting accessed after deletion.<commit_after>#include "cmm_thread.h"
#include "debug.h"
#include <stdexcept>
#include <pthread.h>
#include <assert.h>
#include "pthread_util.h"
#include <algorithm>
#include <functional>
using std::for_each; using std::bind2nd;
using std::ptr_fun;

pthread_key_t thread_name_key;
static pthread_once_t key_once = PTHREAD_ONCE_INIT;

pthread_mutex_t CMMThread::joinable_lock = PTHREAD_MUTEX_INITIALIZER;
std::set<pthread_t> CMMThread::joinable_threads;

void
ThreadCleanup(void * arg)
{
    CMMThread *thread = (CMMThread *)arg;
    assert(thread);
    pthread_mutex_lock(&thread->starter_mutex);
    thread->running = false;
    pthread_mutex_unlock(&thread->starter_mutex);

    {
        PthreadScopedLock lock(&CMMThread::joinable_lock);
        CMMThread::joinable_threads.erase(thread->tid);
    }

    thread->Finish();
}

static void delete_name_string(void *arg)
{
    char *name_str = (char*)arg;
    delete [] name_str;
}

static void make_key()
{
    (void)pthread_key_create(&thread_name_key, delete_name_string);
    pthread_setspecific(thread_name_key, NULL);
}

void set_thread_name(const char *name)
{
    (void) pthread_once(&key_once, make_key);

    assert(name);
    char *old_name = (char*)pthread_getspecific(thread_name_key);
    delete [] old_name;

    char *name_str = new char[MAX_NAME_LEN+1];
    memset(name_str, 0, MAX_NAME_LEN+1);
    strncpy(name_str, name, MAX_NAME_LEN);
    pthread_setspecific(thread_name_key, name_str);
}

char * get_thread_name()
{
    (void) pthread_once(&key_once, make_key);

    char * name_str = (char*)pthread_getspecific(thread_name_key);
    if (!name_str) {
        char *name = new char[12];
        sprintf(name, "%08lx", pthread_self());
        pthread_setspecific(thread_name_key, name);
        name_str = name;
    }

    return name_str;
}

void *
ThreadFn(void * arg)
{
    pthread_cleanup_push(ThreadCleanup, arg);

    (void)get_thread_name();

    CMMThread *thread = (CMMThread*)arg;
    assert(thread);
    try {
	pthread_mutex_lock(&thread->starter_mutex);
        thread->running = true;
	pthread_cond_signal(&thread->starter_cv);
	pthread_mutex_unlock(&thread->starter_mutex);

        thread->Run();
	dbgprintf("Thread %08x exited normally.\n", pthread_self());
    } catch(const std::exception& e) {
	dbgprintf("Thread %08x exited: %s\n", pthread_self(), e.what());
    } catch(const CMMThreadFinish& e) {
	dbgprintf("Thread %08x was cancelled via exception.\n", pthread_self());
    }

    pthread_cleanup_pop(1);
    return NULL;
}

int
CMMThread::start()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 1024*1024);

    {
        PthreadScopedLock lock(&joinable_lock);
        int rc = pthread_create(&tid, &attr, ThreadFn, this);
        if (rc != 0) {
            dbgprintf("Failed to create thread! rc=%d\n", rc);
            return rc;
        }
        joinable_threads.insert(tid);
    }

    pthread_mutex_lock(&starter_mutex);
    while (!running) {
	pthread_cond_wait(&starter_cv, &starter_mutex);
    }
    pthread_mutex_unlock(&starter_mutex);

    return 0;
}

CMMThread::CMMThread()
    : tid(0), running(false)
{
    pthread_mutex_init(&starter_mutex, NULL);
    pthread_cond_init(&starter_cv, NULL);
}

CMMThread::~CMMThread()
{
    dbgprintf("CMMThread %p is being destroyed\n", this);
    pthread_mutex_destroy(&starter_mutex);
    pthread_cond_destroy(&starter_cv);
}

void
CMMThread::stop()
{
    PthreadScopedLock lock(&starter_mutex);
    if (running) {
        lock.release();
        if (pthread_cancel(tid) == 0) {
            pthread_join(tid, NULL);
        }
    }
}

void
CMMThread::join()
{
    {
        PthreadScopedLock lock(&starter_mutex);
        if (running) {
            lock.release();
            pthread_join(tid, NULL);
        }
    }

    PthreadScopedLock j_lock(&joinable_lock);
    joinable_threads.erase(tid);
}

void
CMMThread::detach()
{
    assert(tid == pthread_self());
    {
        PthreadScopedLock j_lock(&joinable_lock);
        joinable_threads.erase(tid);
    }

    pthread_detach(tid);
}

void
CMMThread::join_all()
{
    std::set<pthread_t> joinable_threads_private;
    {
        PthreadScopedLock lock(&joinable_lock);
        joinable_threads_private = joinable_threads;
        joinable_threads.clear();
    }
    void **result = NULL;
    for (std::set<pthread_t>::iterator it = joinable_threads_private.begin();
         it != joinable_threads_private.end(); it++) {
        dbgprintf("pthread_join to thread %d\n", *it);
        pthread_join(*it, result);
    }
}
<|endoftext|>


<commit_before>#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include "cnfformula.h"
#include "structs.h"

/** creates a CNF formula with the given clauses and assignments, with default empty clause and empty assignment vectors */
CNFFormula::CNFFormula(unsigned int n, int k, const std::vector<CNFClause> & clauses, const std::vector<assignment> assignments):n(n), k(k), clauses(clauses),unchecked_assignments(assignments){
}

/** solves a CNF formula by brute force - going to all 2^n assignments.
    assigns satisfying_assignments to contain the satisfying assignments
    and sets was_solved to true. if was_solved is already set to true then we do
    not re-solve.*/
void CNFFormula::bruteforce_solve_sat(std::vector<short> partial){
  // we don't want to re-solve if it has already been solved
  if(was_solved){
    return;
  }

  if(partial.size() == 0){
    partial = std::vector<short>(n, -1);
  }

  std::vector<short> bitstring;
  //we enumerate all the bitstrings by taking all permutations of strings
  //that have i bits to 1
  for(unsigned int i = 0; i<=n; i++){
    bitstring = std::vector<short>(n, 0);
    for(unsigned int j = 0; j<i; j++){
      bitstring[j] = 1;
    }
    do {
      std::vector<short> bitstringwithpartial(n);
      for(int j = 0; j<n; j++){
        if(partial[j] != -1){
          bitstringwithpartial[j] = partial[j];
        }
        else{
          bitstringwithpartial[j] = bitstring[j];
        }
      }
      if(check_bitstring(bitstringwithpartial)){
        satisfying_assignments.push_back(bitstringwithpartial);
      }
    } while(std::prev_permutation(bitstring.begin(), bitstring.end()));
  }
  was_solved = true;
}

/** checks whether a bitstring solves a CNF formula
    @param bitstring the candidate bit string
    @return true if the bitstring satisfies the formula, false otw */
bool CNFFormula::check_bitstring(const std::vector<short> & bitstring) const {
  for(const auto & clause : clauses){
    if(!clause.check_bitstring(bitstring)){
      return false;
    }
  }
  return true;
}

/** adds a clause to the formula
    @param clause the clause to add */

void CNFFormula::add_clause(const CNFClause & clause){
  clauses.push_back(clause);
}

std::ostream& operator<<(std::ostream& out, const CNFFormula & formula){
  for(const auto & clause : formula.clauses){
    for(const auto & literal : clause){
      if(literal.value == 0){
        out << "~";
      }
      out << "x" << literal.variable+1 << ",";
    }
    out << std::endl;
  }
  if(formula.was_solved){
    out << "Assignments:" << std::endl;
    for(const auto & assig:formula.satisfying_assignments){
      int var = 1;
      for(const auto & lit : assig){
        out << "x" << var << "=" << lit << ",";
        var++;
      }
      out << std::endl;
    }
  }
  return out;
}

/** does the assignment passed in parameter, does not modify the current formula
    @param assg the assignment to make - 0 or 1 to corresponding variables, -1 for unassigned variables
    @ return a new CNFFormula with the assignment made */
CNFFormula CNFFormula::make_assignment(const assignment & assg) const {
//  assert(assg.size() == n);
  CNFFormula formula(n, k);
  for(const auto & clause : clauses){
    bool addit = true;
    for(const auto & lit : clause){
      //if the variable is not set in the assignment then nothing changes
      if(assg[lit.variable] == -1){
        continue;
      }
      // if a literal has the right value then the clause is satisfied and we do not add it
      if(lit.value == assg[lit.variable]){
        addit = false;
        continue;
      }
      //otherwise we create a new clause without the (unsatisfied) literal and we add it
      //(but not the original clause)
      else{
        CNFClause newclause;
        for(auto lit1 : clause){
          if(lit1.variable != lit.variable){
            newclause.add_literal(lit1);
          }
        }
        formula.add_clause(newclause);
        addit = false;
      }
    }
    //if we still need to add that clause then we do it
    if(addit){
      formula.add_clause(clause);
    }
  }
  return formula;
}

unsigned int CNFFormula::get_n() const{
  return n;
}

bool CNFFormula::is_unsat() const{
  for(auto const & clause : clauses){
    if(clause.size() == 0){
      return true;
    }
  }
  return false;
}

int CNFFormula::get_forced_value(int variable) const{
  for(auto const & clause : clauses){
    if(clause.size() == 1){
      if(clause.getliteral(0).variable == variable){
        return clause.getliteral(0).value;
      }
    }
  }
  return -1;
}

int CNFFormula::get_m() const{
  return clauses.size();
}

/** bruteforce solves to check if a variable is frozen. quite ugly,
    but since PPZ is slow as a tetraplegic turtle anyway... */
bool CNFFormula::is_frozen(int variable, std::vector<short> partial){
  bruteforce_solve_sat(partial);
  //if there is no satisfying assignment, the variable has the same value in all sat. assg.
  if(satisfying_assignments.size() == 0){
    return true;
  }
  short value = satisfying_assignments[0][variable];
  for(auto const & assig : satisfying_assignments){
    if(assig[variable] != value){
      return false;
    }
  }
  return true;
}
<commit_msg>removed a signed/unsigned warning<commit_after>#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include "cnfformula.h"
#include "structs.h"

/** creates a CNF formula with the given clauses and assignments, with default empty clause and empty assignment vectors */
CNFFormula::CNFFormula(unsigned int n, int k, const std::vector<CNFClause> & clauses, const std::vector<assignment> assignments):n(n), k(k), clauses(clauses),unchecked_assignments(assignments){
}

/** solves a CNF formula by brute force - going to all 2^n assignments.
    assigns satisfying_assignments to contain the satisfying assignments
    and sets was_solved to true. if was_solved is already set to true then we do
    not re-solve.*/
void CNFFormula::bruteforce_solve_sat(std::vector<short> partial){
  // we don't want to re-solve if it has already been solved
  if(was_solved){
    return;
  }

  if(partial.size() == 0){
    partial = std::vector<short>(n, -1);
  }

  std::vector<short> bitstring;
  //we enumerate all the bitstrings by taking all permutations of strings
  //that have i bits to 1
  for(unsigned int i = 0; i<=n; i++){
    bitstring = std::vector<short>(n, 0);
    for(unsigned int j = 0; j<i; j++){
      bitstring[j] = 1;
    }
    do {
      std::vector<short> bitstringwithpartial(n);
      for(unsigned int j = 0; j<n; j++){
        if(partial[j] != -1){
          bitstringwithpartial[j] = partial[j];
        }
        else{
          bitstringwithpartial[j] = bitstring[j];
        }
      }
      if(check_bitstring(bitstringwithpartial)){
        satisfying_assignments.push_back(bitstringwithpartial);
      }
    } while(std::prev_permutation(bitstring.begin(), bitstring.end()));
  }
  was_solved = true;
}

/** checks whether a bitstring solves a CNF formula
    @param bitstring the candidate bit string
    @return true if the bitstring satisfies the formula, false otw */
bool CNFFormula::check_bitstring(const std::vector<short> & bitstring) const {
  for(const auto & clause : clauses){
    if(!clause.check_bitstring(bitstring)){
      return false;
    }
  }
  return true;
}

/** adds a clause to the formula
    @param clause the clause to add */

void CNFFormula::add_clause(const CNFClause & clause){
  clauses.push_back(clause);
}

std::ostream& operator<<(std::ostream& out, const CNFFormula & formula){
  for(const auto & clause : formula.clauses){
    for(const auto & literal : clause){
      if(literal.value == 0){
        out << "~";
      }
      out << "x" << literal.variable+1 << ",";
    }
    out << std::endl;
  }
  if(formula.was_solved){
    out << "Assignments:" << std::endl;
    for(const auto & assig:formula.satisfying_assignments){
      int var = 1;
      for(const auto & lit : assig){
        out << "x" << var << "=" << lit << ",";
        var++;
      }
      out << std::endl;
    }
  }
  return out;
}

/** does the assignment passed in parameter, does not modify the current formula
    @param assg the assignment to make - 0 or 1 to corresponding variables, -1 for unassigned variables
    @ return a new CNFFormula with the assignment made */
CNFFormula CNFFormula::make_assignment(const assignment & assg) const {
//  assert(assg.size() == n);
  CNFFormula formula(n, k);
  for(const auto & clause : clauses){
    bool addit = true;
    for(const auto & lit : clause){
      //if the variable is not set in the assignment then nothing changes
      if(assg[lit.variable] == -1){
        continue;
      }
      // if a literal has the right value then the clause is satisfied and we do not add it
      if(lit.value == assg[lit.variable]){
        addit = false;
        continue;
      }
      //otherwise we create a new clause without the (unsatisfied) literal and we add it
      //(but not the original clause)
      else{
        CNFClause newclause;
        for(auto lit1 : clause){
          if(lit1.variable != lit.variable){
            newclause.add_literal(lit1);
          }
        }
        formula.add_clause(newclause);
        addit = false;
      }
    }
    //if we still need to add that clause then we do it
    if(addit){
      formula.add_clause(clause);
    }
  }
  return formula;
}

unsigned int CNFFormula::get_n() const{
  return n;
}

bool CNFFormula::is_unsat() const{
  for(auto const & clause : clauses){
    if(clause.size() == 0){
      return true;
    }
  }
  return false;
}

int CNFFormula::get_forced_value(int variable) const{
  for(auto const & clause : clauses){
    if(clause.size() == 1){
      if(clause.getliteral(0).variable == variable){
        return clause.getliteral(0).value;
      }
    }
  }
  return -1;
}

int CNFFormula::get_m() const{
  return clauses.size();
}

/** bruteforce solves to check if a variable is frozen. quite ugly,
    but since PPZ is slow as a tetraplegic turtle anyway... */
bool CNFFormula::is_frozen(int variable, std::vector<short> partial){
  bruteforce_solve_sat(partial);
  //if there is no satisfying assignment, the variable has the same value in all sat. assg.
  if(satisfying_assignments.size() == 0){
    return true;
  }
  short value = satisfying_assignments[0][variable];
  for(auto const & assig : satisfying_assignments){
    if(assig[variable] != value){
      return false;
    }
  }
  return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_posh/internal/popo/ports/server_port_roudi.hpp"

namespace iox
{
namespace popo
{
ServerPortRouDi::ServerPortRouDi(MemberType_t& serverPortData) noexcept
    : BasePort(&serverPortData)
    , m_chunkSender(&getMembers()->m_chunkSenderData)
    , m_chunkReceiver(&getMembers()->m_chunkReceiverData)

{
}

const ServerPortRouDi::MemberType_t* ServerPortRouDi::getMembers() const noexcept
{
    return reinterpret_cast<const MemberType_t*>(BasePort::getMembers());
}

ServerPortRouDi::MemberType_t* ServerPortRouDi::getMembers() noexcept
{
    return reinterpret_cast<MemberType_t*>(BasePort::getMembers());
}

ConsumerTooSlowPolicy ServerPortRouDi::getClientTooSlowPolicy() const noexcept
{
    return static_cast<ConsumerTooSlowPolicy>(getMembers()->m_chunkSenderData.m_subscriberTooSlowPolicy);
}

cxx::optional<capro::CaproMessage> ServerPortRouDi::tryGetCaProMessage() noexcept
{
    // get offer state request from user side
    const auto offeringRequested = getMembers()->m_offeringRequested.load(std::memory_order_relaxed);

    const auto isOffered = getMembers()->m_offered.load(std::memory_order_relaxed);

    if (isOffered)
    {
        if (!offeringRequested)
        {
            capro::CaproMessage caproMessage(capro::CaproMessageType::STOP_OFFER, this->getCaProServiceDescription());
            return dispatchCaProMessageAndGetPossibleResponse(caproMessage);
        }
    }
    else
    {
        if (offeringRequested)
        {
            capro::CaproMessage caproMessage(capro::CaproMessageType::OFFER, this->getCaProServiceDescription());
            return dispatchCaProMessageAndGetPossibleResponse(caproMessage);
        }
    }

    // nothing to change
    return cxx::nullopt;
}

cxx::optional<capro::CaproMessage>
ServerPortRouDi::dispatchCaProMessageAndGetPossibleResponse(const capro::CaproMessage& caProMessage) noexcept
{
    const auto isOffered = getMembers()->m_offered.load(std::memory_order_relaxed);

    return isOffered ? handleCaProMessageForStateOffered(caProMessage)
                     : handleCaProMessageForStateNotOffered(caProMessage);
}

void ServerPortRouDi::handleCaProProtocolViolation(const capro::CaproMessageType messageType) const noexcept
{
    // this shouldn't be reached
    LogFatal() << "CaPro Protocol Violation! Got '" << messageType << "' with offer state '"
               << (getMembers()->m_offered ? "OFFERED" : "NOT OFFERED") << "'!";
    errorHandler(Error::kPOPO__CAPRO_PROTOCOL_ERROR, nullptr, ErrorLevel::SEVERE);
}

cxx::optional<capro::CaproMessage>
ServerPortRouDi::handleCaProMessageForStateOffered(const capro::CaproMessage& caProMessage) noexcept
{
    capro::CaproMessage responseMessage{capro::CaproMessageType::NACK, this->getCaProServiceDescription()};

    switch (caProMessage.m_type)
    {
    case capro::CaproMessageType::STOP_OFFER:
        getMembers()->m_offered.store(false, std::memory_order_relaxed);
        m_chunkSender.removeAllQueues();
        return caProMessage;
    case capro::CaproMessageType::OFFER:
        return responseMessage;
    case capro::CaproMessageType::CONNECT:
        if (caProMessage.m_chunkQueueData == nullptr)
        {
            LogWarn() << "No client response queue passed to server";
            errorHandler(Error::kPOPO__SERVER_PORT_NO_CLIENT_RESPONSE_QUEUE_TO_CONNECT, nullptr, ErrorLevel::MODERATE);
        }
        else
        {
            m_chunkSender
                .tryAddQueue(static_cast<ClientChunkQueueData_t*>(caProMessage.m_chunkQueueData),
                             caProMessage.m_historyCapacity)
                .and_then([this, &responseMessage]() {
                    responseMessage.m_type = capro::CaproMessageType::ACK;
                    responseMessage.m_chunkQueueData = static_cast<void*>(&getMembers()->m_chunkReceiverData);
                    responseMessage.m_historyCapacity = 0;
                });
        }
        return responseMessage;
    case capro::CaproMessageType::DISCONNECT:
        m_chunkSender.tryRemoveQueue(static_cast<ClientChunkQueueData_t*>(caProMessage.m_chunkQueueData))
            .and_then([&responseMessage]() { responseMessage.m_type = capro::CaproMessageType::ACK; });
        return responseMessage;
    default:
        break;
    }

    handleCaProProtocolViolation(caProMessage.m_type);
    return cxx::nullopt;
}

cxx::optional<capro::CaproMessage>
ServerPortRouDi::handleCaProMessageForStateNotOffered(const capro::CaproMessage& caProMessage) noexcept
{
    switch (caProMessage.m_type)
    {
    case capro::CaproMessageType::OFFER:
        getMembers()->m_offered.store(true, std::memory_order_relaxed);
        return caProMessage;
    case capro::CaproMessageType::STOP_OFFER:
        IOX_FALLTHROUGH;
    case capro::CaproMessageType::CONNECT:
        IOX_FALLTHROUGH;
    case capro::CaproMessageType::DISCONNECT:
        return capro::CaproMessage(capro::CaproMessageType::NACK, this->getCaProServiceDescription());
    default:
        handleCaProProtocolViolation(caProMessage.m_type);
        return cxx::nullopt;
    }
}

void ServerPortRouDi::releaseAllChunks() noexcept
{
    m_chunkSender.releaseAll();
    m_chunkReceiver.releaseAll();
}

} // namespace popo
} // namespace iox
<commit_msg>iox-#27 Move capro protocol violation out of switch statement<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_posh/internal/popo/ports/server_port_roudi.hpp"

namespace iox
{
namespace popo
{
ServerPortRouDi::ServerPortRouDi(MemberType_t& serverPortData) noexcept
    : BasePort(&serverPortData)
    , m_chunkSender(&getMembers()->m_chunkSenderData)
    , m_chunkReceiver(&getMembers()->m_chunkReceiverData)

{
}

const ServerPortRouDi::MemberType_t* ServerPortRouDi::getMembers() const noexcept
{
    return reinterpret_cast<const MemberType_t*>(BasePort::getMembers());
}

ServerPortRouDi::MemberType_t* ServerPortRouDi::getMembers() noexcept
{
    return reinterpret_cast<MemberType_t*>(BasePort::getMembers());
}

ConsumerTooSlowPolicy ServerPortRouDi::getClientTooSlowPolicy() const noexcept
{
    return static_cast<ConsumerTooSlowPolicy>(getMembers()->m_chunkSenderData.m_subscriberTooSlowPolicy);
}

cxx::optional<capro::CaproMessage> ServerPortRouDi::tryGetCaProMessage() noexcept
{
    // get offer state request from user side
    const auto offeringRequested = getMembers()->m_offeringRequested.load(std::memory_order_relaxed);

    const auto isOffered = getMembers()->m_offered.load(std::memory_order_relaxed);

    if (isOffered)
    {
        if (!offeringRequested)
        {
            capro::CaproMessage caproMessage(capro::CaproMessageType::STOP_OFFER, this->getCaProServiceDescription());
            return dispatchCaProMessageAndGetPossibleResponse(caproMessage);
        }
    }
    else
    {
        if (offeringRequested)
        {
            capro::CaproMessage caproMessage(capro::CaproMessageType::OFFER, this->getCaProServiceDescription());
            return dispatchCaProMessageAndGetPossibleResponse(caproMessage);
        }
    }

    // nothing to change
    return cxx::nullopt;
}

cxx::optional<capro::CaproMessage>
ServerPortRouDi::dispatchCaProMessageAndGetPossibleResponse(const capro::CaproMessage& caProMessage) noexcept
{
    const auto isOffered = getMembers()->m_offered.load(std::memory_order_relaxed);

    return isOffered ? handleCaProMessageForStateOffered(caProMessage)
                     : handleCaProMessageForStateNotOffered(caProMessage);
}

void ServerPortRouDi::handleCaProProtocolViolation(const capro::CaproMessageType messageType) const noexcept
{
    // this shouldn't be reached
    LogFatal() << "CaPro Protocol Violation! Got '" << messageType << "' with offer state '"
               << (getMembers()->m_offered ? "OFFERED" : "NOT OFFERED") << "'!";
    errorHandler(Error::kPOPO__CAPRO_PROTOCOL_ERROR, nullptr, ErrorLevel::SEVERE);
}

cxx::optional<capro::CaproMessage>
ServerPortRouDi::handleCaProMessageForStateOffered(const capro::CaproMessage& caProMessage) noexcept
{
    capro::CaproMessage responseMessage{capro::CaproMessageType::NACK, this->getCaProServiceDescription()};

    switch (caProMessage.m_type)
    {
    case capro::CaproMessageType::STOP_OFFER:
        getMembers()->m_offered.store(false, std::memory_order_relaxed);
        m_chunkSender.removeAllQueues();
        return caProMessage;
    case capro::CaproMessageType::OFFER:
        return responseMessage;
    case capro::CaproMessageType::CONNECT:
        if (caProMessage.m_chunkQueueData == nullptr)
        {
            LogWarn() << "No client response queue passed to server";
            errorHandler(Error::kPOPO__SERVER_PORT_NO_CLIENT_RESPONSE_QUEUE_TO_CONNECT, nullptr, ErrorLevel::MODERATE);
        }
        else
        {
            m_chunkSender
                .tryAddQueue(static_cast<ClientChunkQueueData_t*>(caProMessage.m_chunkQueueData),
                             caProMessage.m_historyCapacity)
                .and_then([this, &responseMessage]() {
                    responseMessage.m_type = capro::CaproMessageType::ACK;
                    responseMessage.m_chunkQueueData = static_cast<void*>(&getMembers()->m_chunkReceiverData);
                    responseMessage.m_historyCapacity = 0;
                });
        }
        return responseMessage;
    case capro::CaproMessageType::DISCONNECT:
        m_chunkSender.tryRemoveQueue(static_cast<ClientChunkQueueData_t*>(caProMessage.m_chunkQueueData))
            .and_then([&responseMessage]() { responseMessage.m_type = capro::CaproMessageType::ACK; });
        return responseMessage;
    default:
        // leave switch statement and handle protocol violation
        break;
    }

    handleCaProProtocolViolation(caProMessage.m_type);
    return cxx::nullopt;
}

cxx::optional<capro::CaproMessage>
ServerPortRouDi::handleCaProMessageForStateNotOffered(const capro::CaproMessage& caProMessage) noexcept
{
    switch (caProMessage.m_type)
    {
    case capro::CaproMessageType::OFFER:
        getMembers()->m_offered.store(true, std::memory_order_relaxed);
        return caProMessage;
    case capro::CaproMessageType::STOP_OFFER:
        IOX_FALLTHROUGH;
    case capro::CaproMessageType::CONNECT:
        IOX_FALLTHROUGH;
    case capro::CaproMessageType::DISCONNECT:
        return capro::CaproMessage(capro::CaproMessageType::NACK, this->getCaProServiceDescription());
    default:
        // leave switch statement and handle protocol violation
        break;
    }

    handleCaProProtocolViolation(caProMessage.m_type);
    return cxx::nullopt;
}

void ServerPortRouDi::releaseAllChunks() noexcept
{
    m_chunkSender.releaseAll();
    m_chunkReceiver.releaseAll();
}

} // namespace popo
} // namespace iox
<|endoftext|>


<commit_before>// Copyright since 2016 : Evgenii Shatunov (github.com/FrankStain/jnipp)
// Apache 2.0 License
#pragma once

namespace Jni
{
namespace Marshaling
{
	inline void NativeTypeTraits<bool>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = ( source )? JNI_TRUE : JNI_FALSE;
	};

	inline void NativeTypeTraits<const char*>::ToJava( const NativeType& source, JavaType& destination )
	{
		auto local_env	= VirtualMachine::GetLocalEnvironment();
		destination		= local_env->NewStringUTF( source );
	};

	inline void NativeTypeTraits<const char16_t*>::ToJava( const NativeType& source, JavaType& destination )
	{
		auto local_env	= VirtualMachine::GetLocalEnvironment();
		destination		= local_env->NewString( reinterpret_cast<const jchar*>( source ), std::char_traits<char16_t>::length( source ) );
	};

	inline void NativeTypeTraits<std::string>::ToJava( const NativeType& source, JavaType& destination )
	{
		NativeTypeTraits<const char*>::ToJava( source.c_str(), destination );
	};

	inline void NativeTypeTraits<std::u16string>::ToJava( const NativeType& source, JavaType& destination )
	{
		NativeTypeTraits<const char16_t*>::ToJava( source.c_str(), destination );
	};

	inline void NativeTypeTraits<float>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<double>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int8_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<char16_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int16_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int32_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int64_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint8_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint16_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint32_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint64_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = reinterpret_cast<const int64_t&>( source );
	};

	template< typename TNativeElementType, typename TAllocatorType >
	inline void NativeTypeTraits<std::vector<TNativeElementType, TAllocatorType>>::ToJava( const NativeType& source, JavaType& destination )
	{

	};
};
};
<commit_msg>Native array translation function.<commit_after>// Copyright since 2016 : Evgenii Shatunov (github.com/FrankStain/jnipp)
// Apache 2.0 License
#pragma once

namespace Jni
{
namespace Marshaling
{
	inline void NativeTypeTraits<bool>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = ( source )? JNI_TRUE : JNI_FALSE;
	};

	inline void NativeTypeTraits<const char*>::ToJava( const NativeType& source, JavaType& destination )
	{
		auto local_env	= VirtualMachine::GetLocalEnvironment();
		destination		= local_env->NewStringUTF( source );
	};

	inline void NativeTypeTraits<const char16_t*>::ToJava( const NativeType& source, JavaType& destination )
	{
		auto local_env	= VirtualMachine::GetLocalEnvironment();
		destination		= local_env->NewString( reinterpret_cast<const jchar*>( source ), std::char_traits<char16_t>::length( source ) );
	};

	inline void NativeTypeTraits<std::string>::ToJava( const NativeType& source, JavaType& destination )
	{
		NativeTypeTraits<const char*>::ToJava( source.c_str(), destination );
	};

	inline void NativeTypeTraits<std::u16string>::ToJava( const NativeType& source, JavaType& destination )
	{
		NativeTypeTraits<const char16_t*>::ToJava( source.c_str(), destination );
	};

	inline void NativeTypeTraits<float>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<double>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int8_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<char16_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int16_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int32_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<int64_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint8_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint16_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint32_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = source;
	};

	inline void NativeTypeTraits<uint64_t>::ToJava( const NativeType& source, JavaType& destination )
	{
		destination = reinterpret_cast<const int64_t&>( source );
	};

	template< typename TNativeElementType, typename TAllocatorType >
	inline void NativeTypeTraits<std::vector<TNativeElementType, TAllocatorType>>::ToJava( const NativeType& source, JavaType& destination )
	{
		using ElementTraits = NativeTypeTraits<TNativeElementType>;

		constexpr auto ARRAY_CONSTRUCT_HANDLER	= ElementTraits::ARRAY_CONSTRUCT_HANDLER;

		auto local_env = VirtualMachine::GetLocalEnvironment();
		if( ElementTraits::IS_PLAIN )
		{
			constexpr auto ARRAY_ELEMENTS_ACQUIRE_HANDLER	= ElementTraits::ARRAY_ELEMENTS_ACQUIRE_HANDLER;
			constexpr auto ARRAY_ELEMENTS_RELEASE_HANDLER	= ElementTraits::ARRAY_ELEMENTS_RELEASE_HANDLER;

			destination = (local_env->*ARRAY_CONSTRUCT_HANDLER)( static_cast<jsize>( source.size() ) );
			JNI_RETURN_IF( source.empty() );

			auto array_elements = (local_env->*ARRAY_ELEMENTS_ACQUIRE_HANDLER)( source, nullptr );
			JNI_RETURN_IF_E( array_elements == nullptr, , "Failed to read elements of array." );

			std::transform(
				source.begin(), source.end(), array_elements,
				[]( const TNativeElementType& stored_value )
				{
					return Jni::Marshaling::ToJava<TNativeElementType>( stored_value );
				}
			);

			(local_env->*ARRAY_ELEMENTS_RELEASE_HANDLER)( source, array_elements, JNI_OK );
		}
		else
		{

		};
	};
};
};
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

   This program 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 2 of the License, or
   (at your option) any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <signaldata/DictTabInfo.hpp>
#include <ndb_limits.h>

//static
const
SimpleProperties::SP2StructMapping
DictTabInfo::TableMapping[] = {
  DTIMAPS(Table, TableName, TableName, 0, MAX_TAB_NAME_SIZE),
  DTIMAP(Table, TableId, TableId),
  DTIMAPS(Table, PrimaryTable, PrimaryTable, 0, MAX_TAB_NAME_SIZE),
  DTIMAP(Table, PrimaryTableId, PrimaryTableId),
  DTIMAP2(Table, TableLoggedFlag, TableLoggedFlag, 0, 1),
  DTIMAP2(Table, TableTemporaryFlag, TableTemporaryFlag, 0, 1),
  DTIMAP2(Table, TableKValue, TableKValue,         6, 6),
  DTIMAP2(Table, MinLoadFactor, MinLoadFactor,     0, 90),
  DTIMAP2(Table, MaxLoadFactor, MaxLoadFactor,    25, 110),
  DTIMAP2(Table, FragmentTypeVal, FragmentType,       0, 3),
  DTIMAP2(Table, TableTypeVal, TableType,         1, 3),
  DTIMAP(Table, NoOfKeyAttr, NoOfKeyAttr),
  DTIMAP2(Table, NoOfAttributes, NoOfAttributes, 1, MAX_ATTRIBUTES_IN_TABLE),
  DTIMAP(Table, NoOfNullable, NoOfNullable),
  DTIMAP2(Table, NoOfVariable, NoOfVariable,       0, 0),
  DTIMAP(Table, KeyLength, KeyLength),
  DTIMAP(Table, TableVersion, TableVersion),
  DTIMAP(Table, IndexState, IndexState),
  DTIMAP(Table, InsertTriggerId, InsertTriggerId),
  DTIMAP(Table, UpdateTriggerId, UpdateTriggerId),
  DTIMAP(Table, DeleteTriggerId, DeleteTriggerId),
  DTIMAP(Table, CustomTriggerId, CustomTriggerId),
  DTIMAP2(Table, FrmLen, FrmLen, 0, MAX_FRM_DATA_SIZE),
  DTIMAPB(Table, FrmData, FrmData, 0, MAX_FRM_DATA_SIZE, FrmLen),
  DTIMAP2(Table, FragmentCount, FragmentCount, 0, MAX_NDB_PARTITIONS),
  DTIMAP2(Table, ReplicaDataLen, ReplicaDataLen, 0, 2*MAX_FRAGMENT_DATA_BYTES),
  DTIMAPB(Table, ReplicaData, ReplicaData, 0, 2*MAX_FRAGMENT_DATA_BYTES, ReplicaDataLen),
  DTIMAP2(Table, FragmentDataLen, FragmentDataLen, 0, 6*MAX_NDB_PARTITIONS),
  DTIMAPB(Table, FragmentData, FragmentData, 0, 6*MAX_NDB_PARTITIONS, FragmentDataLen),
  DTIMAP2(Table, TablespaceDataLen, TablespaceDataLen, 0, 8*MAX_NDB_PARTITIONS),
  DTIMAPB(Table, TablespaceData, TablespaceData, 0, 8*MAX_NDB_PARTITIONS, TablespaceDataLen),
  DTIMAP2(Table, RangeListDataLen, RangeListDataLen, 0, 8*MAX_NDB_PARTITIONS),
  DTIMAPB(Table, RangeListData, RangeListData, 0, 8*MAX_NDB_PARTITIONS, RangeListDataLen),
  DTIMAP(Table, TablespaceId, TablespaceId),
  DTIMAP(Table, TablespaceVersion, TablespaceVersion),
  DTIMAP(Table, MaxRowsLow, MaxRowsLow),
  DTIMAP(Table, MaxRowsHigh, MaxRowsHigh),
  DTIMAP(Table, DefaultNoPartFlag, DefaultNoPartFlag),
  DTIMAP(Table, LinearHashFlag, LinearHashFlag),
  DTIMAP(Table, TablespaceVersion, TablespaceVersion),
  DTIMAP(Table, RowGCIFlag, RowGCIFlag),
  DTIMAP(Table, RowChecksumFlag, RowChecksumFlag),
  DTIMAP(Table, MaxRowsLow, MaxRowsLow),
  DTIMAP(Table, MaxRowsHigh, MaxRowsHigh),
  DTIMAP(Table, MinRowsLow, MinRowsLow),
  DTIMAP(Table, MinRowsHigh, MinRowsHigh),
  DTIBREAK(AttributeName)
};

//static
const Uint32 DictTabInfo::TableMappingSize =
sizeof(DictTabInfo::TableMapping) / sizeof(SimpleProperties::SP2StructMapping);

//static
const
SimpleProperties::SP2StructMapping
DictTabInfo::AttributeMapping[] = {
  DTIMAPS(Attribute, AttributeName, AttributeName, 0, MAX_ATTR_NAME_SIZE),
  DTIMAP(Attribute, AttributeId, AttributeId),
  DTIMAP(Attribute, AttributeType, AttributeType),
  DTIMAP2(Attribute, AttributeSize, AttributeSize,     3, 7),
  DTIMAP2(Attribute, AttributeArraySize, AttributeArraySize, 0, 65535),
  DTIMAP2(Attribute, AttributeArrayType, AttributeArrayType, 0, 3),
  DTIMAP2(Attribute, AttributeKeyFlag, AttributeKeyFlag, 0, 1),
  DTIMAP2(Attribute, AttributeNullableFlag, AttributeNullableFlag, 0, 1),
  DTIMAP2(Attribute, AttributeDKey, AttributeDKey, 0, 1),
  DTIMAP2(Attribute, AttributeStorageType, AttributeStorageType, 0, 1),
  DTIMAP(Attribute, AttributeExtType, AttributeExtType),
  DTIMAP(Attribute, AttributeExtPrecision, AttributeExtPrecision),
  DTIMAP(Attribute, AttributeExtScale, AttributeExtScale),
  DTIMAP(Attribute, AttributeExtLength, AttributeExtLength),
  DTIMAP2(Attribute, AttributeAutoIncrement, AttributeAutoIncrement, 0, 1),
  DTIMAPS(Attribute, AttributeDefaultValue, AttributeDefaultValue,
    0, MAX_ATTR_DEFAULT_VALUE_SIZE),
  DTIBREAK(AttributeEnd)
};

//static
const Uint32 DictTabInfo::AttributeMappingSize =
sizeof(DictTabInfo::AttributeMapping) /
sizeof(SimpleProperties::SP2StructMapping);

bool printDICTTABINFO(FILE * output, const Uint32 * theData,
		      Uint32 len, Uint16 receiverBlockNo)
{
//  const DictTabInfo * const sig = (DictTabInfo *) theData;

  fprintf(output, "Signal data: ");
  Uint32 i = 0;
  while (i < len)
    fprintf(output, "H\'%.8x ", theData[i++]);
  fprintf(output,"\n");
  return true;
}

void
DictTabInfo::Table::init(){
  memset(TableName, 0, sizeof(TableName));//TableName[0] = 0;
  TableId = ~0;
  memset(PrimaryTable, 0, sizeof(PrimaryTable));//PrimaryTable[0] = 0; // Only used when "index"
  PrimaryTableId = RNIL;
  TableLoggedFlag = 1;
  TableTemporaryFlag = 0;
  NoOfKeyAttr = 0;
  NoOfAttributes = 0;
  NoOfNullable = 0;
  NoOfVariable = 0;
  TableKValue = 6;
  MinLoadFactor = 78;
  MaxLoadFactor = 80;
  KeyLength = 0;
  FragmentType = DictTabInfo::AllNodesSmallTable;
  TableType = DictTabInfo::UndefTableType;
  TableVersion = 0;
  IndexState = ~0;
  InsertTriggerId = RNIL;
  UpdateTriggerId = RNIL;
  DeleteTriggerId = RNIL;
  CustomTriggerId = RNIL;
  FrmLen = 0;
  FragmentDataLen = 0;
  ReplicaDataLen = 0;
  RangeListDataLen = 0;
  TablespaceDataLen = 0;
  memset(FrmData, 0, sizeof(FrmData));
  memset(FragmentData, 0, sizeof(FragmentData));
  memset(ReplicaData, 0, sizeof(ReplicaData));
  memset(RangeListData, 0, sizeof(RangeListData));
  memset(TablespaceData, 0, sizeof(TablespaceData));
  FragmentCount = 0;
  TablespaceId = RNIL;
  TablespaceVersion = ~0;
  MaxRowsLow = 0;
  MaxRowsHigh = 0;
  DefaultNoPartFlag = 1;
  LinearHashFlag = 1;

  RowGCIFlag = ~0;
  RowChecksumFlag = ~0;

  MaxRowsLow = 0;
  MaxRowsHigh = 0;
  MinRowsLow = 0;
  MinRowsHigh = 0;
}

void
DictTabInfo::Attribute::init(){
  memset(AttributeName, 0, sizeof(AttributeName));//AttributeName[0] = 0;
  AttributeId = 0xFFFF; // ZNIL
  AttributeType = ~0, // deprecated
  AttributeSize = DictTabInfo::a32Bit;
  AttributeArraySize = 1;
  AttributeArrayType = NDB_ARRAYTYPE_FIXED;
  AttributeKeyFlag = 0;
  AttributeNullableFlag = 0;
  AttributeDKey = 0;
  AttributeExtType = DictTabInfo::ExtUnsigned,
  AttributeExtPrecision = 0,
  AttributeExtScale = 0,
  AttributeExtLength = 0,
  AttributeAutoIncrement = false;
  AttributeStorageType = 0;
  memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));//AttributeDefaultValue[0] = 0;
}

//static
const
SimpleProperties::SP2StructMapping
DictFilegroupInfo::Mapping[] = {
  DFGIMAPS(Filegroup, FilegroupName, FilegroupName, 0, MAX_TAB_NAME_SIZE),
  DFGIMAP2(Filegroup, FilegroupType, FilegroupType, 0, 1),
  DFGIMAP(Filegroup,  FilegroupId, FilegroupId),
  DFGIMAP(Filegroup,  FilegroupVersion, FilegroupVersion),

  DFGIMAP(Filegroup,  TS_ExtentSize,   TS_ExtentSize),
  DFGIMAP(Filegroup,  TS_LogfileGroupId, TS_LogfileGroupId),
  DFGIMAP(Filegroup,  TS_LogfileGroupVersion, TS_LogfileGroupVersion),
  DFGIMAP(Filegroup,  TS_GrowLimit, TS_DataGrow.GrowLimit),
  DFGIMAP(Filegroup,  TS_GrowSizeHi, TS_DataGrow.GrowSizeHi),
  DFGIMAP(Filegroup,  TS_GrowSizeLo, TS_DataGrow.GrowSizeLo),
  DFGIMAPS(Filegroup, TS_GrowPattern, TS_DataGrow.GrowPattern, 0, PATH_MAX),
  DFGIMAP(Filegroup,  TS_GrowMaxSize, TS_DataGrow.GrowMaxSize),

  DFGIMAP(Filegroup,  LF_UndoBufferSize, LF_UndoBufferSize),
  DFGIMAP(Filegroup,  LF_UndoGrowLimit, LF_UndoGrow.GrowLimit),
  DFGIMAP(Filegroup,  LF_UndoGrowSizeHi, LF_UndoGrow.GrowSizeHi),
  DFGIMAP(Filegroup,  LF_UndoGrowSizeLo, LF_UndoGrow.GrowSizeLo),
  DFGIMAPS(Filegroup, LF_UndoGrowPattern, LF_UndoGrow.GrowPattern, 0,PATH_MAX),
  DFGIMAP(Filegroup,  LF_UndoGrowMaxSize, LF_UndoGrow.GrowMaxSize),
  DFGIMAP(Filegroup,  LF_UndoFreeWordsHi, LF_UndoFreeWordsHi),
  DFGIMAP(Filegroup,  LF_UndoFreeWordsLo, LF_UndoFreeWordsLo),

  DFGIBREAK(FileName)
};

//static
const Uint32 DictFilegroupInfo::MappingSize =
sizeof(DictFilegroupInfo::Mapping) / sizeof(SimpleProperties::SP2StructMapping);

//static
const
SimpleProperties::SP2StructMapping
DictFilegroupInfo::FileMapping[] = {
  DFGIMAPS(File, FileName, FileName, 0, PATH_MAX),
  DFGIMAP2(File, FileType, FileType, 0, 1),
  DFGIMAP(File, FileId, FileId),
  DFGIMAP(File, FileVersion, FileVersion),
  DFGIMAP(File, FileFGroupId, FilegroupId),
  DFGIMAP(File, FileFGroupVersion, FilegroupVersion),
  DFGIMAP(File, FileSizeHi, FileSizeHi),
  DFGIMAP(File, FileSizeLo, FileSizeLo),
  DFGIMAP(File, FileFreeExtents, FileFreeExtents),
  DFGIBREAK(FileEnd)
};

//static
const Uint32 DictFilegroupInfo::FileMappingSize =
sizeof(DictFilegroupInfo::FileMapping) /
sizeof(SimpleProperties::SP2StructMapping);

void
DictFilegroupInfo::Filegroup::init(){
  memset(FilegroupName, 0, sizeof(FilegroupName));
  FilegroupType = ~0;
  FilegroupId = ~0;
  FilegroupVersion = ~0;

  TS_ExtentSize = 0;
  TS_LogfileGroupId = ~0;
  TS_LogfileGroupVersion = ~0;
  TS_DataGrow.GrowLimit = 0;
  TS_DataGrow.GrowSizeHi = 0;
  TS_DataGrow.GrowSizeLo = 0;
  memset(TS_DataGrow.GrowPattern, 0, sizeof(TS_DataGrow.GrowPattern));
  TS_DataGrow.GrowMaxSize = 0;
  LF_UndoFreeWordsHi= 0;
  LF_UndoFreeWordsLo= 0;
}

void
DictFilegroupInfo::File::init(){
  memset(FileName, sizeof(FileName), 0);
  FileType = ~0;
  FileId = ~0;
  FileVersion = ~0;
  FilegroupId = ~0;
  FilegroupVersion = ~0;
  FileSizeHi = 0;
  FileSizeLo = 0;
  FileFreeExtents = 0;
}

// blob table name hack

bool
DictTabInfo::isBlobTableName(const char* name, Uint32* ptab_id, Uint32* pcol_no)
{
  const char* const prefix = "NDB$BLOB_";
  const char* s = strrchr(name, table_name_separator);
  s = (s == NULL ? name : s + 1);
  if (strncmp(s, prefix, strlen(prefix)) != 0)
    return false;
  s += strlen(prefix);
  uint i, n;
  for (i = 0, n = 0; '0' <= s[i] && s[i] <= '9'; i++)
    n = 10 * n + (s[i] - '0');
  if (i == 0 || s[i] != '_')
    return false;
  const uint tab_id = n;
  s = &s[i + 1];
  for (i = 0, n = 0; '0' <= s[i] && s[i] <= '9'; i++)
    n = 10 * n + (s[i] - '0');
  if (i == 0 || s[i] != 0)
    return false;
  const uint col_no = n;
  if (ptab_id)
    *ptab_id = tab_id;
  if (pcol_no)
    *pcol_no = col_no;
  return true;
}
<commit_msg>DictTabInfo.cpp:   Fix for bug#23169 - memset param switching<commit_after>/* Copyright (C) 2003 MySQL AB

   This program 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 2 of the License, or
   (at your option) any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <signaldata/DictTabInfo.hpp>
#include <ndb_limits.h>

//static
const
SimpleProperties::SP2StructMapping
DictTabInfo::TableMapping[] = {
  DTIMAPS(Table, TableName, TableName, 0, MAX_TAB_NAME_SIZE),
  DTIMAP(Table, TableId, TableId),
  DTIMAPS(Table, PrimaryTable, PrimaryTable, 0, MAX_TAB_NAME_SIZE),
  DTIMAP(Table, PrimaryTableId, PrimaryTableId),
  DTIMAP2(Table, TableLoggedFlag, TableLoggedFlag, 0, 1),
  DTIMAP2(Table, TableTemporaryFlag, TableTemporaryFlag, 0, 1),
  DTIMAP2(Table, TableKValue, TableKValue,         6, 6),
  DTIMAP2(Table, MinLoadFactor, MinLoadFactor,     0, 90),
  DTIMAP2(Table, MaxLoadFactor, MaxLoadFactor,    25, 110),
  DTIMAP2(Table, FragmentTypeVal, FragmentType,       0, 3),
  DTIMAP2(Table, TableTypeVal, TableType,         1, 3),
  DTIMAP(Table, NoOfKeyAttr, NoOfKeyAttr),
  DTIMAP2(Table, NoOfAttributes, NoOfAttributes, 1, MAX_ATTRIBUTES_IN_TABLE),
  DTIMAP(Table, NoOfNullable, NoOfNullable),
  DTIMAP2(Table, NoOfVariable, NoOfVariable,       0, 0),
  DTIMAP(Table, KeyLength, KeyLength),
  DTIMAP(Table, TableVersion, TableVersion),
  DTIMAP(Table, IndexState, IndexState),
  DTIMAP(Table, InsertTriggerId, InsertTriggerId),
  DTIMAP(Table, UpdateTriggerId, UpdateTriggerId),
  DTIMAP(Table, DeleteTriggerId, DeleteTriggerId),
  DTIMAP(Table, CustomTriggerId, CustomTriggerId),
  DTIMAP2(Table, FrmLen, FrmLen, 0, MAX_FRM_DATA_SIZE),
  DTIMAPB(Table, FrmData, FrmData, 0, MAX_FRM_DATA_SIZE, FrmLen),
  DTIMAP2(Table, FragmentCount, FragmentCount, 0, MAX_NDB_PARTITIONS),
  DTIMAP2(Table, ReplicaDataLen, ReplicaDataLen, 0, 2*MAX_FRAGMENT_DATA_BYTES),
  DTIMAPB(Table, ReplicaData, ReplicaData, 0, 2*MAX_FRAGMENT_DATA_BYTES, ReplicaDataLen),
  DTIMAP2(Table, FragmentDataLen, FragmentDataLen, 0, 6*MAX_NDB_PARTITIONS),
  DTIMAPB(Table, FragmentData, FragmentData, 0, 6*MAX_NDB_PARTITIONS, FragmentDataLen),
  DTIMAP2(Table, TablespaceDataLen, TablespaceDataLen, 0, 8*MAX_NDB_PARTITIONS),
  DTIMAPB(Table, TablespaceData, TablespaceData, 0, 8*MAX_NDB_PARTITIONS, TablespaceDataLen),
  DTIMAP2(Table, RangeListDataLen, RangeListDataLen, 0, 8*MAX_NDB_PARTITIONS),
  DTIMAPB(Table, RangeListData, RangeListData, 0, 8*MAX_NDB_PARTITIONS, RangeListDataLen),
  DTIMAP(Table, TablespaceId, TablespaceId),
  DTIMAP(Table, TablespaceVersion, TablespaceVersion),
  DTIMAP(Table, MaxRowsLow, MaxRowsLow),
  DTIMAP(Table, MaxRowsHigh, MaxRowsHigh),
  DTIMAP(Table, DefaultNoPartFlag, DefaultNoPartFlag),
  DTIMAP(Table, LinearHashFlag, LinearHashFlag),
  DTIMAP(Table, TablespaceVersion, TablespaceVersion),
  DTIMAP(Table, RowGCIFlag, RowGCIFlag),
  DTIMAP(Table, RowChecksumFlag, RowChecksumFlag),
  DTIMAP(Table, MaxRowsLow, MaxRowsLow),
  DTIMAP(Table, MaxRowsHigh, MaxRowsHigh),
  DTIMAP(Table, MinRowsLow, MinRowsLow),
  DTIMAP(Table, MinRowsHigh, MinRowsHigh),
  DTIBREAK(AttributeName)
};

//static
const Uint32 DictTabInfo::TableMappingSize =
sizeof(DictTabInfo::TableMapping) / sizeof(SimpleProperties::SP2StructMapping);

//static
const
SimpleProperties::SP2StructMapping
DictTabInfo::AttributeMapping[] = {
  DTIMAPS(Attribute, AttributeName, AttributeName, 0, MAX_ATTR_NAME_SIZE),
  DTIMAP(Attribute, AttributeId, AttributeId),
  DTIMAP(Attribute, AttributeType, AttributeType),
  DTIMAP2(Attribute, AttributeSize, AttributeSize,     3, 7),
  DTIMAP2(Attribute, AttributeArraySize, AttributeArraySize, 0, 65535),
  DTIMAP2(Attribute, AttributeArrayType, AttributeArrayType, 0, 3),
  DTIMAP2(Attribute, AttributeKeyFlag, AttributeKeyFlag, 0, 1),
  DTIMAP2(Attribute, AttributeNullableFlag, AttributeNullableFlag, 0, 1),
  DTIMAP2(Attribute, AttributeDKey, AttributeDKey, 0, 1),
  DTIMAP2(Attribute, AttributeStorageType, AttributeStorageType, 0, 1),
  DTIMAP(Attribute, AttributeExtType, AttributeExtType),
  DTIMAP(Attribute, AttributeExtPrecision, AttributeExtPrecision),
  DTIMAP(Attribute, AttributeExtScale, AttributeExtScale),
  DTIMAP(Attribute, AttributeExtLength, AttributeExtLength),
  DTIMAP2(Attribute, AttributeAutoIncrement, AttributeAutoIncrement, 0, 1),
  DTIMAPS(Attribute, AttributeDefaultValue, AttributeDefaultValue,
    0, MAX_ATTR_DEFAULT_VALUE_SIZE),
  DTIBREAK(AttributeEnd)
};

//static
const Uint32 DictTabInfo::AttributeMappingSize =
sizeof(DictTabInfo::AttributeMapping) /
sizeof(SimpleProperties::SP2StructMapping);

bool printDICTTABINFO(FILE * output, const Uint32 * theData,
		      Uint32 len, Uint16 receiverBlockNo)
{
//  const DictTabInfo * const sig = (DictTabInfo *) theData;

  fprintf(output, "Signal data: ");
  Uint32 i = 0;
  while (i < len)
    fprintf(output, "H\'%.8x ", theData[i++]);
  fprintf(output,"\n");
  return true;
}

void
DictTabInfo::Table::init(){
  memset(TableName, 0, sizeof(TableName));//TableName[0] = 0;
  TableId = ~0;
  memset(PrimaryTable, 0, sizeof(PrimaryTable));//PrimaryTable[0] = 0; // Only used when "index"
  PrimaryTableId = RNIL;
  TableLoggedFlag = 1;
  TableTemporaryFlag = 0;
  NoOfKeyAttr = 0;
  NoOfAttributes = 0;
  NoOfNullable = 0;
  NoOfVariable = 0;
  TableKValue = 6;
  MinLoadFactor = 78;
  MaxLoadFactor = 80;
  KeyLength = 0;
  FragmentType = DictTabInfo::AllNodesSmallTable;
  TableType = DictTabInfo::UndefTableType;
  TableVersion = 0;
  IndexState = ~0;
  InsertTriggerId = RNIL;
  UpdateTriggerId = RNIL;
  DeleteTriggerId = RNIL;
  CustomTriggerId = RNIL;
  FrmLen = 0;
  FragmentDataLen = 0;
  ReplicaDataLen = 0;
  RangeListDataLen = 0;
  TablespaceDataLen = 0;
  memset(FrmData, 0, sizeof(FrmData));
  memset(FragmentData, 0, sizeof(FragmentData));
  memset(ReplicaData, 0, sizeof(ReplicaData));
  memset(RangeListData, 0, sizeof(RangeListData));
  memset(TablespaceData, 0, sizeof(TablespaceData));
  FragmentCount = 0;
  TablespaceId = RNIL;
  TablespaceVersion = ~0;
  MaxRowsLow = 0;
  MaxRowsHigh = 0;
  DefaultNoPartFlag = 1;
  LinearHashFlag = 1;

  RowGCIFlag = ~0;
  RowChecksumFlag = ~0;

  MaxRowsLow = 0;
  MaxRowsHigh = 0;
  MinRowsLow = 0;
  MinRowsHigh = 0;
}

void
DictTabInfo::Attribute::init(){
  memset(AttributeName, 0, sizeof(AttributeName));//AttributeName[0] = 0;
  AttributeId = 0xFFFF; // ZNIL
  AttributeType = ~0, // deprecated
  AttributeSize = DictTabInfo::a32Bit;
  AttributeArraySize = 1;
  AttributeArrayType = NDB_ARRAYTYPE_FIXED;
  AttributeKeyFlag = 0;
  AttributeNullableFlag = 0;
  AttributeDKey = 0;
  AttributeExtType = DictTabInfo::ExtUnsigned,
  AttributeExtPrecision = 0,
  AttributeExtScale = 0,
  AttributeExtLength = 0,
  AttributeAutoIncrement = false;
  AttributeStorageType = 0;
  memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));//AttributeDefaultValue[0] = 0;
}

//static
const
SimpleProperties::SP2StructMapping
DictFilegroupInfo::Mapping[] = {
  DFGIMAPS(Filegroup, FilegroupName, FilegroupName, 0, MAX_TAB_NAME_SIZE),
  DFGIMAP2(Filegroup, FilegroupType, FilegroupType, 0, 1),
  DFGIMAP(Filegroup,  FilegroupId, FilegroupId),
  DFGIMAP(Filegroup,  FilegroupVersion, FilegroupVersion),

  DFGIMAP(Filegroup,  TS_ExtentSize,   TS_ExtentSize),
  DFGIMAP(Filegroup,  TS_LogfileGroupId, TS_LogfileGroupId),
  DFGIMAP(Filegroup,  TS_LogfileGroupVersion, TS_LogfileGroupVersion),
  DFGIMAP(Filegroup,  TS_GrowLimit, TS_DataGrow.GrowLimit),
  DFGIMAP(Filegroup,  TS_GrowSizeHi, TS_DataGrow.GrowSizeHi),
  DFGIMAP(Filegroup,  TS_GrowSizeLo, TS_DataGrow.GrowSizeLo),
  DFGIMAPS(Filegroup, TS_GrowPattern, TS_DataGrow.GrowPattern, 0, PATH_MAX),
  DFGIMAP(Filegroup,  TS_GrowMaxSize, TS_DataGrow.GrowMaxSize),

  DFGIMAP(Filegroup,  LF_UndoBufferSize, LF_UndoBufferSize),
  DFGIMAP(Filegroup,  LF_UndoGrowLimit, LF_UndoGrow.GrowLimit),
  DFGIMAP(Filegroup,  LF_UndoGrowSizeHi, LF_UndoGrow.GrowSizeHi),
  DFGIMAP(Filegroup,  LF_UndoGrowSizeLo, LF_UndoGrow.GrowSizeLo),
  DFGIMAPS(Filegroup, LF_UndoGrowPattern, LF_UndoGrow.GrowPattern, 0,PATH_MAX),
  DFGIMAP(Filegroup,  LF_UndoGrowMaxSize, LF_UndoGrow.GrowMaxSize),
  DFGIMAP(Filegroup,  LF_UndoFreeWordsHi, LF_UndoFreeWordsHi),
  DFGIMAP(Filegroup,  LF_UndoFreeWordsLo, LF_UndoFreeWordsLo),

  DFGIBREAK(FileName)
};

//static
const Uint32 DictFilegroupInfo::MappingSize =
sizeof(DictFilegroupInfo::Mapping) / sizeof(SimpleProperties::SP2StructMapping);

//static
const
SimpleProperties::SP2StructMapping
DictFilegroupInfo::FileMapping[] = {
  DFGIMAPS(File, FileName, FileName, 0, PATH_MAX),
  DFGIMAP2(File, FileType, FileType, 0, 1),
  DFGIMAP(File, FileId, FileId),
  DFGIMAP(File, FileVersion, FileVersion),
  DFGIMAP(File, FileFGroupId, FilegroupId),
  DFGIMAP(File, FileFGroupVersion, FilegroupVersion),
  DFGIMAP(File, FileSizeHi, FileSizeHi),
  DFGIMAP(File, FileSizeLo, FileSizeLo),
  DFGIMAP(File, FileFreeExtents, FileFreeExtents),
  DFGIBREAK(FileEnd)
};

//static
const Uint32 DictFilegroupInfo::FileMappingSize =
sizeof(DictFilegroupInfo::FileMapping) /
sizeof(SimpleProperties::SP2StructMapping);

void
DictFilegroupInfo::Filegroup::init(){
  memset(FilegroupName, 0, sizeof(FilegroupName));
  FilegroupType = ~0;
  FilegroupId = ~0;
  FilegroupVersion = ~0;

  TS_ExtentSize = 0;
  TS_LogfileGroupId = ~0;
  TS_LogfileGroupVersion = ~0;
  TS_DataGrow.GrowLimit = 0;
  TS_DataGrow.GrowSizeHi = 0;
  TS_DataGrow.GrowSizeLo = 0;
  memset(TS_DataGrow.GrowPattern, 0, sizeof(TS_DataGrow.GrowPattern));
  TS_DataGrow.GrowMaxSize = 0;
  LF_UndoFreeWordsHi= 0;
  LF_UndoFreeWordsLo= 0;
}

void
DictFilegroupInfo::File::init(){
  memset(FileName, 0, sizeof(FileName));
  FileType = ~0;
  FileId = ~0;
  FileVersion = ~0;
  FilegroupId = ~0;
  FilegroupVersion = ~0;
  FileSizeHi = 0;
  FileSizeLo = 0;
  FileFreeExtents = 0;
}

// blob table name hack

bool
DictTabInfo::isBlobTableName(const char* name, Uint32* ptab_id, Uint32* pcol_no)
{
  const char* const prefix = "NDB$BLOB_";
  const char* s = strrchr(name, table_name_separator);
  s = (s == NULL ? name : s + 1);
  if (strncmp(s, prefix, strlen(prefix)) != 0)
    return false;
  s += strlen(prefix);
  uint i, n;
  for (i = 0, n = 0; '0' <= s[i] && s[i] <= '9'; i++)
    n = 10 * n + (s[i] - '0');
  if (i == 0 || s[i] != '_')
    return false;
  const uint tab_id = n;
  s = &s[i + 1];
  for (i = 0, n = 0; '0' <= s[i] && s[i] <= '9'; i++)
    n = 10 * n + (s[i] - '0');
  if (i == 0 || s[i] != 0)
    return false;
  const uint col_no = n;
  if (ptab_id)
    *ptab_id = tab_id;
  if (pcol_no)
    *pcol_no = col_no;
  return true;
}
<|endoftext|>