<commit_before>// An implementation of the synthetic PHOLD simulation model
// See "Performance of Time Warp Under Synthetic Workloads" by R.M. Fujimoto

#include<string>
#include<vector>
#include<memory>

#include "warped.hpp"
#include "tclap/ValueArg.h"

WARPED_DEFINE_OBJECT_STATE_STRUCT(PholdState) { }

class PholdEvent : public warped::Event {
public:
  PholdEvent();
  PholdEvent()(const std::string& receiver_name, const unsigned int timestamp,
               const std::string& creator_name)
    : creator_name(creator_name), receiver_name(receiver_name), timestamp(timestamp) {}

  const std::string& receiverName() const { return this->receiver_name; }
  unsigned int timestamp() const { return this->timestamp; }

protected:
  std::string creator_name;
  std::string receiever_name;
  unsigned int timestamp;

  WARPED_REGISTER_SERIALIZABLE_MEMBERS(creator_name, receiver_name, timestamp)
};

WARPED_REGISTER_POLYMORPHIC_SERIALIZABLE_CLASS(PholdEvent)

class PholdObject : public warped::SimulationObject {
public:
  PholdObject(const std::string& name, const unsigned int hold_mean,
              const unsigned int initial_events, const unsigned int num_objects)
    : name(name), state(), hold_mean(hold_mean), initial_events(initial_events),
      num_objects(num_objects) {}

  warped::ObjectState& getState() { return this->state; }

  std::vector<std::unique_ptr<warped::Event> > createInitialEvents() {
    std::vector<std::unique_ptr<warped::Event> > events;
    for (unsigned int i = 0; i < this->initial_events; i++) {
      events.emplace_back(new PholdEvent { this->get_destination(), this->get_timestamp(),
            this->name });
    }
    return events;
  }

  std::vector<std::unique_ptr<warped::Event> > receiveEvent(const warped::Event& event) {
    std::vector<std::unique_ptr<warped::Event> > response_events;
    auto received_event = static_cast<const PholdEvent&>(event);

    // Handle PHOLD events

    return response_events;
  }

protected:
  PholdState state;
  const unsigned int hold_mean;
  const unsigned int initial_events;
  const unsigned int num_objects;

  const std::string& get_destination() const {
    // TODO: Generate random destination LP
  }

  const unsigned int get_timestamp(const unsigned int exponential_mean) const {
    // TODO: Generate exponentially distributed random timestamp
  }
};

int main(int argc, const char** argv) {
  unsigned int hold_mean;
  unsigned int initial_events;
  unsigned int num_objects;

  return 0;
}
<commit_msg>Completed initial coding of PHOLD model<commit_after>// An implementation of the synthetic PHOLD simulation model
// See "Performance of Time Warp Under Synthetic Workloads" by R.M. Fujimoto

#include <string>
#include <vector>
#include <memory>
#include <iostream>

#include "warped.hpp"
#include "tclap/ValueArg.h"

#include "MLCG.h"
#include "Normal.h"
#include "Poisson.h"
#include "Binomial.h"
#include "Uniform.h"
#include "NegExp.h"
#include "DiscUnif.h"

enum distribution_t {UNIFORM, POISSON, EXPONENTIAL, NORMAL, BINOMIAL, FIXED,
                     ALTERNATE, ROUNDROBIN, CONDITIONAL, ALL};

WARPED_DEFINE_OBJECT_STATE_STRUCT(PholdState) { };

class PholdEvent : public warped::Event {
public:
  PholdEvent() = default;
  PholdEvent(const std::string& receiver_name, const unsigned int timestamp,
             const std::string& creator_name)
    : creator_name(creator_name), receiver_name(receiver_name), time_stamp(timestamp) {}

  const std::string& receiverName() const { return receiver_name; }
  unsigned int timestamp() const { return time_stamp; }

  std::string creator_name;
  std::string receiver_name;
  unsigned int time_stamp;

  WARPED_REGISTER_SERIALIZABLE_MEMBERS(creator_name, receiver_name, time_stamp)
};

WARPED_REGISTER_POLYMORPHIC_SERIALIZABLE_CLASS(PholdEvent)

class PholdObject : public warped::SimulationObject {
public:
  PholdObject(const std::string& name, const unsigned int initial_events,
              const unsigned int num_objects, const distribution_t distribution,
              const double distribution_mean = 1.0)
    : SimulationObject(name), state(), initial_events(initial_events),
      num_objects(num_objects), rng(new MLCG), distribution(distribution),
      distribution_mean(distribution_mean) {}

  warped::ObjectState& getState() { return this->state; }

  std::vector<std::unique_ptr<warped::Event> > createInitialEvents() {
    std::vector<std::unique_ptr<warped::Event> > events;
    for (unsigned int i = 0; i < this->initial_events; i++) {
      events.emplace_back(new PholdEvent { this->get_destination(), this->get_timestamp_delay(),
            this->name });
    }
    return events;
  }

  std::vector<std::unique_ptr<warped::Event> > receiveEvent(const warped::Event& event) {
    std::vector<std::unique_ptr<warped::Event> > response_events;
    auto received_event = static_cast<const PholdEvent&>(event);

    response_events.emplace_back(new PholdEvent { this->get_destination(),
          event.timestamp() + this->get_timestamp_delay(), this->name });

    return response_events;
  }

protected:
  std::string name;
  PholdState state;
  const unsigned int initial_events;
  const unsigned int num_objects;
  std::unique_ptr<MLCG> rng;
  const distribution_t distribution;
  const double distribution_mean;

  std::string get_destination() const {
    DiscreteUniform Dest(0, ((int)(num_objects))-1, this->rng.get());
    unsigned int destination_number = (unsigned int) Dest();
    return std::string("Object ") + std::to_string(destination_number);
  }

  unsigned int get_timestamp_delay() const {

    double delay;

    switch ( this->distribution ) {
    case UNIFORM :
      {
        Uniform uniform(this->distribution_mean, 0.0, this->rng.get());
        delay = uniform();
        break;
      }
    case NORMAL :
      {
        Normal normal(this->distribution_mean, 0.0, this->rng.get());
        delay = normal();
        break;
      }
    case BINOMIAL :
      {
        Binomial binomial((int)this->distribution_mean, 0.0, this->rng.get());
        delay = binomial();
        break;
      }
    case POISSON :
      {
        Poisson poisson(this->distribution_mean, this->rng.get());
        delay = poisson();
        break;
      }
    case EXPONENTIAL :
      {
        NegativeExpntl expo(this->distribution_mean, this->rng.get());
        delay = expo();
        break;
      }
    case FIXED :
      delay = (unsigned int)this->distribution_mean ;
      break;
    default :
      delay = 0;
      std::cerr << "Improper Distribution for a Source Object!!!" << std::endl;
      break;
    }
    return ( (unsigned int) delay );
  }
};

