<commit_before>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.
https://github.com/ETLCPP/etl

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>
#include "ExtraCheckMacros.h"

#include "data.h"

#include <set>
#include <vector>

#include "../pool.h"

typedef TestDataDC<std::string>  Test_Data;
typedef TestDataNDC<std::string> Test_Data2;

namespace
{
  SUITE(test_pool)
  {
    //*************************************************************************
    TEST(test_allocate)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1;
      Test_Data* p2;
      Test_Data* p3;
      Test_Data* p4;

      CHECK_NO_THROW(p1 = pool.allocate());
      CHECK_NO_THROW(p2 = pool.allocate());
      CHECK_NO_THROW(p3 = pool.allocate());
      CHECK_NO_THROW(p4 = pool.allocate());

      CHECK(p1 != p2);
      CHECK(p1 != p3);
      CHECK(p1 != p4);
      CHECK(p2 != p3);
      CHECK(p2 != p4);
      CHECK(p3 != p4);

      CHECK_THROW(pool.allocate(), etl::pool_no_allocation);
    }

    //*************************************************************************
    TEST(test_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(*p3));
      CHECK_NO_THROW(pool.release(p1));
      CHECK_NO_THROW(pool.release(*p4));

      CHECK_EQUAL(4, pool.available());

      Test_Data not_in_pool;

      CHECK_THROW(pool.release(not_in_pool), etl::pool_object_not_in_pool);
    }

    //*************************************************************************
    TEST(test_allocate_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      // Allocated p1, p2, p3, p4

      CHECK_EQUAL(0, pool.available());

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));

      // Allocated p1, p4

      CHECK_EQUAL(2, pool.available());

      Test_Data* p5 = pool.allocate();
      Test_Data* p6 = pool.allocate();

      // Allocated p1, p4, p5, p6

      CHECK_EQUAL(0, pool.available());

      CHECK(p5 != p1);
      CHECK(p5 != p4);

      CHECK(p6 != p1);
      CHECK(p6 != p4);

      CHECK_NO_THROW(pool.release(p5));

      // Allocated p1, p4, p6

      CHECK_EQUAL(1, pool.available());

      Test_Data* p7 = pool.allocate();

      // Allocated p1, p4, p6, p7

      CHECK(p7 != p1);
      CHECK(p7 != p4);
      CHECK(p7 != p6);

      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_available)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK_EQUAL(3, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(2, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(1, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(0, pool.available());
    }

    //*************************************************************************
    TEST(test_none_free)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_is_in_pool)
    {
      etl::pool<Test_Data, 4> pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate();

      CHECK(pool.is_in_pool(p1));
      CHECK(!pool.is_in_pool(not_in_pool));
    }

    //*************************************************************************
    TEST(test_const_iterator)
    {
      etl::pool<Test_Data2, 10> pool;

      std::set<Test_Data2>     compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") };
      std::set<Test_Data2>     test;
      std::vector<Test_Data2*> objects;

      // Build the set of objects.
      objects.push_back(pool.allocate(Test_Data2("9")));
      objects.push_back(pool.allocate(Test_Data2("7")));
      objects.push_back(pool.allocate(Test_Data2("8")));
      objects.push_back(pool.allocate(Test_Data2("6")));
      objects.push_back(pool.allocate(Test_Data2("5")));
      objects.push_back(pool.allocate(Test_Data2("3")));
      objects.push_back(pool.allocate(Test_Data2("4")));
      objects.push_back(pool.allocate(Test_Data2("2")));
      objects.push_back(pool.allocate(Test_Data2("0")));
      objects.push_back(pool.allocate(Test_Data2("1")));

      // Release "1", "3", "5", "7", "9".
      pool.release(objects[0]);
      pool.release(objects[1]);
      pool.release(objects[4]);
      pool.release(objects[5]);
      pool.release(objects[9]);

      // Fill the test set with what we get from the iterator.
      etl::pool<Test_Data2, 10>::const_iterator i_pool = pool.begin();

      while (i_pool != pool.end())
      {
        test.insert(*i_pool);
        ++i_pool;
      }

      // Compare the results.
      std::set<Test_Data2>::const_iterator i_compare = compare.begin();
      std::set<Test_Data2>::const_iterator i_test    = test.begin();

      CHECK_EQUAL(compare.size(), test.size());

      while ((i_compare != compare.end()) && (i_test != test.end()))
      {
        CHECK_EQUAL(*i_compare++, *i_test++);
      }
    }
  };
}
<commit_msg>Added get_iterator tests<commit_after>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.
https://github.com/ETLCPP/etl

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>
#include "ExtraCheckMacros.h"

#include "data.h"

#include <set>
#include <vector>

#include "../pool.h"

typedef TestDataDC<std::string>  Test_Data;
typedef TestDataNDC<std::string> Test_Data2;

namespace
{
  SUITE(test_pool)
  {
    //*************************************************************************
    TEST(test_allocate)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1;
      Test_Data* p2;
      Test_Data* p3;
      Test_Data* p4;

      CHECK_NO_THROW(p1 = pool.allocate());
      CHECK_NO_THROW(p2 = pool.allocate());
      CHECK_NO_THROW(p3 = pool.allocate());
      CHECK_NO_THROW(p4 = pool.allocate());

      CHECK(p1 != p2);
      CHECK(p1 != p3);
      CHECK(p1 != p4);
      CHECK(p2 != p3);
      CHECK(p2 != p4);
      CHECK(p3 != p4);

      CHECK_THROW(pool.allocate(), etl::pool_no_allocation);
    }

    //*************************************************************************
    TEST(test_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(*p3));
      CHECK_NO_THROW(pool.release(p1));
      CHECK_NO_THROW(pool.release(*p4));

      CHECK_EQUAL(4, pool.available());

      Test_Data not_in_pool;