int main(int argc, const char** argv) {
  double distribution_mean = 1.0;
  unsigned int num_initial_events = 10;
  unsigned int num_objects = 10;
  distribution_t distribution = EXPONENTIAL;

  TCLAP::ValueArg<double> distribution_mean_arg("m", "mean", "mean delay for events", false,
                                                distribution_mean, "double");
  TCLAP::ValueArg<unsigned int> num_initial_events_arg("e", "events", "number of initial events per object",
                                                       false, num_initial_events, "unsigned int");
  TCLAP::ValueArg<unsigned int> num_objects_arg("n", "num_objects", "number of simulation objects",
                                                false, num_objects, "unsigned int");

  std::vector<TCLAP::Arg*> args = {&distribution_mean_arg, &num_initial_events_arg, &num_objects_arg};

  warped::Simulation phold_sim {"PHOLD Simulation", argc, argv, args};

  distribution_mean = distribution_mean_arg.getValue();
  num_initial_events = num_initial_events_arg.getValue();
  num_objects = num_objects_arg.getValue();

  std::vector<PholdObject> objects;

  for (unsigned int i = 0; i < num_objects; i++) {
    std::string name = std::string("Object ") + std::to_string(i);
    objects.emplace_back(name, num_initial_events, num_objects, distribution, distribution_mean);
  }

  std::vector<warped::SimulationObject*> object_pointers;
  for (auto& o : objects) {
    object_pointers.push_back(&o);
  }

  phold_sim.simulate(object_pointers);

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    "../Characters/Format.h"
#include    "../Time/Date.h"
#include    "../Time/DateTime.h"

#include    "ObjectVariantMapper.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::DataExchangeFormat;

using   Time::Date;
using   Time::DateTime;

/*
 ********************************************************************************
 ******* DataExchangeFormat::ObjectVariantMapper::TypeMappingDetails ************
 ********************************************************************************
 */
ObjectVariantMapper::TypeMappingDetails::TypeMappingDetails (
    const type_index& forTypeInfo,
    const std::function<VariantValue(ObjectVariantMapper* mapper, const Byte* objOfType)>& toVariantMapper,
    const std::function<void(ObjectVariantMapper* mapper, const VariantValue& d, Byte* into)>& fromVariantMapper
)
    : fForType (forTypeInfo)
    , fToVariantMapper (toVariantMapper)
    , fFromVariantMapper (fromVariantMapper)
{
}

/*
 ********************************************************************************
 ****************** DataExchangeFormat::ObjectVariantMapper *********************
 ********************************************************************************
 */
ObjectVariantMapper::ObjectVariantMapper ()
{
    RegisterCommonSerializers ();
}

void    ObjectVariantMapper::RegisterSerializer (const TypeMappingDetails& serializerInfo)
{
    fSerializers_.Add (serializerInfo);
}

void    ObjectVariantMapper::ClearRegistry ()
{
    fSerializers_.clear ();
}

void    ObjectVariantMapper::ResetToDefaultRegistry ()
{
    ClearRegistry ();
    RegisterCommonSerializers ();
}

namespace {
    template    <typename T, typename UseVariantType>
    ObjectVariantMapper::TypeMappingDetails mkSerializerInfo_ ()
    {
        auto toVariantMapper = [] (ObjectVariantMapper * mapper, const Byte * objOfType) -> VariantValue {
            return VariantValue (static_cast<UseVariantType> (*reinterpret_cast<const T*> (objOfType)));
        };
        auto fromVariantMapper = [] (ObjectVariantMapper * mapper, const VariantValue & d, Byte * into) -> void {
            *reinterpret_cast<T*> (into) = static_cast<T> (d.As<UseVariantType> ());
        };
        return ObjectVariantMapper::TypeMappingDetails (typeid (T), toVariantMapper, fromVariantMapper);
    }
}

void    ObjectVariantMapper::RegisterCommonSerializers ()
{
    RegisterSerializer (mkSerializerInfo_<bool, bool> ());
    RegisterSerializer (mkSerializerInfo_<int, int> ());
    RegisterSerializer (mkSerializerInfo_<float, VariantValue::FloatType> ());
    RegisterSerializer (mkSerializerInfo_<double, VariantValue::FloatType> ());
    RegisterSerializer (mkSerializerInfo_<Date, Date> ());
    RegisterSerializer (mkSerializerInfo_<DateTime, DateTime> ());
    /// TODO - ARRAY??? Maybe using Sequence???
    RegisterSerializer (mkSerializerInfo_<String, String> ());
}

VariantValue    ObjectVariantMapper::Serialize (const type_index& forTypeInfo, const Byte* objOfType)
{
    return Lookup_ (forTypeInfo).fToVariantMapper (this, objOfType);
}

void    ObjectVariantMapper::Deserialize (const type_index& forTypeInfo, const VariantValue& d, Byte* into)
{
    Lookup_ (forTypeInfo).fFromVariantMapper (this, d, into);
}

ObjectVariantMapper::TypeMappingDetails  ObjectVariantMapper::mkSerializerForStruct (const type_index& forTypeInfo, size_t n, const Sequence<StructureFieldInfo>& fields)
{
#if     qDebug
    for (auto i : fields) {
        Require (i.fOffset < n);
    }
#endif

    // foo magic (could do cleaner?) to assure lifetime for whats captured in lambda
    struct foo {
        Sequence<StructureFieldInfo> fields;
    };
    shared_ptr<foo> fooptr (new foo ());
    fooptr->fields = fields;
    auto toVariantMapper = [fooptr] (ObjectVariantMapper * mapper, const Byte * objOfType) -> VariantValue {
        Mapping<String, VariantValue> m;
        for (auto i : fooptr->fields) {
            const Byte* fieldObj = objOfType + i.fOffset;
            m.Add (i.fSerializedFieldName, mapper->Serialize (i.fTypeInfo, objOfType + i.fOffset));
        }
        return VariantValue (m);
    };
    auto fromVariantMapper = [fooptr] (ObjectVariantMapper * mapper, const VariantValue & d, Byte * into) -> void {
        Mapping<String, VariantValue> m  =   d.As<Mapping<String, VariantValue>> ();
        for (auto i : fooptr->fields) {
            Memory::Optional<VariantValue> o = m.Lookup (i.fSerializedFieldName);
            if (not o.empty ()) {
                mapper->Deserialize (i.fTypeInfo, *o, into + i.fOffset);
            }
        }
    };
    return TypeMappingDetails (forTypeInfo, toVariantMapper, fromVariantMapper);
}

ObjectVariantMapper::TypeMappingDetails  ObjectVariantMapper::Lookup_(const type_index& forTypeInfo) const
{
    TypeMappingDetails  foo (forTypeInfo, nullptr, nullptr);
    auto i  = fSerializers_.Lookup (foo);
    if (i.empty ()) {
        throw "OOPS";
    }
    return *i;
}
<commit_msg>Assertions on ObjectVariantMapper<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#include    "../StroikaPreComp.h"

#include    "../Characters/Format.h"
#include    "../Time/Date.h"
#include    "../Time/DateTime.h"

#include    "ObjectVariantMapper.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::DataExchangeFormat;

using   Time::Date;
using   Time::DateTime;

/*
 ********************************************************************************
 ******* DataExchangeFormat::ObjectVariantMapper::TypeMappingDetails ************
 ********************************************************************************
 */
ObjectVariantMapper::TypeMappingDetails::TypeMappingDetails (
    const type_index& forTypeInfo,
    const std::function<VariantValue(ObjectVariantMapper* mapper, const Byte* objOfType)>& toVariantMapper,
    const std::function<void(ObjectVariantMapper* mapper, const VariantValue& d, Byte* into)>& fromVariantMapper
)
    : fForType (forTypeInfo)
    , fToVariantMapper (toVariantMapper)
    , fFromVariantMapper (fromVariantMapper)
{
}

/*
 ********************************************************************************
 ****************** DataExchangeFormat::ObjectVariantMapper *********************
 ********************************************************************************
 */
ObjectVariantMapper::ObjectVariantMapper ()
{
    RegisterCommonSerializers ();
}

void    ObjectVariantMapper::RegisterSerializer (const TypeMappingDetails& serializerInfo)
{
    fSerializers_.Add (serializerInfo);
}

void    ObjectVariantMapper::ClearRegistry ()
{
    fSerializers_.clear ();
}

void    ObjectVariantMapper::ResetToDefaultRegistry ()
{
    ClearRegistry ();
    RegisterCommonSerializers ();
}

namespace {
    template    <typename T, typename UseVariantType>
    ObjectVariantMapper::TypeMappingDetails mkSerializerInfo_ ()
    {
        auto toVariantMapper = [] (ObjectVariantMapper * mapper, const Byte * objOfType) -> VariantValue {
            return VariantValue (static_cast<UseVariantType> (*reinterpret_cast<const T*> (objOfType)));
        };
        auto fromVariantMapper = [] (ObjectVariantMapper * mapper, const VariantValue & d, Byte * into) -> void {
            *reinterpret_cast<T*> (into) = static_cast<T> (d.As<UseVariantType> ());
        };
        return ObjectVariantMapper::TypeMappingDetails (typeid (T), toVariantMapper, fromVariantMapper);
    }
}

void    ObjectVariantMapper::RegisterCommonSerializers ()
{
    RegisterSerializer (mkSerializerInfo_<bool, bool> ());
    RegisterSerializer (mkSerializerInfo_<int, int> ());
    RegisterSerializer (mkSerializerInfo_<float, VariantValue::FloatType> ());
    RegisterSerializer (mkSerializerInfo_<double, VariantValue::FloatType> ());
    RegisterSerializer (mkSerializerInfo_<Date, Date> ());
    RegisterSerializer (mkSerializerInfo_<DateTime, DateTime> ());
    /// TODO - ARRAY??? Maybe using Sequence???
    RegisterSerializer (mkSerializerInfo_<String, String> ());
}

VariantValue    ObjectVariantMapper::Serialize (const type_index& forTypeInfo, const Byte* objOfType)
{
    Require (Lookup_ (forTypeInfo).fToVariantMapper);
    return Lookup_ (forTypeInfo).fToVariantMapper (this, objOfType);
}

void    ObjectVariantMapper::Deserialize (const type_index& forTypeInfo, const VariantValue& d, Byte* into)
{
    Require (Lookup_ (forTypeInfo).fFromVariantMapper);
    Lookup_ (forTypeInfo).fFromVariantMapper (this, d, into);
}

ObjectVariantMapper::TypeMappingDetails  ObjectVariantMapper::mkSerializerForStruct (const type_index& forTypeInfo, size_t n, const Sequence<StructureFieldInfo>& fields)
{
#if     qDebug
    for (auto i : fields) {
        Require (i.fOffset < n);
    }
#endif

    // foo magic (could do cleaner?) to assure lifetime for whats captured in lambda
    struct foo {
        Sequence<StructureFieldInfo> fields;
    };
    shared_ptr<foo> fooptr (new foo ());
    fooptr->fields = fields;
    auto toVariantMapper = [fooptr] (ObjectVariantMapper * mapper, const Byte * objOfType) -> VariantValue {
        Mapping<String, VariantValue> m;
        for (auto i : fooptr->fields) {
            const Byte* fieldObj = objOfType + i.fOffset;
            m.Add (i.fSerializedFieldName, mapper->Serialize (i.fTypeInfo, objOfType + i.fOffset));
        }
        return VariantValue (m);
    };
    auto fromVariantMapper = [fooptr] (ObjectVariantMapper * mapper, const VariantValue & d, Byte * into) -> void {
        Mapping<String, VariantValue> m  =   d.As<Mapping<String, VariantValue>> ();
        for (auto i : fooptr->fields) {
            Memory::Optional<VariantValue> o = m.Lookup (i.fSerializedFieldName);
            if (not o.empty ()) {
                mapper->Deserialize (i.fTypeInfo, *o, into + i.fOffset);
            }
        }
    };
    return TypeMappingDetails (forTypeInfo, toVariantMapper, fromVariantMapper);
}

ObjectVariantMapper::TypeMappingDetails  ObjectVariantMapper::Lookup_ (const type_index& forTypeInfo) const
{
    TypeMappingDetails  foo (forTypeInfo, nullptr, nullptr);
    auto i  = fSerializers_.Lookup (foo);
    Require (i.IsPresent ());   // if not present, this is a usage error - only use types which are registered
    return *i;
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//
// Copyright (C) 2008 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2008 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__

/// \file StereoSessionIsis.cc
///

// Vision Workbench
#include <vw/Image.h>
#include <vw/Math.h>
#include <vw/FileIO.h>
#include <vw/InterestPoint.h>
#include <vw/Stereo/DisparityMap.h>
#include <vw/Cartography.h>
// Stereo Pipeline
#include <asp/Sessions/ISIS/StereoSessionIsis.h>
#include <asp/IsisIO/IsisCameraModel.h>
#include <asp/Core/StereoSettings.h>
#include <asp/IsisIO/IsisAdjustCameraModel.h>
#include <asp/IsisIO/DiskImageResourceIsis.h>

// Boost
#include <boost/filesystem/operations.hpp>
#include <boost/shared_ptr.hpp>
using namespace boost::filesystem;

using namespace vw;
using namespace vw::camera;
using namespace vw::cartography;
using namespace vw::stereo;
using namespace vw::ip;

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
}

// Do not attempt interest point alignment; assume ISIS images are already map projected.
// Simply remove the special pixels and normalize between 0 and 1 (so that the image masks
// are found properly)
void StereoSessionIsis::pre_preprocessing_hook(std::string const& input_file1, std::string const& input_file2,
                                               std::string & output_file1, std::string & output_file2) {
  output_file1 = m_out_prefix + "-L.tif";
  output_file2 = m_out_prefix + "-R.tif";
  if (exists(output_file1) && exists(output_file2)) {
    vw_out(InfoMessage) << "Skipping normalization step, using cached images: " <<
      output_file1 << " and " << output_file2 << "\n";
    return;
  }

  DiskImageView<PixelGray<float> > left_disk_image(input_file1);
  DiskImageView<PixelGray<float> > right_disk_image(input_file2);
  DiskImageResourceIsis left_rsrc(input_file1);
  DiskImageResourceIsis right_rsrc(input_file2);

  float left_lo, left_hi, right_lo, right_hi;

  vw_out(InfoMessage) << "\t--> Computing min/max values for the left image\n";
  min_max_channel_values(create_mask(left_disk_image, left_rsrc.valid_minimum(),
                                     left_rsrc.valid_maximum()), left_lo, left_hi);
  vw_out(InfoMessage) << "\t    Left: [ lo:" << left_lo << " hi:" << left_hi << "]\n";
  vw_out(InfoMessage) << "\t--> Computing min/max values for the right image\n";
  min_max_channel_values(create_mask(right_disk_image, right_rsrc.valid_minimum(),
                                     right_rsrc.valid_maximum()), right_lo, right_hi);
  vw_out(InfoMessage) << "\t    Right: [ lo:" << right_lo << " hi:" << right_hi << "]\n";

  // Normalizing to -+2 sigmas around mean
  if ( stereo_settings().force_max_min == 0 ) {
    float left_mean, left_std, right_mean, right_std;
    vw_out(InfoMessage) << "\t--> Finding left mean and sigma.\n";
    left_mean = mean_channel_value(create_mask(left_disk_image, left_rsrc.valid_minimum(),
                                               left_rsrc.valid_maximum()));
    left_std = stddev_channel_value(create_mask(left_disk_image,left_rsrc.valid_minimum(),
                                                left_rsrc.valid_maximum()));
    vw_out(InfoMessage) << "\t    Left: [ m:" << left_mean << " s:" << left_std << "]\n";
    vw_out(InfoMessage) << "\t--> Finding right mean and sigma.\n";
    right_mean = mean_channel_value(create_mask(right_disk_image, right_rsrc.valid_minimum(),
                                                right_rsrc.valid_maximum()));
    right_std = stddev_channel_value(create_mask(right_disk_image,right_rsrc.valid_minimum(),
                                                   right_rsrc.valid_maximum()));
    vw_out(InfoMessage) << "\t    Right: [ m:" << right_mean << " s:" << right_std << "]\n";

    vw_out(InfoMessage) << "\t--> Adjusting hi and lo to -+2 sigmas around mean.\n";

    if ( left_lo < left_mean - 2*left_std )
      left_lo = left_mean - 2*left_std;
    if ( right_lo < right_mean - 2*right_std )
      right_lo = right_mean - 2*right_std;
    if ( left_hi > left_mean + 2*left_std )
      left_hi = left_mean + 2*left_std;
    if ( right_hi > right_mean + 2*right_std )
      right_hi = right_mean + 2*right_std;

    vw_out(InfoMessage) << "\t    Left changed: [ lo:"<<left_lo<<" hi:"<<left_hi<<"]\n";
    vw_out(InfoMessage) << "\t    Right changed: [ lo:"<<right_lo<<" hi:"<<right_hi<<"]\n";
  }

  ImageViewRef<PixelGray<float> > Limg;
  ImageViewRef<PixelGray<float> > Rimg;

  if (stereo_settings().individually_normalize == 0 ) {
    // Picking Global
    float lo = std::min (left_lo, right_lo);
    float hi = std::max (left_hi, right_hi);

    vw_out(0) << "\t--> Normalizing globally to: ["<<lo<<" "<<hi<<"]\n";
    Limg = clamp(normalize(remove_isis_special_pixels(left_disk_image, left_lo, left_hi, lo),
                           lo,hi,0.0,1.0),0.0,1.0);
    Rimg = clamp(normalize(remove_isis_special_pixels(right_disk_image,right_lo,right_hi,lo),
                           lo,hi,0.0,1.0),0.0,1.0);
  } else {
    vw_out(0) << "\t--> Individually normalizing.\n";
    Limg = clamp(normalize(remove_isis_special_pixels(left_disk_image, left_lo, left_hi, left_lo),
                           left_lo,left_hi,0.0,1.0),0.0,1.0);
    Rimg = clamp(normalize(remove_isis_special_pixels(right_disk_image,right_lo,right_hi,right_lo),
                           right_lo,right_hi,0.0,1.0),0.0,1.0);
  }

  // Write the results to disk.
  vw_out(0) << "\t--> Writing normalized images.\n";
  DiskImageResourceGDAL left_out_rsrc( output_file1, Limg.format(), Vector2i(vw_settings().default_tile_size(),vw_settings().default_tile_size()) );
  block_write_image( left_out_rsrc, Limg, TerminalProgressCallback(InfoMessage, "\t    Left:  "));

  DiskImageResourceGDAL right_out_rsrc( output_file2, Rimg.format(), Vector2i(vw_settings().default_tile_size(),vw_settings().default_tile_size()) );
  block_write_image( right_out_rsrc, Rimg, TerminalProgressCallback(InfoMessage, "\t    Right: "));
}

// Stage 2: Correlation
//
// Pre file is a pair of grayscale images.  ( ImageView<PixelGray<float> > )
// Post file is a disparity map.            ( ImageView<PixelMask<Vector2f> > )
void StereoSessionIsis::pre_filtering_hook(std::string const& input_file, std::string & output_file) {
  output_file = input_file;

  // ****************************************************
  // The following code is for Apollo Metric Camera ONLY!
  // (use at your own risk)
  // ****************************************************
  if (stereo_settings().mask_flatfield) {
    vw_out(0) << "\t--> Masking pixels that are less than 0.0.  (NOTE: Use this option with Apollo Metric Camera frames only!)\n";
    output_file = m_out_prefix + "-R-masked.exr";
    DiskImageView<PixelGray<float> > left_disk_image(m_left_image_file);
    DiskImageView<PixelGray<float> > right_disk_image(m_right_image_file);
    DiskImageView<uint8> left_disk_mask( m_out_prefix + "-lMask.tif");
    DiskImageView<uint8> right_disk_mask( m_out_prefix + "-rMask.tif");

    ImageViewRef<PixelMask<uint8> > Lmask = intersect_mask(create_mask(left_disk_mask),
                                                           create_mask(clamp(left_disk_image,0,1e6)));
    ImageViewRef<PixelMask<uint8> > Rmask = intersect_mask(create_mask(right_disk_mask),
                                                           create_mask(clamp(right_disk_image,0,1e6)));

    write_image(m_out_prefix + "-lMaskDebug.tif", Lmask);
    write_image(m_out_prefix + "-rMaskDebug.tif", Rmask);

    DiskImageView<PixelMask<Vector2f> > disparity_disk_image(input_file);
    ImageViewRef<PixelMask<Vector2f> > disparity_map = disparity_mask(disparity_disk_image, Lmask, Rmask);

    DiskImageResourceOpenEXR disparity_map_rsrc(output_file, disparity_map.format() );
    disparity_map_rsrc.set_tiled_write(std::min(512,disparity_map.cols()),
                                       std::min(512,disparity_map.rows()));
    block_write_image( disparity_map_rsrc, disparity_map, TerminalProgressCallback(InfoMessage, "\t--> Saving Mask :") );
  }
}

// Reverse any pre-alignment that was done to the images.
void StereoSessionIsis::pre_pointcloud_hook(std::string const& input_file, std::string & output_file) {

  DiskImageView<PixelMask<Vector2f> > disparity_map(input_file);
  output_file = m_out_prefix + "-F-corrected.exr";
  ImageViewRef<PixelMask<Vector2f> > result;

  // We used a homography to line up the images, we may want
  // to generate pre-alignment disparities before passing this information
  // onto the camera model in the next stage of the stereo pipeline.
  Matrix<double> align_matrix;
  try {
    read_matrix(align_matrix, m_out_prefix + "-align.exr");
    vw_out(DebugMessage) << "Alignment Matrix: " << align_matrix << "\n";
  } catch (vw::IOErr &e) {
    vw_out(0) << "\nCould not read in aligment matrix: " << m_out_prefix << "-align.exr.  Exiting. \n\n";
    exit(1);
  }

  result = stereo::transform_disparities(disparity_map, HomographyTransform(align_matrix));

  // Remove pixels that are outside the bounds of the secondary image.
  DiskImageView<PixelGray<float> > right_disk_image(m_right_image_file);
  result = stereo::disparity_range_mask(result,
                                        Vector2f(0,0),
                                        Vector2f( right_disk_image.cols(),
                                                  right_disk_image.rows() ) );

  DiskImageResourceOpenEXR disparity_corrected_rsrc(output_file, result.format() );
  disparity_corrected_rsrc.set_tiled_write(std::min(512,disparity_map.cols()),
                                     std::min(512,disparity_map.rows()));
  block_write_image( disparity_corrected_rsrc, result,
                     TerminalProgressCallback(InfoMessage, "\t    Processing:"));
}

boost::shared_ptr<vw::camera::CameraModel> StereoSessionIsis::camera_model(std::string image_file,
                                                                           std::string camera_file) {

  if (boost::ends_with(boost::to_lower_copy(camera_file), ".isis_adjust")){
    vw_out(0) << "\t--> Using adjusted Isis Camera Model: " << camera_file << "\n";

    // Creating Equations for the files
    std::ifstream input( camera_file.c_str() );
    boost::shared_ptr<BaseEquation> posF = read_equation( input );
    boost::shared_ptr<BaseEquation> poseF = read_equation( input );
    input.close();

    // Finally creating camera model
    return boost::shared_ptr<camera::CameraModel>(new IsisAdjustCameraModel( image_file, posF, poseF ));

  } else {
    vw_out(0) << "\t--> Using standard Isis camera model: " << image_file << "\n";
    return boost::shared_ptr<camera::CameraModel>(new IsisCameraModel(image_file));
  }

}

<commit_msg>Oops, images need to be cropped to the same size in order for CorrelatorView to work.  Also, removed the search for the aligning transform since we're no longer using interest point alignment.<commit_after>// __BEGIN_LICENSE__
//
// Copyright (C) 2008 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
//
// Copyright 2008 Carnegie Mellon University. All rights reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
// __END_LICENSE__

/// \file StereoSessionIsis.cc
///

// Vision Workbench
#include <vw/Image.h>
#include <vw/Math.h>
#include <vw/FileIO.h>
#include <vw/InterestPoint.h>
#include <vw/Stereo/DisparityMap.h>
#include <vw/Cartography.h>
// Stereo Pipeline
#include <asp/Sessions/ISIS/StereoSessionIsis.h>
#include <asp/IsisIO/IsisCameraModel.h>
#include <asp/Core/StereoSettings.h>
#include <asp/IsisIO/IsisAdjustCameraModel.h>
#include <asp/IsisIO/DiskImageResourceIsis.h>

// Boost
#include <boost/filesystem/operations.hpp>
#include <boost/shared_ptr.hpp>
using namespace boost::filesystem;

using namespace vw;
using namespace vw::camera;
using namespace vw::cartography;
using namespace vw::stereo;
using namespace vw::ip;

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
}

// Do not attempt interest point alignment; assume ISIS images are already map projected.
// Simply remove the special pixels and normalize between 0 and 1 (so that the image masks
// are found properly)
void StereoSessionIsis::pre_preprocessing_hook(std::string const& input_file1, std::string const& input_file2,
                                               std::string & output_file1, std::string & output_file2) {
  output_file1 = m_out_prefix + "-L.tif";
  output_file2 = m_out_prefix + "-R.tif";
  if (exists(output_file1) && exists(output_file2)) {
    vw_out(InfoMessage) << "Skipping normalization step, using cached images: " <<
      output_file1 << " and " << output_file2 << "\n";
    return;
  }

  DiskImageView<PixelGray<float> > left_disk_image(input_file1);
  DiskImageView<PixelGray<float> > right_disk_image(input_file2);
  DiskImageResourceIsis left_rsrc(input_file1);
  DiskImageResourceIsis right_rsrc(input_file2);

  float left_lo, left_hi, right_lo, right_hi;

  vw_out(InfoMessage) << "\t--> Computing min/max values for the left image\n";
  min_max_channel_values(create_mask(left_disk_image, left_rsrc.valid_minimum(),
                                     left_rsrc.valid_maximum()), left_lo, left_hi);
  vw_out(InfoMessage) << "\t    Left: [ lo:" << left_lo << " hi:" << left_hi << "]\n";
  vw_out(InfoMessage) << "\t--> Computing min/max values for the right image\n";
  min_max_channel_values(create_mask(right_disk_image, right_rsrc.valid_minimum(),
                                     right_rsrc.valid_maximum()), right_lo, right_hi);
  vw_out(InfoMessage) << "\t    Right: [ lo:" << right_lo << " hi:" << right_hi << "]\n";

  // Normalizing to -+2 sigmas around mean
  if ( stereo_settings().force_max_min == 0 ) {
    float left_mean, left_std, right_mean, right_std;
    vw_out(InfoMessage) << "\t--> Finding left mean and sigma.\n";
    left_mean = mean_channel_value(create_mask(left_disk_image, left_rsrc.valid_minimum(),
                                               left_rsrc.valid_maximum()));
    left_std = stddev_channel_value(create_mask(left_disk_image,left_rsrc.valid_minimum(),
                                                left_rsrc.valid_maximum()));
    vw_out(InfoMessage) << "\t    Left: [ m:" << left_mean << " s:" << left_std << "]\n";
    vw_out(InfoMessage) << "\t--> Finding right mean and sigma.\n";
    right_mean = mean_channel_value(create_mask(right_disk_image, right_rsrc.valid_minimum(),
                                                right_rsrc.valid_maximum()));
    right_std = stddev_channel_value(create_mask(right_disk_image,right_rsrc.valid_minimum(),
                                                   right_rsrc.valid_maximum()));
    vw_out(InfoMessage) << "\t    Right: [ m:" << right_mean << " s:" << right_std << "]\n";

    vw_out(InfoMessage) << "\t--> Adjusting hi and lo to -+2 sigmas around mean.\n";

    if ( left_lo < left_mean - 2*left_std )
      left_lo = left_mean - 2*left_std;
    if ( right_lo < right_mean - 2*right_std )
      right_lo = right_mean - 2*right_std;
    if ( left_hi > left_mean + 2*left_std )
      left_hi = left_mean + 2*left_std;
    if ( right_hi > right_mean + 2*right_std )
      right_hi = right_mean + 2*right_std;

    vw_out(InfoMessage) << "\t    Left changed: [ lo:"<<left_lo<<" hi:"<<left_hi<<"]\n";
    vw_out(InfoMessage) << "\t    Right changed: [ lo:"<<right_lo<<" hi:"<<right_hi<<"]\n";
  }

  ImageViewRef<PixelGray<float> > Limg;
  ImageViewRef<PixelGray<float> > Rimg;

  if (stereo_settings().individually_normalize == 0 ) {
    // Picking Global
    float lo = std::min (left_lo, right_lo);
    float hi = std::max (left_hi, right_hi);

    vw_out(0) << "\t--> Normalizing globally to: ["<<lo<<" "<<hi<<"]\n";
    Limg = normalize(remove_isis_special_pixels(left_disk_image, left_lo, left_hi, lo), lo, hi, 0.0, 1.0);
    Rimg = normalize(remove_isis_special_pixels(right_disk_image, right_lo, right_hi, lo), lo, hi, 0.0, 1.0);
  } else {
    vw_out(0) << "\t--> Individually normalizing.\n";
    Limg = normalize(remove_isis_special_pixels(left_disk_image, left_lo, left_hi, left_lo), left_lo, left_hi, 0.0, 1.0);
    Rimg = normalize(remove_isis_special_pixels(right_disk_image, right_lo, right_hi, right_lo), right_lo, right_hi, 0.0, 1.0);
  }

  int width = std::min(left_disk_image.cols(), right_disk_image.cols());
  int height = std::min(left_disk_image.rows(), right_disk_image.rows());

  Limg = crop(Limg, 0, 0, width, height);
  Rimg = crop(Rimg, 0, 0, width, height);

  // Write the results to disk.
  vw_out(0) << "\t--> Writing normalized images.\n";
  DiskImageResourceGDAL left_out_rsrc( output_file1, Limg.format(), Vector2i(vw_settings().default_tile_size(),vw_settings().default_tile_size()) );
  block_write_image( left_out_rsrc, Limg, TerminalProgressCallback(InfoMessage, "\t    Left:  "));

  DiskImageResourceGDAL right_out_rsrc( output_file2, Rimg.format(), Vector2i(vw_settings().default_tile_size(),vw_settings().default_tile_size()) );
  block_write_image( right_out_rsrc, Rimg, TerminalProgressCallback(InfoMessage, "\t    Right: "));
}