      CHECK_THROW(pool.release(not_in_pool), etl::pool_object_not_in_pool);
    }

    //*************************************************************************
    TEST(test_allocate_release)
    {
      etl::pool<Test_Data, 4> pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();
      Test_Data* p3 = pool.allocate();
      Test_Data* p4 = pool.allocate();

      // Allocated p1, p2, p3, p4

      CHECK_EQUAL(0, pool.available());

      CHECK_NO_THROW(pool.release(p2));
      CHECK_NO_THROW(pool.release(p3));

      // Allocated p1, p4

      CHECK_EQUAL(2, pool.available());

      Test_Data* p5 = pool.allocate();
      Test_Data* p6 = pool.allocate();

      // Allocated p1, p4, p5, p6

      CHECK_EQUAL(0, pool.available());

      CHECK(p5 != p1);
      CHECK(p5 != p4);

      CHECK(p6 != p1);
      CHECK(p6 != p4);

      CHECK_NO_THROW(pool.release(p5));

      // Allocated p1, p4, p6

      CHECK_EQUAL(1, pool.available());

      Test_Data* p7 = pool.allocate();

      // Allocated p1, p4, p6, p7

      CHECK(p7 != p1);
      CHECK(p7 != p4);
      CHECK(p7 != p6);

      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_available)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK_EQUAL(3, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(2, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(1, pool.available());

      p = pool.allocate();
      CHECK_EQUAL(0, pool.available());
    }

    //*************************************************************************
    TEST(test_none_free)
    {
      etl::pool<Test_Data, 4> pool;
      CHECK_EQUAL(4, pool.available());

      Test_Data* p;

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(!pool.none_free());

      p = pool.allocate();
      CHECK(pool.none_free());
    }

    //*************************************************************************
    TEST(test_is_in_pool)
    {
      etl::pool<Test_Data, 4> pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate();

      CHECK(pool.is_in_pool(p1));
      CHECK(!pool.is_in_pool(not_in_pool));
    }

    //*************************************************************************
    TEST(test_const_iterator)
    {
      etl::pool<Test_Data2, 10> pool;

      std::set<Test_Data2>     compare = { Test_Data2("0"), Test_Data2("2"), Test_Data2("4"), Test_Data2("6"), Test_Data2("8") };
      std::set<Test_Data2>     test;
      std::vector<Test_Data2*> objects;

      // Build the set of objects.
      objects.push_back(pool.allocate(Test_Data2("9")));
      objects.push_back(pool.allocate(Test_Data2("7")));
      objects.push_back(pool.allocate(Test_Data2("8")));
      objects.push_back(pool.allocate(Test_Data2("6")));
      objects.push_back(pool.allocate(Test_Data2("5")));
      objects.push_back(pool.allocate(Test_Data2("3")));
      objects.push_back(pool.allocate(Test_Data2("4")));
      objects.push_back(pool.allocate(Test_Data2("2")));
      objects.push_back(pool.allocate(Test_Data2("0")));
      objects.push_back(pool.allocate(Test_Data2("1")));

      // Release "1", "3", "5", "7", "9".
      pool.release(objects[0]);
      pool.release(objects[1]);
      pool.release(objects[4]);
      pool.release(objects[5]);
      pool.release(objects[9]);

      // Fill the test set with what we get from the iterator.
      etl::pool<Test_Data2, 10>::const_iterator i_pool = pool.begin();

      while (i_pool != pool.end())
      {
        test.insert(*i_pool);
        ++i_pool;
      }

      // Compare the results.
      std::set<Test_Data2>::const_iterator i_compare = compare.begin();
      std::set<Test_Data2>::const_iterator i_test    = test.begin();

      CHECK_EQUAL(compare.size(), test.size());

      while ((i_compare != compare.end()) && (i_test != test.end()))
      {
        CHECK_EQUAL(*i_compare++, *i_test++);
      }
    }

    //*************************************************************************
    TEST(test_get_iterator)
    {
      typedef etl::pool<Test_Data, 4> Pool;

      Pool pool;
      Test_Data not_in_pool;

      Test_Data* p1 = pool.allocate();
      Test_Data* p2 = pool.allocate();

      Pool::iterator i_data  = pool.get_iterator(*p1);
      Pool::iterator i_ndata = pool.get_iterator(not_in_pool);

      CHECK(p1 == &*i_data);
      CHECK(p2 != &*i_data);
      CHECK(pool.end() == i_ndata);
    }

    //*************************************************************************
    TEST(test_get_iterator_const)
    {
      typedef etl::pool<Test_Data, 4> Pool;

      Pool pool;
      const Test_Data not_in_pool;

      const Test_Data* p1 = pool.allocate();
      const Test_Data* p2 = pool.allocate();

      Pool::const_iterator i_data = pool.get_iterator(*p1);
      Pool::const_iterator i_ndata = pool.get_iterator(not_in_pool);

      CHECK(p1 == &*i_data);
      CHECK(p2 != &*i_data);
      CHECK(pool.end() == i_ndata);
    }
  };
}
<|endoftext|>


<commit_before>// @(#)root/utils:$Id$
// Author: Philippe Canal 27/08/2003

/*************************************************************************
 * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers, and al.          *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS              *
 *************************************************************************/

#include "RConfigure.h"
#include "RConfig.h"

#include "RStl.h"
#include "TClassEdit.h"
#include "TMetaUtils.h"
using namespace TClassEdit;

#include <stdio.h>

#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"

#include "Scanner.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"

#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/AST/DeclTemplate.h"

#ifndef ROOT_Varargs
#include "Varargs.h"
#endif
// void Error(const char *location, const char *va_(fmt), ...);
// void Warning(const char *location, const char *va_(fmt), ...);

//
// ROOT::Internal::RStl is the rootcint STL handling class.
//

static int fgCount = 0;

ROOT::Internal::RStl& ROOT::Internal::RStl::Instance()
{
   // Return the singleton ROOT::Internal::RStl.

   static ROOT::Internal::RStl instance;
   return instance;

}

void ROOT::Internal::RStl::GenerateTClassFor(const clang::QualType &type, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.

   const clang::CXXRecordDecl *stlclass = type.getTypePtr()->getAsCXXRecordDecl();
   if (stlclass == 0) {
      return;
   }
   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (templateCl == 0) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,type.getTypePtr(),stlclass,"",false /* for backward compatibility rather than 'true' .. neither really make a difference */,false,false,false,-1, interp, normCtxt) );

   // fprintf(stderr,"Registered the STL class %s as needing a dictionary\n",R__GetQualifiedName(*stlclass).c_str());

   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation(), arg.getAsType());
                  }
                  // Do we need to strip the qualifier?
                  GenerateTClassFor(arg.getAsType(),interp,normCtxt);
               }
            }
      }
   }
}

void ROOT::Internal::RStl::GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlclass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.

   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (templateCl == 0) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,stlclass,requestedName,true,false,false,false,-1, interp,normCtxt) );

   TClassEdit::TSplitType splitType( requestedName, (TClassEdit::EModType)(TClassEdit::kLong64 | TClassEdit::kDropStd) );
   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation (), arg.getAsType());
                     clxx = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
                  }
                  if (!splitType.fElements.empty()) {
                     GenerateTClassFor( splitType.fElements[i+1].c_str(), clxx, interp, normCtxt);
                  } else {
                     GenerateTClassFor( "", clxx, interp, normCtxt );
                  }
               }
            }
      }
   }

   //    fprintf(stderr,"ROOT::Internal::RStl registered %s as %s\n",stlclassname.c_str(),registername.c_str());
}

void ROOT::Internal::RStl::Print()
{
   // Print the content of the object
   fprintf(stderr,"ROOT::Internal::RStl singleton\n");
   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      fprintf(stderr, "need TClass for %s\n", ROOT::TMetaUtils::GetQualifiedName(*(*iter)).c_str());
   }
}

void ROOT::Internal::RStl::WriteClassInit(std::ostream &ostr,
                                const cling::Interpreter &interp,
                                const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
                                const ROOT::TMetaUtils::RConstructorTypes& ctorTypes,
                                bool &needCollectionProxy,
                                void (*emitStreamerInfo)(const char*) )
{
   // This function writes the TGeneraticClassInfo initialiser
   // and the auxiliary functions (new and delete wrappers) for
   // each of the STL containers that have been registered

   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      const clang::CXXRecordDecl* result;

      if (!iter->GetRecordDecl()->getDefinition()) {

         // We do not have a complete definition, we need to force the instantiation
         // and findScope can do that.
         const cling::LookupHelper& lh = interp.getLookupHelper();
         result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(iter->GetNormalizedName(),
                                                                            cling::LookupHelper::NoDiagnostics,
                                                                            0)
                                                               );

         if (!result || !iter->GetRecordDecl()->getDefinition()) {
            fprintf(stderr,"Error: incomplete definition for %s\n",iter->GetNormalizedName());
            continue;
         }
      }
      else
      {
         result = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl());
      }