// Stage 2: Correlation
//
// Pre file is a pair of grayscale images.  ( ImageView<PixelGray<float> > )
// Post file is a disparity map.            ( ImageView<PixelMask<Vector2f> > )
void StereoSessionIsis::pre_filtering_hook(std::string const& input_file, std::string & output_file) {
  output_file = input_file;

  // ****************************************************
  // The following code is for Apollo Metric Camera ONLY!
  // (use at your own risk)
  // ****************************************************
  if (stereo_settings().mask_flatfield) {
    vw_out(0) << "\t--> Masking pixels that are less than 0.0.  (NOTE: Use this option with Apollo Metric Camera frames only!)\n";
    output_file = m_out_prefix + "-R-masked.exr";
    DiskImageView<PixelGray<float> > left_disk_image(m_left_image_file);
    DiskImageView<PixelGray<float> > right_disk_image(m_right_image_file);
    DiskImageView<uint8> left_disk_mask( m_out_prefix + "-lMask.tif");
    DiskImageView<uint8> right_disk_mask( m_out_prefix + "-rMask.tif");

    ImageViewRef<PixelMask<uint8> > Lmask = intersect_mask(create_mask(left_disk_mask),
                                                           create_mask(clamp(left_disk_image,0,1e6)));
    ImageViewRef<PixelMask<uint8> > Rmask = intersect_mask(create_mask(right_disk_mask),
                                                           create_mask(clamp(right_disk_image,0,1e6)));

    write_image(m_out_prefix + "-lMaskDebug.tif", Lmask);
    write_image(m_out_prefix + "-rMaskDebug.tif", Rmask);

    DiskImageView<PixelMask<Vector2f> > disparity_disk_image(input_file);
    ImageViewRef<PixelMask<Vector2f> > disparity_map = disparity_mask(disparity_disk_image, Lmask, Rmask);

    DiskImageResourceOpenEXR disparity_map_rsrc(output_file, disparity_map.format() );
    disparity_map_rsrc.set_tiled_write(std::min(vw_settings().default_tile_size(),disparity_map.cols()),
                                       std::min(vw_settings().default_tile_size(),disparity_map.rows()));
    block_write_image( disparity_map_rsrc, disparity_map, TerminalProgressCallback(InfoMessage, "\t--> Saving Mask :") );
  }
}

// Reverse any pre-alignment that was done to the images.
void StereoSessionIsis::pre_pointcloud_hook(std::string const& input_file, std::string & output_file) {

  DiskImageView<PixelMask<Vector2f> > disparity_map(input_file);
  ImageViewRef<PixelMask<Vector2f> > result = disparity_map;

  output_file = m_out_prefix + "-F-corrected.exr";

  // Remove pixels that are outside the bounds of the secondary image.
  DiskImageView<PixelGray<float> > right_disk_image(m_right_image_file);
  result = stereo::disparity_range_mask(result,
                                        Vector2f(0,0),
                                        Vector2f( right_disk_image.cols(),
                                                  right_disk_image.rows() ) );

  DiskImageResourceOpenEXR disparity_corrected_rsrc(output_file, result.format() );
  disparity_corrected_rsrc.set_tiled_write(std::min(vw_settings().default_tile_size(),disparity_map.cols()),
                                           std::min(vw_settings().default_tile_size(),disparity_map.rows()));
  block_write_image( disparity_corrected_rsrc, result,
                     TerminalProgressCallback(InfoMessage, "\t    Processing:"));
}

boost::shared_ptr<vw::camera::CameraModel> StereoSessionIsis::camera_model(std::string image_file,
                                                                           std::string camera_file) {

  if (boost::ends_with(boost::to_lower_copy(camera_file), ".isis_adjust")){
    vw_out(0) << "\t--> Using adjusted Isis Camera Model: " << camera_file << "\n";

    // Creating Equations for the files
    std::ifstream input( camera_file.c_str() );
    boost::shared_ptr<BaseEquation> posF = read_equation( input );
    boost::shared_ptr<BaseEquation> poseF = read_equation( input );
    input.close();

    // Finally creating camera model
    return boost::shared_ptr<camera::CameraModel>(new IsisAdjustCameraModel( image_file, posF, poseF ));

  } else {
    vw_out(0) << "\t--> Using standard Isis camera model: " << image_file << "\n";
    return boost::shared_ptr<camera::CameraModel>(new IsisCameraModel(image_file));
  }

}

<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// workload.cpp
//
// Identification: benchmark/hyadapt/workload.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <chrono>
#include <iostream>
#include <ctime>
#include <cassert>

#include "backend/benchmark/hyadapt/workload.h"
#include "backend/catalog/manager.h"
#include "backend/catalog/schema.h"
#include "backend/common/types.h"
#include "backend/common/value.h"
#include "backend/common/value_factory.h"
#include "backend/concurrency/transaction.h"
#include "backend/executor/abstract_executor.h"
#include "backend/executor/seq_scan_executor.h"
#include "backend/executor/logical_tile.h"
#include "backend/executor/logical_tile_factory.h"
#include "backend/executor/materialization_executor.h"
#include "backend/expression/abstract_expression.h"
#include "backend/expression/expression_util.h"
#include "backend/index/index_factory.h"
#include "backend/planner/abstract_plan.h"
#include "backend/planner/materialization_plan.h"
#include "backend/planner/seq_scan_plan.h"
#include "backend/storage/backend_vm.h"
#include "backend/storage/tile.h"
#include "backend/storage/tile_group.h"
#include "backend/storage/data_table.h"
#include "backend/storage/table_factory.h"

namespace peloton {
namespace benchmark {
namespace hyadapt{

std::vector<oid_t> hyadapt_column_ids = {
    198, 206, 169, 119, 9, 220, 2, 230, 212, 164, 111, 136, 106, 8, 112, 4, 234, 147, 35, 114, 89, 127, 144, 71, 186,
    34, 145, 124, 146, 7, 40, 227, 59, 190, 249, 157, 38, 64, 134, 167, 63, 178, 156, 94, 84, 187, 153, 158, 42, 236,
    83, 182, 107, 76, 58, 102, 96, 31, 244, 54, 37, 228, 24, 120, 92, 233, 170, 209, 93, 12, 47, 200, 248, 171, 22,
    166, 213, 101, 97, 29, 237, 149, 49, 142, 181, 196, 75, 188, 208, 218, 183, 250, 151, 189, 60, 226, 214, 174, 128, 239,
    27, 235, 217, 98, 143, 165, 160, 109, 65, 23, 74, 207, 115, 69, 108, 30, 201, 221, 202, 20, 225, 105, 91, 95, 150,
    123, 16, 238, 81, 3, 219, 204, 68, 203, 73, 41, 66, 192, 113, 216, 117, 99, 126, 53, 1, 139, 116, 229, 100, 215,
    48, 10, 86, 211, 17, 224, 122, 51, 103, 85, 110, 50, 162, 129, 243, 67, 133, 138, 193, 141, 232, 118, 159, 199, 39,
    154, 137, 163, 179, 77, 194, 130, 46, 32, 125, 241, 246, 140, 26, 78, 177, 148, 223, 185, 197, 61, 195, 18, 80, 231,
    222, 70, 191, 52, 72, 155, 88, 175, 43, 172, 173, 13, 152, 180, 62, 121, 25, 55, 247, 36, 15, 210, 56, 6, 104,
    14, 132, 135, 168, 176, 28, 245, 11, 184, 131, 161, 5, 21, 242, 87, 44, 45, 205, 57, 19, 33, 90, 240, 79, 82
};

expression::AbstractExpression *CreatePredicate( const int lower_bound) {

  // ATTR0 > LOWER_BOUND

  // First, create tuple value expression.
  expression::AbstractExpression *tuple_value_expr =
      expression::TupleValueFactory(0, 0);

  // Second, create constant value expression.
  Value constant_value = ValueFactory::GetIntegerValue(lower_bound);
  expression::AbstractExpression *constant_value_expr =
      expression::ConstantValueFactory(constant_value);

  // Finally, link them together using an greater than expression.
  expression::AbstractExpression *predicate =
      expression::ComparisonFactory(EXPRESSION_TYPE_COMPARE_GREATERTHAN,
                                    tuple_value_expr,
                                    constant_value_expr);

  constant_value.Free();

  return predicate;
}

void RunDirectTest() {
  std::chrono::time_point<std::chrono::system_clock> start, end;

  std::cout << "LAYOUT :: " << peloton_layout << "\n";

  const int tuples_per_tilegroup_count = DEFAULT_TUPLES_PER_TILEGROUP;
  const int tile_group_count = state.scale_factor;

  const int tuple_count = tuples_per_tilegroup_count * tile_group_count;
  const int lower_bound = (1 - state.selectivity) * tuple_count;

  const oid_t col_count = state.column_count;
  const bool is_inlined = true;
  const bool indexes = false;

  std::vector<catalog::Column> columns;

  for(oid_t col_itr = 0 ; col_itr <= col_count; col_itr++) {
    auto column =
        catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER),
                        "" + std::to_string(col_itr), is_inlined);

    columns.push_back(column);
  }

  catalog::Schema *table_schema = new catalog::Schema(columns);
  std::string table_name("TEST_TABLE");

  /////////////////////////////////////////////////////////
  // Create table.
  /////////////////////////////////////////////////////////

  bool own_schema = true;
  bool adapt_table = true;
  std::unique_ptr<storage::DataTable> table(storage::TableFactory::GetDataTable(
      INVALID_OID, INVALID_OID, table_schema, table_name,
      tuples_per_tilegroup_count,
      own_schema, adapt_table));

  // PRIMARY INDEX
  if (indexes == true) {
    std::vector<oid_t> key_attrs;

    auto tuple_schema = table->GetSchema();
    catalog::Schema *key_schema;
    index::IndexMetadata *index_metadata;
    bool unique;

    key_attrs = {0};
    key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs);
    key_schema->SetIndexedColumns(key_attrs);

    unique = true;

    index_metadata = new index::IndexMetadata(
        "primary_index", 123, INDEX_TYPE_BTREE,
        INDEX_CONSTRAINT_TYPE_PRIMARY_KEY, tuple_schema, key_schema, unique);

    index::Index *pkey_index = index::IndexFactory::GetInstance(index_metadata);
    table->AddIndex(pkey_index);
  }

  /////////////////////////////////////////////////////////
  // Load in the data
  /////////////////////////////////////////////////////////

  // Insert tuples into tile_group.
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  const bool allocate = true;
  auto txn = txn_manager.BeginTransaction();

  for (int rowid = 0; rowid < tuple_count; rowid++) {
    int populate_value = rowid;

    storage::Tuple tuple(table_schema, allocate);

    for(oid_t col_itr = 0 ; col_itr <= col_count; col_itr++) {
      auto value = ValueFactory::GetIntegerValue(populate_value + col_itr);
      tuple.SetValue(col_itr, value);
    }

    ItemPointer tuple_slot_id = table->InsertTuple(txn, &tuple);
    assert(tuple_slot_id.block != INVALID_OID);
    assert(tuple_slot_id.offset != INVALID_OID);
    txn->RecordInsert(tuple_slot_id);
  }

  txn_manager.CommitTransaction(txn);

  /////////////////////////////////////////////////////////
  // Do a seq scan with predicate on top of the table
  /////////////////////////////////////////////////////////

  start = std::chrono::system_clock::now();

  txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  // Column ids to be added to logical tile after scan.
  std::vector<oid_t> column_ids;
  oid_t column_count = state.projectivity * state.column_count;

  for(oid_t col_itr = 0 ; col_itr <= column_count; col_itr++) {
    column_ids.push_back(col_itr);
  }

  // Create and set up seq scan executor
  auto predicate = CreatePredicate(lower_bound);
  planner::SeqScanPlan seq_scan_node(table.get(), predicate, column_ids);
  int expected_num_tiles = tile_group_count;

  executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, context.get());

  // Create and set up materialization executor
  std::vector<catalog::Column> output_columns;
  std::unordered_map<oid_t, oid_t> old_to_new_cols;
  oid_t col_itr = 0;
  for(auto column_id : column_ids) {
    auto column =
        catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER),
                        "" + std::to_string(column_id), is_inlined);
    output_columns.push_back(column);

    old_to_new_cols[col_itr] = col_itr;
    col_itr++;
  }

  std::unique_ptr<catalog::Schema> output_schema(
      new catalog::Schema(output_columns));
  bool physify_flag = true;  // is going to create a physical tile
  planner::MaterializationPlan mat_node(old_to_new_cols, output_schema.release(),
                                        physify_flag);

  executor::MaterializationExecutor mat_executor(&mat_node, nullptr);
  mat_executor.AddChild(&seq_scan_executor);
  bool status = false;

  status = mat_executor.Init();
  assert(status == true);

  std::vector<std::unique_ptr<executor::LogicalTile>> result_tiles;

  while(mat_executor.Execute() == true) {
    std::unique_ptr<executor::LogicalTile> result_tile(mat_executor.GetOutput());
    assert(result_tile != nullptr);
    result_tiles.emplace_back(result_tile.release());
  }

  status = mat_executor.Execute();
  assert(status == false);

  txn_manager.CommitTransaction(txn);

  end = std::chrono::system_clock::now();
  std::chrono::duration<double> elapsed_seconds = end-start;

  std::cout << "logical tile count :: " << result_tiles.size() << "\n";
  std::cout << "duration :: " << elapsed_seconds.count() << "s\n";
}

void RunAggregateTest() {

}

void RunArithmeticTest() {

}

}  // namespace hyadapt
}  // namespace benchmark
}  // namespace peloton
<commit_msg>Refactoring<commit_after>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// workload.cpp
//
// Identification: benchmark/hyadapt/workload.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <chrono>
#include <iostream>
#include <ctime>
#include <cassert>

#include "backend/benchmark/hyadapt/workload.h"
#include "backend/catalog/manager.h"
#include "backend/catalog/schema.h"
#include "backend/common/types.h"
#include "backend/common/value.h"
#include "backend/common/value_factory.h"
#include "backend/concurrency/transaction.h"
#include "backend/executor/abstract_executor.h"
#include "backend/executor/seq_scan_executor.h"
#include "backend/executor/logical_tile.h"
#include "backend/executor/logical_tile_factory.h"
#include "backend/executor/materialization_executor.h"
#include "backend/expression/abstract_expression.h"
#include "backend/expression/expression_util.h"
#include "backend/index/index_factory.h"
#include "backend/planner/abstract_plan.h"
#include "backend/planner/materialization_plan.h"
#include "backend/planner/seq_scan_plan.h"
#include "backend/storage/backend_vm.h"
#include "backend/storage/tile.h"
#include "backend/storage/tile_group.h"
#include "backend/storage/data_table.h"
#include "backend/storage/table_factory.h"

namespace peloton {
namespace benchmark {
namespace hyadapt{

std::vector<oid_t> hyadapt_column_ids = {
    198, 206, 169, 119, 9, 220, 2, 230, 212, 164, 111, 136, 106, 8, 112, 4, 234, 147, 35, 114, 89, 127, 144, 71, 186,
    34, 145, 124, 146, 7, 40, 227, 59, 190, 249, 157, 38, 64, 134, 167, 63, 178, 156, 94, 84, 187, 153, 158, 42, 236,
    83, 182, 107, 76, 58, 102, 96, 31, 244, 54, 37, 228, 24, 120, 92, 233, 170, 209, 93, 12, 47, 200, 248, 171, 22,
    166, 213, 101, 97, 29, 237, 149, 49, 142, 181, 196, 75, 188, 208, 218, 183, 250, 151, 189, 60, 226, 214, 174, 128, 239,
    27, 235, 217, 98, 143, 165, 160, 109, 65, 23, 74, 207, 115, 69, 108, 30, 201, 221, 202, 20, 225, 105, 91, 95, 150,
    123, 16, 238, 81, 3, 219, 204, 68, 203, 73, 41, 66, 192, 113, 216, 117, 99, 126, 53, 1, 139, 116, 229, 100, 215,
    48, 10, 86, 211, 17, 224, 122, 51, 103, 85, 110, 50, 162, 129, 243, 67, 133, 138, 193, 141, 232, 118, 159, 199, 39,
    154, 137, 163, 179, 77, 194, 130, 46, 32, 125, 241, 246, 140, 26, 78, 177, 148, 223, 185, 197, 61, 195, 18, 80, 231,
    222, 70, 191, 52, 72, 155, 88, 175, 43, 172, 173, 13, 152, 180, 62, 121, 25, 55, 247, 36, 15, 210, 56, 6, 104,
    14, 132, 135, 168, 176, 28, 245, 11, 184, 131, 161, 5, 21, 242, 87, 44, 45, 205, 57, 19, 33, 90, 240, 79, 82
};

expression::AbstractExpression *CreatePredicate( const int lower_bound) {

  // ATTR0 > LOWER_BOUND

  // First, create tuple value expression.
  expression::AbstractExpression *tuple_value_expr =
      expression::TupleValueFactory(0, 0);

  // Second, create constant value expression.
  Value constant_value = ValueFactory::GetIntegerValue(lower_bound);
  expression::AbstractExpression *constant_value_expr =
      expression::ConstantValueFactory(constant_value);

  // Finally, link them together using an greater than expression.
  expression::AbstractExpression *predicate =
      expression::ComparisonFactory(EXPRESSION_TYPE_COMPARE_GREATERTHAN,
                                    tuple_value_expr,
                                    constant_value_expr);

  constant_value.Free();

  return predicate;
}

static storage::DataTable* CreateTable() {

  const int tuples_per_tilegroup_count = DEFAULT_TUPLES_PER_TILEGROUP;
  const oid_t col_count = state.column_count;
  const bool is_inlined = true;
  const bool indexes = false;

  // Create schema first
  std::vector<catalog::Column> columns;

  for(oid_t col_itr = 0 ; col_itr <= col_count; col_itr++) {
    auto column =
        catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER),
                        "" + std::to_string(col_itr), is_inlined);

    columns.push_back(column);
  }

  catalog::Schema *table_schema = new catalog::Schema(columns);
  std::string table_name("TEST_TABLE");

  /////////////////////////////////////////////////////////
  // Create table.
  /////////////////////////////////////////////////////////

  bool own_schema = true;
  bool adapt_table = true;
  std::unique_ptr<storage::DataTable> table(storage::TableFactory::GetDataTable(
      INVALID_OID, INVALID_OID, table_schema, table_name,
      tuples_per_tilegroup_count,
      own_schema, adapt_table));

  // PRIMARY INDEX
  if (indexes == true) {
    std::vector<oid_t> key_attrs;

    auto tuple_schema = table->GetSchema();
    catalog::Schema *key_schema;
    index::IndexMetadata *index_metadata;
    bool unique;

    key_attrs = {0};
    key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs);
    key_schema->SetIndexedColumns(key_attrs);

    unique = true;

    index_metadata = new index::IndexMetadata(
        "primary_index", 123, INDEX_TYPE_BTREE,
        INDEX_CONSTRAINT_TYPE_PRIMARY_KEY, tuple_schema, key_schema, unique);

    index::Index *pkey_index = index::IndexFactory::GetInstance(index_metadata);
    table->AddIndex(pkey_index);
  }

  return table.release();
}

static void LoadTable(storage::DataTable *table) {

  const int tuples_per_tilegroup_count = DEFAULT_TUPLES_PER_TILEGROUP;
  const int tile_group_count = state.scale_factor;
  const oid_t col_count = state.column_count;

  const int tuple_count = tuples_per_tilegroup_count * tile_group_count;

  auto table_schema = table->GetSchema();

  /////////////////////////////////////////////////////////
  // Load in the data
  /////////////////////////////////////////////////////////

  // Insert tuples into tile_group.
  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  const bool allocate = true;
  auto txn = txn_manager.BeginTransaction();

  for (int rowid = 0; rowid < tuple_count; rowid++) {
    int populate_value = rowid;

    storage::Tuple tuple(table_schema, allocate);

    for(oid_t col_itr = 0 ; col_itr <= col_count; col_itr++) {
      auto value = ValueFactory::GetIntegerValue(populate_value + col_itr);
      tuple.SetValue(col_itr, value);
    }

    ItemPointer tuple_slot_id = table->InsertTuple(txn, &tuple);
    assert(tuple_slot_id.block != INVALID_OID);
    assert(tuple_slot_id.offset != INVALID_OID);
    txn->RecordInsert(tuple_slot_id);
  }

  txn_manager.CommitTransaction(txn);

}

static storage::DataTable *CreateAndLoadTable() {

  auto table = CreateTable();

  LoadTable(table);

  return table;
}

static int GetLowerBound() {
  const int tuples_per_tilegroup_count = DEFAULT_TUPLES_PER_TILEGROUP;
  const int tile_group_count = state.scale_factor;

  const int tuple_count = tuples_per_tilegroup_count * tile_group_count;
  const int lower_bound = (1 - state.selectivity) * tuple_count;

  return lower_bound;
}