//      std::string fullname = TMetaUtils::GetQualifiedName(*iter->GetRecordDecl());
//      fprintf(stderr,"RStl is generating TClass for %ld %s %s %s\n",iter->GetRuleIndex(),iter->GetRequestedName(),iter->GetNormalizedName(),fullname.c_str());

      ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy);
      ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt);

      if (emitStreamerInfo) emitStreamerInfo(iter->GetNormalizedName());
   }
}

// void ROOT::Internal::RStl::WriteStreamer(FILE *file, const clang::CXXRecordDecl *stlcl)
// {
//    // Write the free standing streamer function for the given
//    // STL container class.

//    std::string streamerName = "stl_streamer_";

//    std::string shortTypeName = GetLong64_Name( TClassEdit::ShortType(ROOT::TMetaUtils::GetQualifiedName(*stlcl).c_str(),TClassEdit::kDropStlDefault) );
//    std::string noConstTypeName( TClassEdit::CleanType(shortTypeName.c_str(),2) );

//    std::string typedefName;
//    ROOT::TMetaUtils::GetCppName(typedefName, shortTypeName.c_str());
//    streamerName += typedefName;

//    const clang::ClassTemplateSpecializationDecl *tmplt_specialization = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl> (stlcl);
//    if (!tmplt_specialization) return;

//    int stltype = TClassEdit::STLKind(tmplt_specialization->getName().str().c_str());

//    const clang::TemplateArgument &arg0( tmplt_specialization->getTemplateArgs().get(0) );

//    clang::QualType firstType = arg0.getAsType();
//    clang::QualType secondType;

//    const char *tclFirst=0,*tclSecond=0;
//    std::string firstFullName, secondFullName;

//    if (ROOT::TMetaUtils::ElementStreamer(*stlcl, firstType,0,0)) {
//       tclFirst = "R__tcl1";
//       firstFullName = firstType.getAsString();
//    }
//    if (stltype==kMap || stltype==kMultiMap) {
//       const clang::TemplateArgument &arg1( tmplt_specialization->getTemplateArgs().get(1) );
//       secondType = arg1.getAsType();

//       if (ROOT::TMetaUtils::ElementStreamer(*stlcl, secondType,0,0)) {
//          tclSecond="R__tcl2";
//          secondFullName = secondType.getAsString();
//       }
//    }

//    fprintf(file, "//___________________________________________________________");
//    fprintf(file, "_____________________________________________________________\n");
//    fprintf(file, "namespace ROOT {\n");
//    fprintf(file, "   typedef %s %s;\n",shortTypeName.c_str(), typedefName.c_str());
//    fprintf(file, "   static void %s(TBuffer &R__b, void *R__p)\n",streamerName.c_str());
//    fprintf(file, "   {\n");
//    fprintf(file, "      if (gDebug>1) Info(__FILE__,\"Running compiled streamer for %s at %%p\",R__p);\n",shortTypeName.c_str());
//    fprintf(file, "      %s &R__stl = *(%s *)R__p;\n",shortTypeName.c_str(),shortTypeName.c_str());
//    fprintf(file, "      if (R__b.IsReading()) {\n");
//    fprintf(file, "         R__stl.clear();\n");

//    if (tclFirst)
//       fprintf(file, "         TClass *R__tcl1 = TBuffer::GetClass(typeid(%s));\n",
//               firstFullName.c_str());
//    if (tclSecond)
//       fprintf(file, "         TClass *R__tcl2 = TBuffer::GetClass(typeid(%s));\n",
//               secondFullName.c_str());

//    fprintf(file, "         int R__i, R__n;\n");
//    fprintf(file, "         R__b >> R__n;\n");

//    if (stltype==kVector) {
//       fprintf(file,"         R__stl.reserve(R__n);\n");
//    }
//    fprintf(file, "         for (R__i = 0; R__i < R__n; R__i++) {\n");

//    ROOT::TMetaUtils::ElementStreamer(*stlcl, firstType,"R__t",0,tclFirst);
//    if (stltype == kMap || stltype == kMultiMap) {     //Second Arg
//       ROOT::TMetaUtils::ElementStreamer(*stlcl, secondType,"R__t2",0,tclSecond);
//    }
//    switch (stltype) {

//       case kMap:
//       case kMultiMap:
//          fprintf(file, "            R__stl.insert(make_pair(R__t,R__t2));\n");
//          break;
//       case kSet:
//       case kMultiSet:
//          fprintf(file, "            R__stl.insert(R__t);\n");
//          break;
//       case kVector:
//       case kList:
//       case kDeque:
//          fprintf(file, "            R__stl.push_back(R__t);\n");
//          break;

//       default:
//             assert(0);
//    }
//    fprintf(file, "         }\n");

//    fprintf(file, "      } else {\n");

//    fprintf(file, "         int R__n=(&R__stl) ? int(R__stl.size()) : 0;\n");
//    fprintf(file, "         R__b << R__n;\n");
//    fprintf(file, "         if(R__n) {\n");

//    if (tclFirst) {
//       fprintf(file, "            TClass *R__tcl1 = TBuffer::GetClass(typeid(%s));\n",
//               firstFullName.c_str());
//       fprintf(file, "            if (R__tcl1==0) {\n");
//       fprintf(file, "               Error(\"%s streamer\",\"Missing the TClass object for %s!\");\n",
//               shortTypeName.c_str(), firstFullName.c_str());
//       fprintf(file, "               return;\n");
//       fprintf(file, "            }\n");
//    }
//    if (tclSecond) {
//       fprintf(file, "            TClass *R__tcl2 = TBuffer::GetClass(typeid(%s));\n",
//               secondFullName.c_str());
//       fprintf(file, "            if (R__tcl2==0) {\n");
//       fprintf(file, "               Error(\"%s streamer\",\"Missing the TClass object for %s!\");\n",
//               shortTypeName.c_str(), secondFullName.c_str());
//       fprintf(file, "               return;\n");
//       fprintf(file, "            }\n");
//    }
//    fprintf(file, "            %s::iterator R__k;\n", shortTypeName.c_str());
//    fprintf(file, "            for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {\n");

//    if (stltype == kMap || stltype == kMultiMap) {
//       ROOT::TMetaUtils::ElementStreamer(*stlcl, firstType ,"((*R__k).first )",1,tclFirst);
//       ROOT::TMetaUtils::ElementStreamer(*stlcl, secondType,"((*R__k).second)",1,tclSecond);
//    } else {
//       ROOT::TMetaUtils::ElementStreamer(*stlcl, firstType ,"(*R__k)"         ,1,tclFirst);
//    }

//    fprintf(file, "            }\n");
//    fprintf(file, "         }\n");

//    fprintf(file, "      }\n");
//    fprintf(file, "   } // end of %s streamer\n",ROOT::TMetaUtils::GetQualifiedName(*stlcl).c_str());
//    fprintf(file, "} // close namespace ROOT\n\n");