void RunDirectTest() {
  std::chrono::time_point<std::chrono::system_clock> start, end;

  std::cout << "LAYOUT :: " << peloton_layout << "\n";

  std::unique_ptr<storage::DataTable> table(CreateAndLoadTable());

  const int lower_bound = GetLowerBound();
  const bool is_inlined = true;
  const int tile_group_count = state.scale_factor;
  auto &txn_manager = concurrency::TransactionManager::GetInstance();

  start = std::chrono::system_clock::now();

  /////////////////////////////////////////////////////////
  // SEQ SCAN + PREDICATE
  /////////////////////////////////////////////////////////

  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  // Column ids to be added to logical tile after scan.
  std::vector<oid_t> column_ids;
  oid_t column_count = state.projectivity * state.column_count;

  for(oid_t col_itr = 0 ; col_itr <= column_count; col_itr++) {
    column_ids.push_back(col_itr);
  }

  // Create and set up seq scan executor
  auto predicate = CreatePredicate(lower_bound);
  planner::SeqScanPlan seq_scan_node(table.get(), predicate, column_ids);
  int expected_num_tiles = tile_group_count;

  executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, context.get());

  /////////////////////////////////////////////////////////
  // MATERIALIZE
  /////////////////////////////////////////////////////////

  // Create and set up materialization executor
  std::vector<catalog::Column> output_columns;
  std::unordered_map<oid_t, oid_t> old_to_new_cols;
  oid_t col_itr = 0;
  for(auto column_id : column_ids) {
    auto column =
        catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER),
                        "" + std::to_string(column_id), is_inlined);
    output_columns.push_back(column);

    old_to_new_cols[col_itr] = col_itr;
    col_itr++;
  }

  std::unique_ptr<catalog::Schema> output_schema(
      new catalog::Schema(output_columns));
  bool physify_flag = true;  // is going to create a physical tile
  planner::MaterializationPlan mat_node(old_to_new_cols, output_schema.release(),
                                        physify_flag);

  executor::MaterializationExecutor mat_executor(&mat_node, nullptr);
  mat_executor.AddChild(&seq_scan_executor);
  bool status = false;

  /////////////////////////////////////////////////////////
  // EXECUTE
  /////////////////////////////////////////////////////////

  status = mat_executor.Init();
  assert(status == true);

  std::vector<std::unique_ptr<executor::LogicalTile>> result_tiles;

  while(mat_executor.Execute() == true) {
    std::unique_ptr<executor::LogicalTile> result_tile(mat_executor.GetOutput());
    assert(result_tile != nullptr);
    result_tiles.emplace_back(result_tile.release());
  }

  status = mat_executor.Execute();
  assert(status == false);

  txn_manager.CommitTransaction(txn);

  end = std::chrono::system_clock::now();
  std::chrono::duration<double> elapsed_seconds = end-start;

  std::cout << "logical tile count :: " << result_tiles.size() << "\n";
  std::cout << "duration :: " << elapsed_seconds.count() << "s\n";
}

void RunAggregateTest() {

}

void RunArithmeticTest() {

}

}  // namespace hyadapt
}  // namespace benchmark
}  // namespace peloton
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Part of LevelMutex test program for The Loki Library
// Copyright (c) 2008, 2009 Richard Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The author makes no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
////////////////////////////////////////////////////////////////////////////////

// $Id$

// ----------------------------------------------------------------------------

#ifndef LOKI_TEST_LEVEL_MUTEX_THING_H
#define LOKI_TEST_LEVEL_MUTEX_THING_H

#include <LevelMutex.h>
#include <Allocator.h>

#include <vector>

// ----------------------------------------------------------------------------

void GoToSleep( unsigned int milliSeconds );

// ----------------------------------------------------------------------------

class ExceptionTossingMutex : public ::Loki::SleepLevelMutex
{
public:

    enum ThrowingPolicy
    {
        Never,
        Always,
        Randomly
    };

    ExceptionTossingMutex( unsigned int level );

    virtual ~ExceptionTossingMutex( void );

    virtual ::Loki::MutexErrors::Type Lock( void ) volatile;

    virtual ::Loki::MutexErrors::Type TryLock( void ) volatile;

    virtual ::Loki::MutexErrors::Type Unlock( void ) volatile;

    inline ThrowingPolicy GetTossPolicy( void ) const { return m_policy; }

    inline void SetTossPolicy( ThrowingPolicy policy ) { m_policy = policy; }

private:

    ExceptionTossingMutex( void );
    ExceptionTossingMutex( const ExceptionTossingMutex & );
    ExceptionTossingMutex & operator = ( const ExceptionTossingMutex & );

    ThrowingPolicy m_policy;
};

typedef ::Loki::LevelMutex< ExceptionTossingMutex, 1,
    ::Loki::JustReturnMutexError, ::Loki::NoMutexWait > ExceptionMutex;

typedef ::Loki::LevelMutex< ::Loki::SleepLevelMutex, 1,
    ::Loki::JustReturnMutexError, ::Loki::MutexSleepWaits > SleepMutex;

// ----------------------------------------------------------------------------

class TestResults
{
public:

    static bool Create( unsigned int threadCount );

    static void Destroy( void );

    inline static TestResults * GetIt( void ) { return s_instance; }

    void Reset( unsigned int threadCount );

    void SetResult( unsigned int threadIndex, unsigned int total,
        unsigned int fails );

    void OutputResults( void );

private:

    struct TestResult
    {
        TestResult( void );
        TestResult( const TestResult & that );
        ~TestResult( void );
        unsigned int m_total;
        unsigned int m_fails;
    };

    typedef ::std::vector< TestResult, ::Loki::LokiAllocator< TestResult > > Results;

    explicit TestResults( unsigned int threadCount );

    ~TestResults( void );

    TestResults( void );
    TestResults( const TestResults & );
    TestResults & operator = ( const TestResults & );

    static TestResults * s_instance;

    Results m_results;
};

// ----------------------------------------------------------------------------

class Thing
{
public:

    typedef ::std::vector< volatile Thing * > ThingPool;

    static volatile Thing & GetIt( void ) { return *s_thing; }

    static void Init( unsigned int value );

    static void Destroy( void );

    static volatile Thing * GetFromPool( unsigned int index );

    static bool MakePool( unsigned int count );

    static unsigned int GetPoolSize( void );

    static void DestroyPool( void );

    void Print( unsigned int value, unsigned int index, unsigned int startSize ) const volatile;

    void Print( unsigned int value, unsigned int index, unsigned int startSize ) const;

    unsigned int GetValue( void ) const volatile { return m_value; }

    unsigned int GetValue( void ) const { return m_value; }

    void SetValue( unsigned int value ) volatile;

    void SetValue( unsigned int value ) { m_value = value; }

    inline volatile SleepMutex & GetMutex( void ) volatile { return m_mutex; }

    inline const volatile SleepMutex & GetMutex( void ) const volatile { return m_mutex; }

private:

    explicit Thing( unsigned int value );

    ~Thing( void );

    Thing( void );
    Thing( const Thing & );
    Thing & operator = ( const Thing & );

    static volatile Thing * s_thing;

    static ThingPool s_pool;

    static TestResults s_results;

    mutable volatile SleepMutex m_mutex;
    unsigned int m_value;
};

typedef ::std::vector< Thing * > UnsafeThingPool;

// ----------------------------------------------------------------------------

template < class Thingy >
class Unlocker
{
public:
    explicit inline Unlocker( volatile Thingy * thing ) : m_thing( thing ) {}
    inline Unlocker( const Unlocker & that ) : m_thing( that.m_thing )
    {
        const_cast< Unlocker & >( that ).m_thing = NULL;
    }
    inline ~Unlocker( void ) { Unlock(); }
    inline void Unlock( void )
    {
        if ( NULL != m_thing )
            m_thing->UnlockHierarchy();
    }
private:
    volatile Thingy * m_thing;
};

// ----------------------------------------------------------------------------

class LevelThing
{
public:

    typedef Unlocker< LevelThing > MyUnlocker;

    static volatile LevelThing * GetFromPool( unsigned int index );

    static bool MakePool( unsigned int count );

    static void DestroyPool( void );

    MyUnlocker LockHierarchy( void ) volatile;

    void UnlockHierarchy( void ) volatile;

    void SetValue( unsigned int value ) volatile;

    void SetValue( unsigned int value );

    inline unsigned int GetValue( void ) const volatile { return m_value; }

    inline unsigned int GetValue( void ) const { return m_value; }

    bool DoValuesMatch( unsigned int value ) const volatile;

    bool DoValuesMatch( unsigned int value ) const;

    inline volatile ::Loki::LevelMutexInfo & GetMutex( void ) volatile { return m_mutex; }

    inline const volatile ::Loki::LevelMutexInfo & GetMutex( void ) const volatile { return m_mutex; }

private:

    typedef ::std::vector< volatile LevelThing * > LevelThingPool;

    LevelThing( unsigned int level, unsigned int place );

    ~LevelThing( void );

    LevelThing( void );
    LevelThing( const LevelThing & );
    LevelThing & operator = ( const LevelThing & );

    static LevelThingPool s_pool;

    mutable volatile SleepMutex m_mutex;
    const unsigned int m_place;
    unsigned int m_value;
};

// ----------------------------------------------------------------------------

class SomeThing
{
public:

    SomeThing( unsigned int level, unsigned int place );

    ~SomeThing( void );

    inline unsigned int GetLevel( void ) const volatile { return m_level; }

    void SetValue( unsigned int value ) volatile;

    void SetValue( unsigned int value );

    inline unsigned int GetValue( void ) const volatile { return m_value; }

    inline unsigned int GetValue( void ) const { return m_value; }

    inline volatile ::Loki::LevelMutexInfo & GetMutex( void ) volatile { return m_mutex; }

    inline const volatile ::Loki::LevelMutexInfo & GetMutex( void ) const volatile { return m_mutex; }

private:

    SomeThing( void );
    SomeThing( const SomeThing & );
    SomeThing & operator = ( const SomeThing & );

    mutable volatile SleepMutex m_mutex;
    const unsigned int m_place;
    const unsigned int m_level;
    unsigned int m_value;
};

typedef ::std::vector< volatile SomeThing * > SomeThingPool;

typedef SomeThingPool::iterator SomeThingPoolIter;

// ----------------------------------------------------------------------------

class ManyThingsPool
{
public:

    explicit ManyThingsPool( unsigned int level, unsigned int count );

    ~ManyThingsPool( void );

    volatile SomeThing * GetFromPool( unsigned int index );

    unsigned int GetCount( void ) const;

private:

    ManyThingsPool( void );
    ManyThingsPool( const ManyThingsPool & );
    ManyThingsPool & operator = ( const ManyThingsPool & );

    SomeThingPool m_pool;
};

// ----------------------------------------------------------------------------

class MultiLevelPool
{
public:

    static void MakePool( unsigned int count, unsigned int thingCount );