//    fprintf(file, "// Register the streamer (a typedef is used to avoid problem with macro parameters\n");

//    //if ( 0 != ::getenv("MY_ROOT") && ::getenv("MY_ROOT")[0]>'1' )  {
//    //  fprintf(file, "// Disabled due customized build:\n// ");
//    //}
//    fprintf(file, "RootStlStreamer(%s,%s)\n", typedefName.c_str(), streamerName.c_str());
//    fprintf(file, "\n");

// }

// void ROOT::Internal::RStl::WriteStreamer(FILE *file)
// {
//    // Write the free standing streamer function for the registereed
//    // STL container classes

//    list_t::iterator iter;
//    for(iter = fList.begin(); iter != fList.end(); ++iter) {
//       WriteStreamer(file,llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl()));
//    }
// }
<commit_msg>Clean old comments<commit_after>// @(#)root/utils:$Id$
// Author: Philippe Canal 27/08/2003

/*************************************************************************
 * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers, and al.          *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS              *
 *************************************************************************/

#include "RConfigure.h"
#include "RConfig.h"

#include "RStl.h"
#include "TClassEdit.h"
#include "TMetaUtils.h"
using namespace TClassEdit;

#include <stdio.h>

#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"

#include "Scanner.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"

#include "clang/Sema/Sema.h"
#include "clang/Sema/Template.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/AST/DeclTemplate.h"

#ifndef ROOT_Varargs
#include "Varargs.h"
#endif

//
// ROOT::Internal::RStl is the rootcint STL handling class.
//

static int fgCount = 0;

ROOT::Internal::RStl& ROOT::Internal::RStl::Instance()
{
   // Return the singleton ROOT::Internal::RStl.

   static ROOT::Internal::RStl instance;
   return instance;

}

void ROOT::Internal::RStl::GenerateTClassFor(const clang::QualType &type, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.

   const clang::CXXRecordDecl *stlclass = type.getTypePtr()->getAsCXXRecordDecl();
   if (stlclass == 0) {
      return;
   }
   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (templateCl == 0) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,type.getTypePtr(),stlclass,"",false /* for backward compatibility rather than 'true' .. neither really make a difference */,false,false,false,-1, interp, normCtxt) );

   // fprintf(stderr,"Registered the STL class %s as needing a dictionary\n",R__GetQualifiedName(*stlclass).c_str());

   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation(), arg.getAsType());
                  }
                  // Do we need to strip the qualifier?
                  GenerateTClassFor(arg.getAsType(),interp,normCtxt);
               }
            }
      }
   }
}

void ROOT::Internal::RStl::GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlclass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
{
   // Force the generation of the TClass for the given class.

   const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);

   if (templateCl == 0) {
      ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
            ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
   }

   if ( TClassEdit::STLKind( stlclass->getName().str().c_str() )  == ROOT::kSTLvector ) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
         if (decl) {
            // NOTE: we should just compare the decl to the bool builtin!
            llvm::StringRef argname = decl->getName();
            if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
               ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
            }
         }
      }
   }

   fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,stlclass,requestedName,true,false,false,false,-1, interp,normCtxt) );

   TClassEdit::TSplitType splitType( requestedName, (TClassEdit::EModType)(TClassEdit::kLong64 | TClassEdit::kDropStd) );
   for(unsigned int i=0; i <  templateCl->getTemplateArgs().size(); ++i) {
      const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
      if (arg.getKind() == clang::TemplateArgument::Type) {
         const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();

         if (decl && TClassEdit::STLKind( decl->getName().str().c_str() ) != 0 )
            {
               const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
               if (clxx) {
                  if (!clxx->isCompleteDefinition()) {
                     /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation (), arg.getAsType());
                     clxx = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
                  }
                  if (!splitType.fElements.empty()) {
                     GenerateTClassFor( splitType.fElements[i+1].c_str(), clxx, interp, normCtxt);
                  } else {
                     GenerateTClassFor( "", clxx, interp, normCtxt );
                  }
               }
            }
      }
   }

}

void ROOT::Internal::RStl::Print()
{
   // Print the content of the object
   fprintf(stderr,"ROOT::Internal::RStl singleton\n");
   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      fprintf(stderr, "need TClass for %s\n", ROOT::TMetaUtils::GetQualifiedName(*(*iter)).c_str());
   }
}

void ROOT::Internal::RStl::WriteClassInit(std::ostream &ostr,
                                const cling::Interpreter &interp,
                                const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
                                const ROOT::TMetaUtils::RConstructorTypes& ctorTypes,
                                bool &needCollectionProxy,
                                void (*emitStreamerInfo)(const char*) )
{
   // This function writes the TGeneraticClassInfo initialiser
   // and the auxiliary functions (new and delete wrappers) for
   // each of the STL containers that have been registered

   list_t::iterator iter;
   for(iter = fList.begin(); iter != fList.end(); ++iter) {
      const clang::CXXRecordDecl* result;

      if (!iter->GetRecordDecl()->getDefinition()) {

         // We do not have a complete definition, we need to force the instantiation
         // and findScope can do that.
         const cling::LookupHelper& lh = interp.getLookupHelper();
         result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(iter->GetNormalizedName(),
                                                                            cling::LookupHelper::NoDiagnostics,
                                                                            0)
                                                               );

         if (!result || !iter->GetRecordDecl()->getDefinition()) {
            fprintf(stderr,"Error: incomplete definition for %s\n",iter->GetNormalizedName());
            continue;
         }
      }
      else
      {
         result = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl());
      }

      ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy);
      ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt);

      if (emitStreamerInfo) emitStreamerInfo(iter->GetNormalizedName());
   }
}
<|endoftext|>


<commit_before>#include<gsl/gsl_deriv.h>
#include <gsl/gsl_math.h>
#include"../differentiation/forward.hpp"
#include<iostream>
#include<chrono>

class example_function{
  public:
    constexpr double operator()(const double x) const{
      return (12.3*x*x)/std::sqrt(x);
    }
};

double ex_func(const double x, void* params){
  (void)(params); /* avoid unused parameter warning */
  return (12.3*x*x)/std::sqrt(x);
}

int main(){
  //GSL FUNCTION
  auto gsl_begin = std::chrono::high_resolution_clock::now();
  gsl_function F;
  double result, abserr;

  F.function = &ex_func;
  F.params = 0;
  gsl_deriv_forward (&F, 12., 1e-8, &result, &abserr);
  auto gsl_end  = std::chrono::high_resolution_clock::now();
  std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(gsl_end-gsl_begin).count() << "ns" << std::endl;

  std::cout << result << std::endl;
  //NUMPP FUNCTIONS
  auto begin_numpp = std::chrono::high_resolution_clock::now();
  constexpr auto result_numpp = numpp::derivative::forward(example_function{}, 12.);
  auto end_numpp = std::chrono::high_resolution_clock::now();
  std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end_numpp-begin_numpp).count() << "ns" << std::endl;

  std::cout << result_numpp << std::endl;

}
<commit_msg>Fixes derivative include<commit_after>#include<gsl/gsl_deriv.h>
#include <gsl/gsl_math.h>
#include"../../differentiation/forward.hpp"
#include<iostream>
#include<chrono>

class example_function{
  public:
    constexpr double operator()(const double x) const{
      return (12.3*x*x)/std::sqrt(x);
    }
};

double ex_func(const double x, void* params){
  (void)(params); /* avoid unused parameter warning */
  return (12.3*x*x)/std::sqrt(x);
}

int main(){
  //GSL FUNCTION
  auto gsl_begin = std::chrono::high_resolution_clock::now();
  gsl_function F;
  double result, abserr;

  F.function = &ex_func;
  F.params = 0;
  gsl_deriv_forward (&F, 12., 1e-8, &result, &abserr);
  auto gsl_end  = std::chrono::high_resolution_clock::now();
  std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(gsl_end-gsl_begin).count() << "ns" << std::endl;

  std::cout << result << std::endl;
  //NUMPP FUNCTIONS
  auto begin_numpp = std::chrono::high_resolution_clock::now();
  constexpr auto result_numpp = numpp::derivative::forward(example_function{}, 12.);
  auto end_numpp = std::chrono::high_resolution_clock::now();
  std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end_numpp-begin_numpp).count() << "ns" << std::endl;

  std::cout << result_numpp << std::endl;

}
<|endoftext|>


<commit_before>#ifndef TEST_UNIT_UTIL_HPP
#define TEST_UNIT_UTIL_HPP

#include <boost/typeof/typeof.hpp>
#include <gtest/gtest.h>
#include <type_traits>
#include <string>

#define EXPECT_MATRIX_FLOAT_EQ(A, B) \
  EXPECT_EQ(A.rows(), B.rows());        \
  EXPECT_EQ(A.cols(), B.cols());        \
  for (int i = 0; i < A.size(); i++)    \
    EXPECT_FLOAT_EQ(stan::math::value_of(A(i)), stan::math::value_of(B(i)), DELTA);

#define EXPECT_MATRIX_NEAR(A, B, DELTA) \
  EXPECT_EQ(A.rows(), B.rows());        \
  EXPECT_EQ(A.cols(), B.cols());        \
  for (int i = 0; i < A.size(); i++)    \
    EXPECT_NEAR(A(i), B(i), DELTA);

#define EXPECT_THROW_MSG_WITH_COUNT(expr, T_e, msg, count) \
  EXPECT_THROW(expr, T_e);                                 \
  try {                                                    \
    expr;                                                  \
  } catch (const T_e& e) {                                 \
    EXPECT_EQ(count, count_matches(msg, e.what()))         \
        << "expected message: " << msg << std::endl        \
        << "found message:    " << e.what();               \
  }

#define EXPECT_THROW_MSG(expr, T_e, msg) \
  EXPECT_THROW_MSG_WITH_COUNT(expr, T_e, msg, 1)

int count_matches(const std::string& target, const std::string& s) {
  if (target.size() == 0)
    return -1;  // error
  int count = 0;
  for (size_t pos = 0; (pos = s.find(target, pos)) != std::string::npos;
       pos += target.size())
    ++count;
  return count;
}

namespace test {
template <typename T1, typename T2>
void expect_same_type() {
  bool b = std::is_same<T1, T2>::value;
  EXPECT_TRUE(b);
}
}  // namespace test

#endif
<commit_msg>fix util<commit_after>#ifndef TEST_UNIT_UTIL_HPP
#define TEST_UNIT_UTIL_HPP

#include <boost/typeof/typeof.hpp>
#include <gtest/gtest.h>
#include <type_traits>
#include <string>

#define EXPECT_MATRIX_FLOAT_EQ(A, B) \
  EXPECT_EQ(A.rows(), B.rows());        \
  EXPECT_EQ(A.cols(), B.cols());        \
  for (int i = 0; i < A.size(); i++)    \
    EXPECT_FLOAT_EQ(A(i), B(i));

#define EXPECT_MATRIX_NEAR(A, B, DELTA) \
  EXPECT_EQ(A.rows(), B.rows());        \
  EXPECT_EQ(A.cols(), B.cols());        \
  for (int i = 0; i < A.size(); i++)    \
    EXPECT_NEAR(A(i), B(i), DELTA);

#define EXPECT_THROW_MSG_WITH_COUNT(expr, T_e, msg, count) \
  EXPECT_THROW(expr, T_e);                                 \
  try {                                                    \
    expr;                                                  \
  } catch (const T_e& e) {                                 \
    EXPECT_EQ(count, count_matches(msg, e.what()))         \
        << "expected message: " << msg << std::endl        \
        << "found message:    " << e.what();               \
  }

#define EXPECT_THROW_MSG(expr, T_e, msg) \
  EXPECT_THROW_MSG_WITH_COUNT(expr, T_e, msg, 1)

int count_matches(const std::string& target, const std::string& s) {
  if (target.size() == 0)
    return -1;  // error
  int count = 0;
  for (size_t pos = 0; (pos = s.find(target, pos)) != std::string::npos;
       pos += target.size())
    ++count;
  return count;
}

namespace test {
template <typename T1, typename T2>
void expect_same_type() {
  bool b = std::is_same<T1, T2>::value;
  EXPECT_TRUE(b);
}
}  // namespace test

#endif
<|endoftext|>


<commit_before><commit_msg>Add missing PCH for windows builds<commit_after><|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// logger_configuration.cpp
//
// Identification: src/backend/benchmark/logger/logger_configuration.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <iomanip>
#include <algorithm>
#include <sys/stat.h>

#include "backend/common/exception.h"
#include "backend/common/logger.h"
#include "backend/benchmark/logger/logger_configuration.h"
#include "backend/benchmark/ycsb/ycsb_configuration.h"
#include "backend/benchmark/tpcc/tpcc_configuration.h"