    static void DestroyPool( void );

    static ManyThingsPool * GetFromPool( unsigned int index );

    static unsigned int GetCount( void );

private:

    typedef ::std::vector< ManyThingsPool * > MultiThingPool;

    ~MultiLevelPool( void );
    MultiLevelPool( void );
    MultiLevelPool( const MultiLevelPool & );
    MultiLevelPool & operator = ( const MultiLevelPool & );

    static MultiThingPool s_pool;
};

// ----------------------------------------------------------------------------

void CheckForMatchingValues( unsigned int & failCount, unsigned int & testCount,
    unsigned int value, const SomeThingPool & pool );

void CheckForMatchingValues( unsigned int & failCount, unsigned int & testCount,
    unsigned int value, const SomeThingPool & pool, bool locked );

void MakePool( SomeThingPool & pool );

void LockThese( SomeThingPool & pool );

void UnlockThese( SomeThingPool & pool );

unsigned int CountLockedByThisThread( const SomeThingPool & pool );

// ----------------------------------------------------------------------------

#endif
<commit_msg>Changed include paths.<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Part of LevelMutex test program for The Loki Library
// Copyright (c) 2008, 2009 Richard Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The author makes no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
////////////////////////////////////////////////////////////////////////////////

// $Id$

// ----------------------------------------------------------------------------

#ifndef LOKI_TEST_LEVEL_MUTEX_THING_H
#define LOKI_TEST_LEVEL_MUTEX_THING_H

#include <loki/LevelMutex.h>
#include <loki/Allocator.h>

#include <vector>

// ----------------------------------------------------------------------------

void GoToSleep( unsigned int milliSeconds );

// ----------------------------------------------------------------------------

class ExceptionTossingMutex : public ::Loki::SleepLevelMutex
{
public:

    enum ThrowingPolicy
    {
        Never,
        Always,
        Randomly
    };

    ExceptionTossingMutex( unsigned int level );

    virtual ~ExceptionTossingMutex( void );

    virtual ::Loki::MutexErrors::Type Lock( void ) volatile;

    virtual ::Loki::MutexErrors::Type TryLock( void ) volatile;

    virtual ::Loki::MutexErrors::Type Unlock( void ) volatile;

    inline ThrowingPolicy GetTossPolicy( void ) const { return m_policy; }

    inline void SetTossPolicy( ThrowingPolicy policy ) { m_policy = policy; }

private:

    ExceptionTossingMutex( void );
    ExceptionTossingMutex( const ExceptionTossingMutex & );
    ExceptionTossingMutex & operator = ( const ExceptionTossingMutex & );

    ThrowingPolicy m_policy;
};

typedef ::Loki::LevelMutex< ExceptionTossingMutex, 1,
    ::Loki::JustReturnMutexError, ::Loki::NoMutexWait > ExceptionMutex;

typedef ::Loki::LevelMutex< ::Loki::SleepLevelMutex, 1,
    ::Loki::JustReturnMutexError, ::Loki::MutexSleepWaits > SleepMutex;

// ----------------------------------------------------------------------------

class TestResults
{
public:

    static bool Create( unsigned int threadCount );

    static void Destroy( void );

    inline static TestResults * GetIt( void ) { return s_instance; }

    void Reset( unsigned int threadCount );

    void SetResult( unsigned int threadIndex, unsigned int total,
        unsigned int fails );

    void OutputResults( void );

private:

    struct TestResult
    {
        TestResult( void );
        TestResult( const TestResult & that );
        ~TestResult( void );
        unsigned int m_total;
        unsigned int m_fails;
    };

    typedef ::std::vector< TestResult, ::Loki::LokiAllocator< TestResult > > Results;

    explicit TestResults( unsigned int threadCount );

    ~TestResults( void );

    TestResults( void );
    TestResults( const TestResults & );
    TestResults & operator = ( const TestResults & );

    static TestResults * s_instance;

    Results m_results;
};

// ----------------------------------------------------------------------------

class Thing
{
public:

    typedef ::std::vector< volatile Thing * > ThingPool;

    static volatile Thing & GetIt( void ) { return *s_thing; }

    static void Init( unsigned int value );

    static void Destroy( void );

    static volatile Thing * GetFromPool( unsigned int index );

    static bool MakePool( unsigned int count );

    static unsigned int GetPoolSize( void );

    static void DestroyPool( void );

    void Print( unsigned int value, unsigned int index, unsigned int startSize ) const volatile;

    void Print( unsigned int value, unsigned int index, unsigned int startSize ) const;

    unsigned int GetValue( void ) const volatile { return m_value; }

    unsigned int GetValue( void ) const { return m_value; }

    void SetValue( unsigned int value ) volatile;

    void SetValue( unsigned int value ) { m_value = value; }

    inline volatile SleepMutex & GetMutex( void ) volatile { return m_mutex; }

    inline const volatile SleepMutex & GetMutex( void ) const volatile { return m_mutex; }

private:

    explicit Thing( unsigned int value );

    ~Thing( void );

    Thing( void );
    Thing( const Thing & );
    Thing & operator = ( const Thing & );

    static volatile Thing * s_thing;

    static ThingPool s_pool;

    static TestResults s_results;

    mutable volatile SleepMutex m_mutex;
    unsigned int m_value;
};

typedef ::std::vector< Thing * > UnsafeThingPool;

// ----------------------------------------------------------------------------

template < class Thingy >
class Unlocker
{
public:
    explicit inline Unlocker( volatile Thingy * thing ) : m_thing( thing ) {}
    inline Unlocker( const Unlocker & that ) : m_thing( that.m_thing )
    {
        const_cast< Unlocker & >( that ).m_thing = NULL;
    }
    inline ~Unlocker( void ) { Unlock(); }
    inline void Unlock( void )
    {
        if ( NULL != m_thing )
            m_thing->UnlockHierarchy();
    }
private:
    volatile Thingy * m_thing;
};

// ----------------------------------------------------------------------------

class LevelThing
{
public:

    typedef Unlocker< LevelThing > MyUnlocker;

    static volatile LevelThing * GetFromPool( unsigned int index );

    static bool MakePool( unsigned int count );

    static void DestroyPool( void );

    MyUnlocker LockHierarchy( void ) volatile;

    void UnlockHierarchy( void ) volatile;

    void SetValue( unsigned int value ) volatile;

    void SetValue( unsigned int value );

    inline unsigned int GetValue( void ) const volatile { return m_value; }

    inline unsigned int GetValue( void ) const { return m_value; }

    bool DoValuesMatch( unsigned int value ) const volatile;

    bool DoValuesMatch( unsigned int value ) const;

    inline volatile ::Loki::LevelMutexInfo & GetMutex( void ) volatile { return m_mutex; }

    inline const volatile ::Loki::LevelMutexInfo & GetMutex( void ) const volatile { return m_mutex; }

private:

    typedef ::std::vector< volatile LevelThing * > LevelThingPool;

    LevelThing( unsigned int level, unsigned int place );

    ~LevelThing( void );

    LevelThing( void );
    LevelThing( const LevelThing & );
    LevelThing & operator = ( const LevelThing & );

    static LevelThingPool s_pool;

    mutable volatile SleepMutex m_mutex;
    const unsigned int m_place;
    unsigned int m_value;
};

// ----------------------------------------------------------------------------

class SomeThing
{
public:

    SomeThing( unsigned int level, unsigned int place );

    ~SomeThing( void );

    inline unsigned int GetLevel( void ) const volatile { return m_level; }

    void SetValue( unsigned int value ) volatile;

    void SetValue( unsigned int value );

    inline unsigned int GetValue( void ) const volatile { return m_value; }

    inline unsigned int GetValue( void ) const { return m_value; }

    inline volatile ::Loki::LevelMutexInfo & GetMutex( void ) volatile { return m_mutex; }

    inline const volatile ::Loki::LevelMutexInfo & GetMutex( void ) const volatile { return m_mutex; }

private:

    SomeThing( void );
    SomeThing( const SomeThing & );
    SomeThing & operator = ( const SomeThing & );

    mutable volatile SleepMutex m_mutex;
    const unsigned int m_place;
    const unsigned int m_level;
    unsigned int m_value;
};

typedef ::std::vector< volatile SomeThing * > SomeThingPool;

typedef SomeThingPool::iterator SomeThingPoolIter;

// ----------------------------------------------------------------------------

class ManyThingsPool
{
public:

    explicit ManyThingsPool( unsigned int level, unsigned int count );

    ~ManyThingsPool( void );

    volatile SomeThing * GetFromPool( unsigned int index );

    unsigned int GetCount( void ) const;

private:

    ManyThingsPool( void );
    ManyThingsPool( const ManyThingsPool & );
    ManyThingsPool & operator = ( const ManyThingsPool & );

    SomeThingPool m_pool;
};

// ----------------------------------------------------------------------------

class MultiLevelPool
{
public:

    static void MakePool( unsigned int count, unsigned int thingCount );

    static void DestroyPool( void );

    static ManyThingsPool * GetFromPool( unsigned int index );

    static unsigned int GetCount( void );

private:

    typedef ::std::vector< ManyThingsPool * > MultiThingPool;

    ~MultiLevelPool( void );
    MultiLevelPool( void );
    MultiLevelPool( const MultiLevelPool & );
    MultiLevelPool & operator = ( const MultiLevelPool & );

    static MultiThingPool s_pool;
};

// ----------------------------------------------------------------------------

void CheckForMatchingValues( unsigned int & failCount, unsigned int & testCount,
    unsigned int value, const SomeThingPool & pool );

void CheckForMatchingValues( unsigned int & failCount, unsigned int & testCount,
    unsigned int value, const SomeThingPool & pool, bool locked );

void MakePool( SomeThingPool & pool );

void LockThese( SomeThingPool & pool );

void UnlockThese( SomeThingPool & pool );

unsigned int CountLockedByThisThread( const SomeThingPool & pool );

// ----------------------------------------------------------------------------

#endif
<|endoftext|>