namespace peloton {
namespace benchmark {
namespace logger {

void Usage(FILE* out) {
  fprintf(out,
          "Command line options :  logger <options> \n"
          "   -h --help              :  Print help message \n"
          "   -a --asynchronous-mode :  Asynchronous mode \n"
          "   -e --experiment-type   :  Experiment Type \n"
          "   -f --data-file-size    :  Data file size (MB) \n"
          "   -l --logging-type      :  Logging type \n"
          "   -n --nvm-latency       :  NVM latency \n"
          "   -p --pcommit-latency   :  pcommit latency \n"
          "   -v --flush-mode        :  Flush mode \n"
          "   -w --commit-interval   :  Group commit interval \n"
          "   -y --benchmark-type    :  Benchmark type \n"
  );
}

static struct option opts[] = {
    {"asynchronous_mode", optional_argument, NULL, 'a'},
    {"experiment-type", optional_argument, NULL, 'e'},
    {"data-file-size", optional_argument, NULL, 'f'},
    {"logging-type", optional_argument, NULL, 'l'},
    {"nvm-latency", optional_argument, NULL, 'n'},
    {"pcommit-latency", optional_argument, NULL, 'p'},
    {"skew", optional_argument, NULL, 's'},
    {"flush-mode", optional_argument, NULL, 'v'},
    {"commit-interval", optional_argument, NULL, 'w'},
    {"benchmark-type", optional_argument, NULL, 'y'},
    {NULL, 0, NULL, 0}};

static void ValidateLoggingType(const configuration& state) {
  if (state.logging_type <= LOGGING_TYPE_INVALID) {
    LOG_ERROR("Invalid logging_type :: %d", state.logging_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("Logging_type :: %s", LoggingTypeToString(state.logging_type).c_str());
}

std::string BenchmarkTypeToString(BenchmarkType type) {
  switch (type) {
    case BENCHMARK_TYPE_INVALID:
      return "INVALID";

    case BENCHMARK_TYPE_YCSB:
      return "YCSB";
    case BENCHMARK_TYPE_TPCC:
      return "TPCC";

    default:
      LOG_ERROR("Invalid benchmark_type :: %d", type);
      exit(EXIT_FAILURE);
  }
  return "INVALID";
}

std::string ExperimentTypeToString(ExperimentType type) {
  switch (type) {
    case EXPERIMENT_TYPE_INVALID:
      return "INVALID";

    case EXPERIMENT_TYPE_THROUGHPUT:
      return "THROUGHPUT";
    case EXPERIMENT_TYPE_RECOVERY:
      return "RECOVERY";
    case EXPERIMENT_TYPE_STORAGE:
      return "STORAGE";
    case EXPERIMENT_TYPE_LATENCY:
      return "LATENCY";

    default:
      LOG_ERROR("Invalid experiment_type :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

std::string AsynchronousTypeToString(AsynchronousType type) {
  switch (type) {
    case ASYNCHRONOUS_TYPE_INVALID:
      return "INVALID";

    case ASYNCHRONOUS_TYPE_SYNC:
      return "SYNC";
    case ASYNCHRONOUS_TYPE_ASYNC:
      return "ASYNC";
    case ASYNCHRONOUS_TYPE_DISABLED:
      return "DISABLED";

    default:
      LOG_ERROR("Invalid asynchronous_mode :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

static void ValidateBenchmarkType(
    const configuration& state) {
  if (state.benchmark_type <= 0 || state.benchmark_type > 3) {
    LOG_ERROR("Invalid benchmark_type :: %d", state.benchmark_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "benchmark_type", BenchmarkTypeToString(state.benchmark_type).c_str());
}

static void ValidateDataFileSize(
    const configuration& state) {
  if (state.data_file_size <= 0) {
    LOG_ERROR("Invalid data_file_size :: %lu", state.data_file_size);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("data_file_size :: %lu", state.data_file_size);
}

static void ValidateExperimentType(
    const configuration& state) {
  if (state.experiment_type < 0 || state.experiment_type > 4) {
    LOG_ERROR("Invalid experiment_type :: %d", state.experiment_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "experiment_type", ExperimentTypeToString(state.experiment_type).c_str());
}

static void ValidateWaitTimeout(const configuration& state) {
  if (state.wait_timeout < 0) {
    LOG_ERROR("Invalid wait_timeout :: %d", state.wait_timeout);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("wait_timeout :: %d", state.wait_timeout);
}

static void ValidateFlushMode(
    const configuration& state) {
  if (state.flush_mode <= 0 || state.flush_mode >= 3) {
    LOG_ERROR("Invalid flush_mode :: %d", state.flush_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("flush_mode :: %d", state.flush_mode);
}

static void ValidateAsynchronousMode(
    const configuration& state) {
  if (state.asynchronous_mode <= ASYNCHRONOUS_TYPE_INVALID ||
      state.asynchronous_mode > ASYNCHRONOUS_TYPE_DISABLED) {
    LOG_ERROR("Invalid asynchronous_mode :: %d", state.asynchronous_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "asynchronous_mode", AsynchronousTypeToString(state.asynchronous_mode).c_str());
}

static void ValidateNVMLatency(
    const configuration& state) {
  if (state.nvm_latency < 0) {
    LOG_ERROR("Invalid nvm_latency :: %d", state.nvm_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("nvm_latency :: %d", state.nvm_latency);
}

static void ValidatePCOMMITLatency(
    const configuration& state) {
  if (state.pcommit_latency < 0) {
    LOG_ERROR("Invalid pcommit_latency :: %d", state.pcommit_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("pcommit_latency :: %d", state.pcommit_latency);
}

static void ValidateLogFileDir(
    configuration& state) {
  struct stat data_stat;

  // Assign log file dir based on logging type
  switch (state.logging_type) {
    // Log file on NVM
    case LOGGING_TYPE_NVM_WAL:
    case LOGGING_TYPE_NVM_WBL: {
      int status = stat(NVM_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = NVM_DIR;
      }
    } break;

    // Log file on SSD
    case LOGGING_TYPE_SSD_WAL:
    case LOGGING_TYPE_SSD_WBL: {
      int status = stat(SSD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = SSD_DIR;
      }
    } break;

    // Log file on HDD
    case LOGGING_TYPE_HDD_WAL:
    case LOGGING_TYPE_HDD_WBL: {
      int status = stat(HDD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = HDD_DIR;
      }
    } break;

    case LOGGING_TYPE_INVALID:
    default: {
      int status = stat(TMP_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = TMP_DIR;
      } else {
        throw Exception("Could not find temp directory : " +
                        std::string(TMP_DIR));
      }
    } break;
  }

  LOG_INFO("log_file_dir :: %s", state.log_file_dir.c_str());
}

void ParseArguments(int argc, char* argv[], configuration& state) {

  // Default Logger Values
  state.logging_type = LOGGING_TYPE_NVM_WAL;
  state.log_file_dir = TMP_DIR;
  state.data_file_size = 512;

  state.experiment_type = EXPERIMENT_TYPE_THROUGHPUT;
  state.wait_timeout = 200;
  state.benchmark_type = BENCHMARK_TYPE_YCSB;
  state.flush_mode = 2;
  state.nvm_latency = 0;
  state.pcommit_latency = 0;
  state.asynchronous_mode = ASYNCHRONOUS_TYPE_SYNC;

  // Default YCSB Values
  ycsb::state.scale_factor = 1;
  ycsb::state.duration = 1000;
  ycsb::state.column_count = 10;
  ycsb::state.update_ratio = 0.5;
  ycsb::state.backend_count = 2;
  ycsb::state.skew_factor = ycsb::SKEW_FACTOR_LOW;

  // Default Values
  tpcc::state.scale_factor = 1;
  tpcc::state.duration = 1000;
  tpcc::state.backend_count = 2;

  // Parse args
  while (1) {
    int idx = 0;
    // logger - a:e:f:hl:n:p:v:w:y:
    // ycsb   - b:c:d:k:s:u:
    // tpcc   - b:d:k:
    int c = getopt_long(argc, argv, "a:e:f:hl:n:p:v:w:y:b:c:d:k:s:u:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'a':
        state.asynchronous_mode = (AsynchronousType) atoi(optarg);
        break;
      case 'e':
        state.experiment_type = (ExperimentType)atoi(optarg);
        break;
      case 'f':
        state.data_file_size = atoi(optarg);
        break;
      case 'l':
        state.logging_type = (LoggingType)atoi(optarg);
        break;
      case 'n':
        state.nvm_latency = atoi(optarg);
        break;
      case 'p':
        state.pcommit_latency = atoi(optarg);
        break;
      case 'v':
        state.flush_mode = atoi(optarg);
        break;
      case 'w':
        state.wait_timeout = atoi(optarg);
        break;
      case 'y':
        state.benchmark_type = (BenchmarkType)atoi(optarg);
        break;

        // YCSB
      case 'b':
        ycsb::state.backend_count = atoi(optarg);
        tpcc::state.backend_count = atoi(optarg);
        break;
      case 'c':
        ycsb::state.column_count = atoi(optarg);
        break;
      case 'd':
        ycsb::state.duration = atoi(optarg);
        tpcc::state.duration = atoi(optarg);
        break;
      case 'k':
        ycsb::state.scale_factor = atoi(optarg);
        tpcc::state.scale_factor = atoi(optarg);
        break;
      case 's':
        ycsb::state.skew_factor = (ycsb::SkewFactor)atoi(optarg);
        break;
      case 'u':
        ycsb::state.update_ratio = atof(optarg);
        break;

      case 'h':
        Usage(stderr);
        ycsb::Usage(stderr);
        exit(EXIT_FAILURE);
        break;

      default:
        fprintf(stderr, "\nUnknown option: -%c-\n", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;
    }
  }

  // Print Logger configuration
  ValidateLoggingType(state);
  ValidateExperimentType(state);
  ValidateAsynchronousMode(state);
  ValidateBenchmarkType(state);
  ValidateDataFileSize(state);
  ValidateLogFileDir(state);
  ValidateWaitTimeout(state);
  ValidateFlushMode(state);
  ValidateNVMLatency(state);
  ValidatePCOMMITLatency(state);

  // Print YCSB configuration
  if(state.benchmark_type == BENCHMARK_TYPE_YCSB) {
    ycsb::ValidateScaleFactor(ycsb::state);
    ycsb::ValidateColumnCount(ycsb::state);
    ycsb::ValidateUpdateRatio(ycsb::state);
    ycsb::ValidateBackendCount(ycsb::state);
    ycsb::ValidateDuration(ycsb::state);
    ycsb::ValidateSkewFactor(ycsb::state);
  }
  // Print TPCC configuration
  else if(state.benchmark_type == BENCHMARK_TYPE_TPCC){
    tpcc::ValidateBackendCount(tpcc::state);
    tpcc::ValidateDuration(tpcc::state);
    tpcc::ValidateScaleFactor(tpcc::state);

    // Static TPCC parameters
    tpcc::state.warehouse_count = tpcc::state.scale_factor;
    tpcc::state.item_count = 10 * tpcc::state.warehouse_count;
    tpcc::state.districts_per_warehouse = 2;
    tpcc::state.customers_per_district = 30;
    tpcc::state.new_orders_per_district = 9;
  }

}

}  // namespace logger
}  // namespace benchmark
}  // namespace peloton
<commit_msg>Update logger configuration<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// logger_configuration.cpp
//
// Identification: src/backend/benchmark/logger/logger_configuration.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <iomanip>
#include <algorithm>
#include <sys/stat.h>

#include "backend/common/exception.h"
#include "backend/common/logger.h"
#include "backend/benchmark/logger/logger_configuration.h"
#include "backend/benchmark/ycsb/ycsb_configuration.h"
#include "backend/benchmark/tpcc/tpcc_configuration.h"

namespace peloton {
namespace benchmark {
namespace logger {

void Usage(FILE* out) {
  fprintf(out,
          "Command line options :  logger <options> \n"
          "   -h --help              :  Print help message \n"
          "   -a --asynchronous-mode :  Asynchronous mode \n"
          "   -e --experiment-type   :  Experiment Type \n"
          "   -f --data-file-size    :  Data file size (MB) \n"
          "   -l --logging-type      :  Logging type \n"
          "   -n --nvm-latency       :  NVM latency \n"
          "   -p --pcommit-latency   :  pcommit latency \n"
          "   -v --flush-mode        :  Flush mode \n"
          "   -w --commit-interval   :  Group commit interval \n"
          "   -y --benchmark-type    :  Benchmark type \n"
  );
}

static struct option opts[] = {
    {"asynchronous_mode", optional_argument, NULL, 'a'},
    {"experiment-type", optional_argument, NULL, 'e'},
    {"data-file-size", optional_argument, NULL, 'f'},
    {"logging-type", optional_argument, NULL, 'l'},
    {"nvm-latency", optional_argument, NULL, 'n'},
    {"pcommit-latency", optional_argument, NULL, 'p'},
    {"skew", optional_argument, NULL, 's'},
    {"flush-mode", optional_argument, NULL, 'v'},
    {"commit-interval", optional_argument, NULL, 'w'},
    {"benchmark-type", optional_argument, NULL, 'y'},
    {NULL, 0, NULL, 0}};

static void ValidateLoggingType(const configuration& state) {
  if (state.logging_type <= LOGGING_TYPE_INVALID) {
    LOG_ERROR("Invalid logging_type :: %d", state.logging_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("Logging_type :: %s", LoggingTypeToString(state.logging_type).c_str());
}

std::string BenchmarkTypeToString(BenchmarkType type) {
  switch (type) {
    case BENCHMARK_TYPE_INVALID:
      return "INVALID";

    case BENCHMARK_TYPE_YCSB:
      return "YCSB";
    case BENCHMARK_TYPE_TPCC:
      return "TPCC";

    default:
      LOG_ERROR("Invalid benchmark_type :: %d", type);
      exit(EXIT_FAILURE);
  }
  return "INVALID";
}

std::string ExperimentTypeToString(ExperimentType type) {
  switch (type) {
    case EXPERIMENT_TYPE_INVALID:
      return "INVALID";

    case EXPERIMENT_TYPE_THROUGHPUT:
      return "THROUGHPUT";
    case EXPERIMENT_TYPE_RECOVERY:
      return "RECOVERY";
    case EXPERIMENT_TYPE_STORAGE:
      return "STORAGE";
    case EXPERIMENT_TYPE_LATENCY:
      return "LATENCY";

    default:
      LOG_ERROR("Invalid experiment_type :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

std::string AsynchronousTypeToString(AsynchronousType type) {
  switch (type) {
    case ASYNCHRONOUS_TYPE_INVALID:
      return "INVALID";

    case ASYNCHRONOUS_TYPE_SYNC:
      return "SYNC";
    case ASYNCHRONOUS_TYPE_ASYNC:
      return "ASYNC";
    case ASYNCHRONOUS_TYPE_DISABLED:
      return "DISABLED";

    default:
      LOG_ERROR("Invalid asynchronous_mode :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

static void ValidateBenchmarkType(
    const configuration& state) {
  if (state.benchmark_type <= 0 || state.benchmark_type > 3) {
    LOG_ERROR("Invalid benchmark_type :: %d", state.benchmark_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "benchmark_type", BenchmarkTypeToString(state.benchmark_type).c_str());
}

static void ValidateDataFileSize(
    const configuration& state) {
  if (state.data_file_size <= 0) {
    LOG_ERROR("Invalid data_file_size :: %lu", state.data_file_size);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("data_file_size :: %lu", state.data_file_size);
}

static void ValidateExperimentType(
    const configuration& state) {
  if (state.experiment_type < 0 || state.experiment_type > 4) {
    LOG_ERROR("Invalid experiment_type :: %d", state.experiment_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "experiment_type", ExperimentTypeToString(state.experiment_type).c_str());
}

static void ValidateWaitTimeout(const configuration& state) {
  if (state.wait_timeout < 0) {
    LOG_ERROR("Invalid wait_timeout :: %d", state.wait_timeout);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("wait_timeout :: %d", state.wait_timeout);
}

static void ValidateFlushMode(
    const configuration& state) {
  if (state.flush_mode <= 0 || state.flush_mode >= 3) {
    LOG_ERROR("Invalid flush_mode :: %d", state.flush_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("flush_mode :: %d", state.flush_mode);
}

static void ValidateAsynchronousMode(
    const configuration& state) {
  if (state.asynchronous_mode <= ASYNCHRONOUS_TYPE_INVALID ||
      state.asynchronous_mode > ASYNCHRONOUS_TYPE_DISABLED) {
    LOG_ERROR("Invalid asynchronous_mode :: %d", state.asynchronous_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "asynchronous_mode", AsynchronousTypeToString(state.asynchronous_mode).c_str());
}

static void ValidateNVMLatency(
    const configuration& state) {
  if (state.nvm_latency < 0) {
    LOG_ERROR("Invalid nvm_latency :: %d", state.nvm_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("nvm_latency :: %d", state.nvm_latency);
}

static void ValidatePCOMMITLatency(
    const configuration& state) {
  if (state.pcommit_latency < 0) {
    LOG_ERROR("Invalid pcommit_latency :: %d", state.pcommit_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("pcommit_latency :: %d", state.pcommit_latency);
}

static void ValidateLogFileDir(
    configuration& state) {
  struct stat data_stat;

  // Assign log file dir based on logging type
  switch (state.logging_type) {
    // Log file on NVM
    case LOGGING_TYPE_NVM_WAL:
    case LOGGING_TYPE_NVM_WBL: {
      int status = stat(NVM_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = NVM_DIR;
      }
    } break;

    // Log file on SSD
    case LOGGING_TYPE_SSD_WAL:
    case LOGGING_TYPE_SSD_WBL: {
      int status = stat(SSD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = SSD_DIR;
      }
    } break;

    // Log file on HDD
    case LOGGING_TYPE_HDD_WAL:
    case LOGGING_TYPE_HDD_WBL: {
      int status = stat(HDD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = HDD_DIR;
      }
    } break;

    case LOGGING_TYPE_INVALID:
    default: {
      int status = stat(TMP_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = TMP_DIR;
      } else {
        throw Exception("Could not find temp directory : " +
                        std::string(TMP_DIR));
      }
    } break;
  }

  LOG_INFO("log_file_dir :: %s", state.log_file_dir.c_str());
}

void ParseArguments(int argc, char* argv[], configuration& state) {

  // Default Logger Values
  state.logging_type = LOGGING_TYPE_NVM_WAL;
  state.log_file_dir = TMP_DIR;
  state.data_file_size = 512;

  state.experiment_type = EXPERIMENT_TYPE_THROUGHPUT;
  state.wait_timeout = 200;
  state.benchmark_type = BENCHMARK_TYPE_YCSB;
  state.flush_mode = 2;
  state.nvm_latency = 0;
  state.pcommit_latency = 0;
  state.asynchronous_mode = ASYNCHRONOUS_TYPE_SYNC;

  // Default YCSB Values
  ycsb::state.scale_factor = 1;
  ycsb::state.duration = 1000;
  ycsb::state.column_count = 10;
  ycsb::state.update_ratio = 0.5;
  ycsb::state.backend_count = 2;
  ycsb::state.skew_factor = ycsb::SKEW_FACTOR_LOW;

  // Default Values
  tpcc::state.scale_factor = 1;
  tpcc::state.duration = 1000;
  tpcc::state.backend_count = 2;

  // Parse args
  while (1) {
    int idx = 0;
    // logger - a:e:f:hl:n:p:v:w:y:
    // ycsb   - b:c:d:k:s:u:
    // tpcc   - b:d:k:
    int c = getopt_long(argc, argv, "a:e:f:hl:n:p:v:w:y:b:c:d:k:s:u:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'a':
        state.asynchronous_mode = (AsynchronousType) atoi(optarg);
        break;
      case 'e':
        state.experiment_type = (ExperimentType)atoi(optarg);
        break;
      case 'f':
        state.data_file_size = atoi(optarg);
        break;
      case 'l':
        state.logging_type = (LoggingType)atoi(optarg);
        break;
      case 'n':
        state.nvm_latency = atoi(optarg);
        break;
      case 'p':
        state.pcommit_latency = atoi(optarg);
        break;
      case 'v':
        state.flush_mode = atoi(optarg);
        break;
      case 'w':
        state.wait_timeout = atoi(optarg);
        break;
      case 'y':
        state.benchmark_type = (BenchmarkType)atoi(optarg);
        break;

        // YCSB
      case 'b':
        ycsb::state.backend_count = atoi(optarg);
        tpcc::state.backend_count = atoi(optarg);
        break;
      case 'c':
        ycsb::state.column_count = atoi(optarg);
        break;
      case 'd':
        ycsb::state.duration = atoi(optarg);
        tpcc::state.duration = atoi(optarg);
        break;
      case 'k':
        ycsb::state.scale_factor = atoi(optarg);
        tpcc::state.scale_factor = atoi(optarg);
        break;
      case 's':
        ycsb::state.skew_factor = (ycsb::SkewFactor)atoi(optarg);
        break;
      case 'u':
        ycsb::state.update_ratio = atof(optarg);
        break;

      case 'h':
        Usage(stderr);
        ycsb::Usage(stderr);
        exit(EXIT_FAILURE);
        break;

      default:
        fprintf(stderr, "\nUnknown option: -%c-\n", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;
    }
  }

  // Print Logger configuration
  ValidateLoggingType(state);
  ValidateExperimentType(state);
  ValidateAsynchronousMode(state);
  ValidateBenchmarkType(state);
  ValidateDataFileSize(state);
  ValidateLogFileDir(state);
  ValidateWaitTimeout(state);
  ValidateFlushMode(state);
  ValidateNVMLatency(state);
  ValidatePCOMMITLatency(state);

  // Print YCSB configuration
  if(state.benchmark_type == BENCHMARK_TYPE_YCSB) {
    ycsb::ValidateScaleFactor(ycsb::state);
    ycsb::ValidateColumnCount(ycsb::state);
    ycsb::ValidateUpdateRatio(ycsb::state);
    ycsb::ValidateBackendCount(ycsb::state);
    ycsb::ValidateDuration(ycsb::state);
    ycsb::ValidateSkewFactor(ycsb::state);
  }
  // Print TPCC configuration
  else if(state.benchmark_type == BENCHMARK_TYPE_TPCC){
    tpcc::ValidateBackendCount(tpcc::state);
    tpcc::ValidateDuration(tpcc::state);
    tpcc::ValidateScaleFactor(tpcc::state);

    // Static TPCC parameters
    tpcc::state.warehouse_count = 4;                   // 10
    tpcc::state.item_count = 50000;                    // 100000
    tpcc::state.districts_per_warehouse = 4;           // 10
    tpcc::state.customers_per_district = 300;          // 3000
    tpcc::state.new_orders_per_district = 90;          // 900

  }

}

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