<commit_before>#pragma once

#include "indexer/feature_data.hpp"
#include "indexer/classificator.hpp"
#include "indexer/ftypes_matcher.hpp"

#include "base/string_utils.hpp"

#include "std/string.hpp"

class MetadataTagProcessor
{
  FeatureParams & m_params;

public:
  MetadataTagProcessor(FeatureParams &params)
  : m_params(params)
  {
  }

  bool operator() (string const & k, string const & v)
  {
    if (v.empty())
      return false;

    using feature::Metadata;
    Metadata & md = m_params.GetMetadata();

    if (k == "cuisine")
    {
      string const & value = ValidateAndFormat_cuisine(v);
      if (!value.empty())
        md.Add(Metadata::FMD_CUISINE, value);
    }
    else if (k == "phone" || k == "contact:phone")
    {
      string const & value = ValidateAndFormat_phone(v);
      if (!value.empty())
        md.Add(Metadata::FMD_PHONE_NUMBER, value);
    }
    else if (k == "stars")
    {
      string const & value = ValidateAndFormat_stars(v);
      if (!value.empty())
        md.Add(Metadata::FMD_STARS, value);
    }
    else if (k == "addr:postcode")
    {
      string const & value = ValidateAndFormat_postcode(v);
      if (!value.empty())
        md.Add(Metadata::FMD_POSTCODE, value);
    }
    else if (k == "url")
    {
      string const & value = ValidateAndFormat_url(v);
      if (!value.empty())
        md.Add(Metadata::FMD_URL, value);
    }
    else if (k == "website" || k == "contact:website")
    {
      string const & value = ValidateAndFormat_url(v);
      if (!value.empty())
        md.Add(Metadata::FMD_WEBSITE, value);
    }
    else if (k == "operator")
    {
      string const & value = ValidateAndFormat_operator(v);
      if (!value.empty())
        md.Add(Metadata::FMD_OPERATOR, value);
    }
    else if (k == "opening_hours")
    {
      string const & value = ValidateAndFormat_opening_hours(v);
      if (!value.empty())
        md.Add(Metadata::FMD_OPEN_HOURS, value);
    }
    else if (k == "ele")
    {
      string const & value = ValidateAndFormat_ele(v);
      if (!value.empty())
        md.Add(Metadata::FMD_ELE, value);
    }
    else if (k == "turn:lanes")
    {
      string const & value = ValidateAndFormat_turn_lanes(v);
      if (!value.empty())
        md.Add(Metadata::FMD_TURN_LANES, value);
    }
    else if (k == "turn:lanes:forward")
    {
      string const & value = ValidateAndFormat_turn_lanes_forward(v);
      if (!value.empty())
        md.Add(Metadata::FMD_TURN_LANES_FORWARD, value);
    }
    else if (k == "turn:lanes:backward")
    {
      string const & value = ValidateAndFormat_turn_lanes_backward(v);
      if (!value.empty())
        md.Add(Metadata::FMD_TURN_LANES_BACKWARD, value);
    }
    else if (k == "email" || k == "contact:email")
    {
      string const & value = ValidateAndFormat_email(v);
      if (!value.empty())
        md.Add(Metadata::FMD_EMAIL, value);
    }
    else if (k == "wikipedia")
    {
      string const & value = ValidateAndFormat_wikipedia(v);
      if (!value.empty())
        md.Add(Metadata::FMD_WIKIPEDIA, value);
    }
    return false;
  }

protected:
  /// Validation and formatting functions

  string ValidateAndFormat_stars(string const & v) const
  {
    if (v.empty())
      return string();

    // we accepting stars from 1 to 7
    if (v[0] <= '0' || v[0] > '7')
      return string();

    // ignore numbers large then 9
    if (v.size() > 1 && (v[1] >= '0' && v[1] <= '9'))
      return string();

    return string(1, v[0]);
  }

  string ValidateAndFormat_cuisine(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_operator(string const & v) const
  {
    static ftypes::IsATMChecker const IsATM;
    static ftypes::IsFuelStationChecker const IsFuelStation;

    if (!(IsATM(m_params.m_Types) || IsFuelStation(m_params.m_Types)))
      return string();

    return v;
  }
  string ValidateAndFormat_url(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_phone(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_opening_hours(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_ele(string const & v) const
  {
    static ftypes::IsPeakChecker const IsPeak;
    if (!IsPeak(m_params.m_Types))
      return string();
    double val = 0;
    if(!strings::to_double(v, val) || val == 0)
      return string();
    return v;
  }
  string ValidateAndFormat_turn_lanes(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_turn_lanes_forward(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_turn_lanes_backward(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_email(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_postcode(string const & v) const
  {
    return v;
  }

  // Special URL encoding for wikipedia:
  // Replaces special characters with %HH codes
  // And spaces with underscores.
  string WikiUrlEncode(string const & value) const
  {
    ostringstream escaped;
    escaped.fill('0');
    escaped << hex;

    for (auto const & c : value)
    {
      if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
        escaped << c;
      else if (c == ' ')
        escaped << '_';
      else
        escaped << '%' << std::uppercase << setw(2) << static_cast<int>(static_cast<unsigned char>(c));
    }

    return escaped.str();
  }

  string ValidateAndFormat_wikipedia(string const & v) const
  {
    // Find prefix before ':', shortest case: "lg:aa"
    string::size_type i = v.find(':');
    if (i == string::npos || i < 2 || i + 2 > v.length())
      return string();

    // URL encode lang:title, so URL can be reconstructed faster
    if (i <= 3 || v.substr(0, i) == "be-x-old")
      return v.substr(0, i + 1) + WikiUrlEncode(v.substr(i + 1));

    static string::size_type const minUrlPartLength = string("//be.wikipedia.org/wiki/AB").length();
    if (v[i+1] == '/' && i + minUrlPartLength < v.length())
    {
      // Convert URL to "lang:title"
      i += 3;
      string::size_type const j = v.find('.', i + 1);
      static string const wikiUrlPart = ".wikipedia.org/wiki/";
      if (j != string::npos && v.substr(j, wikiUrlPart.length()) == wikiUrlPart)
        return v.substr(i, j - i) + ":" + v.substr(j + wikiUrlPart.length());
    }
    return string();
  }

};
<commit_msg>[generator] More comments for wikipedia tags processing<commit_after>#pragma once

#include "indexer/feature_data.hpp"
#include "indexer/classificator.hpp"
#include "indexer/ftypes_matcher.hpp"

#include "base/string_utils.hpp"

#include "std/string.hpp"

class MetadataTagProcessor
{
  FeatureParams & m_params;

public:
  MetadataTagProcessor(FeatureParams &params)
  : m_params(params)
  {
  }

  bool operator() (string const & k, string const & v)
  {
    if (v.empty())
      return false;

    using feature::Metadata;
    Metadata & md = m_params.GetMetadata();

    if (k == "cuisine")
    {
      string const & value = ValidateAndFormat_cuisine(v);
      if (!value.empty())
        md.Add(Metadata::FMD_CUISINE, value);
    }
    else if (k == "phone" || k == "contact:phone")
    {
      string const & value = ValidateAndFormat_phone(v);
      if (!value.empty())
        md.Add(Metadata::FMD_PHONE_NUMBER, value);
    }
    else if (k == "stars")
    {
      string const & value = ValidateAndFormat_stars(v);
      if (!value.empty())
        md.Add(Metadata::FMD_STARS, value);
    }
    else if (k == "addr:postcode")
    {
      string const & value = ValidateAndFormat_postcode(v);
      if (!value.empty())
        md.Add(Metadata::FMD_POSTCODE, value);
    }
    else if (k == "url")
    {
      string const & value = ValidateAndFormat_url(v);
      if (!value.empty())
        md.Add(Metadata::FMD_URL, value);
    }
    else if (k == "website" || k == "contact:website")
    {
      string const & value = ValidateAndFormat_url(v);
      if (!value.empty())
        md.Add(Metadata::FMD_WEBSITE, value);
    }
    else if (k == "operator")
    {
      string const & value = ValidateAndFormat_operator(v);
      if (!value.empty())
        md.Add(Metadata::FMD_OPERATOR, value);
    }
    else if (k == "opening_hours")
    {
      string const & value = ValidateAndFormat_opening_hours(v);
      if (!value.empty())
        md.Add(Metadata::FMD_OPEN_HOURS, value);
    }
    else if (k == "ele")
    {
      string const & value = ValidateAndFormat_ele(v);
      if (!value.empty())
        md.Add(Metadata::FMD_ELE, value);
    }
    else if (k == "turn:lanes")
    {
      string const & value = ValidateAndFormat_turn_lanes(v);
      if (!value.empty())
        md.Add(Metadata::FMD_TURN_LANES, value);
    }
    else if (k == "turn:lanes:forward")
    {
      string const & value = ValidateAndFormat_turn_lanes_forward(v);
      if (!value.empty())
        md.Add(Metadata::FMD_TURN_LANES_FORWARD, value);
    }
    else if (k == "turn:lanes:backward")
    {
      string const & value = ValidateAndFormat_turn_lanes_backward(v);
      if (!value.empty())
        md.Add(Metadata::FMD_TURN_LANES_BACKWARD, value);
    }
    else if (k == "email" || k == "contact:email")
    {
      string const & value = ValidateAndFormat_email(v);
      if (!value.empty())
        md.Add(Metadata::FMD_EMAIL, value);
    }
    else if (k == "wikipedia")
    {
      string const & value = ValidateAndFormat_wikipedia(v);
      if (!value.empty())
        md.Add(Metadata::FMD_WIKIPEDIA, value);
    }
    return false;
  }

protected:
  /// Validation and formatting functions

  string ValidateAndFormat_stars(string const & v) const
  {
    if (v.empty())
      return string();

    // we accepting stars from 1 to 7
    if (v[0] <= '0' || v[0] > '7')
      return string();

    // ignore numbers large then 9
    if (v.size() > 1 && (v[1] >= '0' && v[1] <= '9'))
      return string();

    return string(1, v[0]);
  }

  string ValidateAndFormat_cuisine(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_operator(string const & v) const
  {
    static ftypes::IsATMChecker const IsATM;
    static ftypes::IsFuelStationChecker const IsFuelStation;

    if (!(IsATM(m_params.m_Types) || IsFuelStation(m_params.m_Types)))
      return string();

    return v;
  }
  string ValidateAndFormat_url(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_phone(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_opening_hours(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_ele(string const & v) const
  {
    static ftypes::IsPeakChecker const IsPeak;
    if (!IsPeak(m_params.m_Types))
      return string();
    double val = 0;
    if(!strings::to_double(v, val) || val == 0)
      return string();
    return v;
  }
  string ValidateAndFormat_turn_lanes(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_turn_lanes_forward(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_turn_lanes_backward(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_email(string const & v) const
  {
    return v;
  }
  string ValidateAndFormat_postcode(string const & v) const
  {
    return v;
  }

  // Special URL encoding for wikipedia:
  // Replaces special characters with %HH codes
  // And spaces with underscores.
  string WikiUrlEncode(string const & value) const
  {
    ostringstream escaped;
    escaped.fill('0');
    escaped << hex;

    for (auto const & c : value)
    {
      if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
        escaped << c;
      else if (c == ' ')
        escaped << '_';
      else
        escaped << '%' << std::uppercase << setw(2) << static_cast<int>(static_cast<unsigned char>(c));
    }

    return escaped.str();
  }

  string ValidateAndFormat_wikipedia(string const & v) const
  {
    // Find prefix before ':', shortest case: "lg:aa"
    string::size_type i = v.find(':');
    if (i == string::npos || i < 2 || i + 2 > v.length())
      return string();

    // URL encode lang:title (lang is at most 3 chars), so URL can be reconstructed faster
    if (i <= 3 || v.substr(0, i) == "be-x-old")
      return v.substr(0, i + 1) + WikiUrlEncode(v.substr(i + 1));

    static string::size_type const minUrlPartLength = string("//be.wikipedia.org/wiki/AB").length();
    if (v[i+1] == '/' && i + minUrlPartLength < v.length())
    {
      // Convert URL to "lang:title"
      i += 3; // skip "://"
      string::size_type const j = v.find('.', i + 1);
      static string const wikiUrlPart = ".wikipedia.org/wiki/";
      if (j != string::npos && v.substr(j, wikiUrlPart.length()) == wikiUrlPart)
        return v.substr(i, j - i) + ":" + v.substr(j + wikiUrlPart.length());
    }
    return string();
  }

};
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include "YetAnotherRegularExpressionEngine.h"
#ifdef _DEBUG
#include <conio.h>
#endif
#if defined(_MSC_VER) && (_M_IX86 >= 500 || defined(_M_AMD64))
#include <intrin.h>
#pragma intrinsic(__rdtsc)
#else
#include <ctime>
#endif
void expect(const char *expr, bool ex, bool ac){
	const char* e = ex ? "true" : "false";
	const char *a = ac ? "true" : "false";
	if (ex == ac){
		std::cout << "passed: " << expr << " = " << e << std::endl;
	}
	else{
		std::cout << "!!error: expect " << expr << " = " << e << ", get " << a << " instead." << std::endl;
	}
}
class TestException{
	FA2 fa;
	std::string re;
public:
	TestException(const char *re) :fa(re), re(re){}
	TestException& operator ,(const char *p){
		try{
			fa << p;
		}
		catch (FA1::SyntaxErrorException&){
			std::cout << "passed: expected exception received for RE /" << re << "/" << std::endl;
			return *this;
		}
		std::cout << "!!error: expected exception was not caught." << std::endl;
		return *this;
	}
};
class Expect{
	bool assert;
public:
	explicit Expect(bool b) :assert(b){}
	bool GetAssert(){ return assert; }
};
class Test{
	bool assert;
	FA1 faCompare;
	FA2 fa;
public:
	Test(const char *re, Expect e) :fa(re), faCompare(re), assert(e.GetAssert()){
		std::cout << "Testing RE /" << re << "/ :" << std::endl;
	}
	Test& operator ,(const char*p){
		using namespace std;
		if (*p == '\0'){
			expect("<Empty String>", assert, fa << p);
		}
		else{
			expect(p, assert, fa << p);
		}
#if defined(_MSC_VER) && (_M_IX86 >= 500 || defined(_M_AMD64))
		unsigned __int64 start;
		start = __rdtsc();
		for (int i = 0; i < 9999; ++i){
			faCompare << p;
		}
		unsigned __int64 time1 = __rdtsc() - start;
		cout << "nfa took " << time1 << " clock cycles to calulate for 9999 times" << endl;
		start = __rdtsc();
		for (int i = 0; i < 9999; ++i){
			fa << p;
		}
		unsigned __int64 time2 = __rdtsc() - start;
		cout << "dfa took " << time2 << " clock cycles to calulate for 9999 times" << endl;
		cout << "factor: " << time1 / time2 << endl;
#else
		time_t tm;
		tm = time(0);
		for (int i = 0; i < 1000000; ++i){
			faCompare << p;
		}
		cout << "nfa took " << (time(0) - tm) << " seconds to calulate for e6 times" << endl;
		tm = time(0);
		for (int i = 0; i < 1000000; ++i){
			fa << p;
		}
		cout << "dfa took " << (time(0) - tm) << " seconds to calulate for e6 times" << endl;
#endif
		return *this;
	}
};
int main(){
	Test("", Expect(true)), "";
	Test("", Expect(false)), "a";
	Test("a", Expect(true)), "a";
	Test("a", Expect(false)), "b", "abc", "";
	Test("ab", Expect(true)), "ab";
	Test("ab", Expect(false)), "", "a", "b", "c";
	Test("a|b", Expect(true)), "a", "b";
	Test("a|b", Expect(false)), "abc", "ab", "";
	Test("ab|c", Expect(true)), "ab", "c";
	Test("ab|c", Expect(false)), "a", "b", "abc";
	Test("ab|a", Expect(true)), "ab", "a";
	Test("ab|a", Expect(false)), "b", "c", "abc";
	Test("a|bc", Expect(true)), "a", "bc";
	Test("a|bc", Expect(false)), "ab", "c", "";
	Test("a*", Expect(true)), "", "a", "aaa";
	Test("a*", Expect(false)), "b", "ab", "ba";
	Test("ab*", Expect(true)), "a", "abb";
	Test("ab*", Expect(false)), "b", "bb", "bc", "abc", "";
	Test("a*b", Expect(true)), "b", "aaab", "ab";
	Test("a*b", Expect(false)), "aa", "ac", "";
	Test("a*ab", Expect(true)), "ab", "aab", "aaaab";
	Test("a*ab", Expect(false)), "a", "b", "c";
	Test("aa*b", Expect(true)), "ab", "aab", "aaaab";
	Test("aa*b", Expect(false)), "a", "b", "c";
	Test("a*|b", Expect(true)), "aaa", "b", "";
	Test("a*|b", Expect(false)), "abc", "ba", "cb", "ab";
	Test("a|b*", Expect(true)), "a", "bb", "";
	Test("a|b*", Expect(false)), "aa", "ab", "bc";
	Test("a|b|c", Expect(true)), "a", "b", "c";
	Test("a|b|c", Expect(false)), "ab", "d", "";
	Test("a|", Expect(true)), "a", "";
	Test("a|", Expect(false)), "b", "aa";
	Test("|a", Expect(true)), "a", "";
	Test("|a", Expect(false)), "b";
	Test("||", Expect(true)), "";
	Test("||", Expect(false)), "a";
	TestException("*"), "", "a", "b";
	TestException("|*"), "", "a", "b";
	TestException("**"), "", "a", "b";
	TestException("*|*"), "", "a", "b";
	TestException("*||*"), "", "a", "b";
	TestException("||*"), "", "a", "b";
#ifdef _DEBUG
#ifdef _MSC_VER
	_CrtCheckMemory();
	_CrtDumpMemoryLeaks();
#endif
	_getch();
#endif
	return 0;
}
<commit_msg>Minor cleanning<commit_after>#include <iostream>
#include <string>
#include "YetAnotherRegularExpressionEngine.h"
#ifdef _DEBUG
#include <conio.h>
#endif
#if defined(_MSC_VER) && (_M_IX86 >= 500 || defined(_M_AMD64))
#include <intrin.h>
#pragma intrinsic(__rdtsc)
#else
#include <limits>
#include <ctime>
#endif
void expect(const char *expr, bool ex, bool ac){
	const char* e = ex ? "true" : "false";
	const char *a = ac ? "true" : "false";
	if (ex == ac){
		std::cout << "passed: " << expr << " = " << e << std::endl;
	}
	else{
		std::cout << "!!error: expect " << expr << " = " << e << ", get " << a << " instead." << std::endl;
	}
}
class TestException{
	FA2 fa;
	std::string re;
public:
	TestException(const char *re) :fa(re), re(re){}
	TestException& operator ,(const char *p){
		try{
			fa << p;
		}
		catch (FA1::SyntaxErrorException&){
			std::cout << "passed: expected exception received for RE /" << re << "/" << std::endl;
			return *this;
		}
		std::cout << "!!error: expected exception was not caught." << std::endl;
		return *this;
	}
};
class Expect{
	bool assert;
public:
	explicit Expect(bool b) :assert(b){}
	bool GetAssert(){ return assert; }
};
class Test{
	bool assert;
	FA1 faCompare;
	FA2 fa;
public:
	Test(const char *re, Expect e) :fa(re), faCompare(re), assert(e.GetAssert()){
		std::cout << "Testing RE /" << re << "/ :" << std::endl;
	}
	Test& operator ,(const char*p){
		using namespace std;
		if (*p == '\0'){
			expect("<Empty String>", assert, fa << p);
		}
		else{
			expect(p, assert, fa << p);
		}
#if defined(_MSC_VER) && (_M_IX86 >= 500 || defined(_M_AMD64))
		unsigned __int64 start;
		start = __rdtsc();
		for (int i = 0; i < 9999; ++i){
			faCompare << p;
		}
		unsigned __int64 time1 = __rdtsc() - start;
		cout << "nfa took " << time1 << " clock cycles to calulate for 9999 times" << endl;
		start = __rdtsc();
		for (int i = 0; i < 9999; ++i){
			fa << p;
		}
		unsigned __int64 time2 = __rdtsc() - start;
		cout << "dfa took " << time2 << " clock cycles to calulate for 9999 times" << endl;
		cout << "factor: " << time1 / time2 << endl;
#else
		time_t tm;
		tm = time(0);
		for (int i = 0; i < 1000000; ++i){
			faCompare << p;
		}
		cout << "nfa took " << (time(0) - tm) << " seconds to calulate for e6 times" << endl;
		tm = time(0);
		for (int i = 0; i < 1000000; ++i){
			fa << p;
		}
		cout << "dfa took " << (time(0) - tm) << " seconds to calulate for e6 times" << endl;
#endif
		return *this;
	}
};
int main(){
	Test("", Expect(true)), "";
	Test("", Expect(false)), "a";
	Test("a", Expect(true)), "a";
	Test("a", Expect(false)), "b", "abc", "";
	Test("ab", Expect(true)), "ab";
	Test("ab", Expect(false)), "", "a", "b", "c";
	Test("a|b", Expect(true)), "a", "b";
	Test("a|b", Expect(false)), "abc", "ab", "";
	Test("ab|c", Expect(true)), "ab", "c";
	Test("ab|c", Expect(false)), "a", "b", "abc";
	Test("ab|a", Expect(true)), "ab", "a";
	Test("ab|a", Expect(false)), "b", "c", "abc";
	Test("a|bc", Expect(true)), "a", "bc";
	Test("a|bc", Expect(false)), "ab", "c", "";
	Test("a*", Expect(true)), "", "a", "aaa";
	Test("a*", Expect(false)), "b", "ab", "ba";
	Test("ab*", Expect(true)), "a", "abb";
	Test("ab*", Expect(false)), "b", "bb", "bc", "abc", "";
	Test("a*b", Expect(true)), "b", "aaab", "ab";
	Test("a*b", Expect(false)), "aa", "ac", "";
	Test("a*ab", Expect(true)), "ab", "aab", "aaaab";
	Test("a*ab", Expect(false)), "a", "b", "c";
	Test("aa*b", Expect(true)), "ab", "aab", "aaaab";
	Test("aa*b", Expect(false)), "a", "b", "c";
	Test("a*|b", Expect(true)), "aaa", "b", "";
	Test("a*|b", Expect(false)), "abc", "ba", "cb", "ab";
	Test("a|b*", Expect(true)), "a", "bb", "";
	Test("a|b*", Expect(false)), "aa", "ab", "bc";
	Test("a|b|c", Expect(true)), "a", "b", "c";
	Test("a|b|c", Expect(false)), "ab", "d", "";
	Test("a|", Expect(true)), "a", "";
	Test("a|", Expect(false)), "b", "aa";
	Test("|a", Expect(true)), "a", "";
	Test("|a", Expect(false)), "b";
	Test("||", Expect(true)), "";
	Test("||", Expect(false)), "a";
	TestException("*"), "", "a", "b";
	TestException("|*"), "", "a", "b";
	TestException("**"), "", "a", "b";
	TestException("*|*"), "", "a", "b";
	TestException("*||*"), "", "a", "b";
	TestException("||*"), "", "a", "b";
#ifdef _DEBUG
#ifdef _MSC_VER
	_CrtCheckMemory();
	_CrtDumpMemoryLeaks();
#endif
	_getch();
#endif
	return 0;
}
<|endoftext|>


<commit_before>#include "../IRCBot/include/command-interface.hpp"
#include "../IRCBot/include/bot.hpp"
#include "../IRCBot/include/packet.hpp"

#include "./include/http.hpp"
#include "./include/json.hpp"

#include <string>
#include <stdexcept>

static void strip_line_endings(std::string& str);
static std::string get_nth_result(const std::string& query, size_t n);

class UrbanCommand : protected IRC::CommandInterface {

	static const size_t MAX_DEF_LEN = 420; /* Maximum character length of definition and example. */

  public:

	UrbanCommand()
		: CommandInterface("@urban ", "checks urban dictionary for a definition.") {}

	void run(const IRC::Packet& p) {

		std::string query = p.content.substr(this->trigger_string.length());

		size_t n = 1, loc;
		if ((loc = query.find(" ")) != std::string::npos) {
			try {
				n = (size_t)std::stoi(query);
				query = query.substr(loc + 1);
			} catch (...) {
				n = 1;
			}
		}

		// std::string def = get_first_result( query );
		std::string def = get_nth_result( query , n );

		if (def.length() >= MAX_DEF_LEN) {
			p.reply("Grr. See for yourself. https://www.urbandictionary.com/define.php?term=" + MyHTTP::uri_encode(query));
		} else if (!def.empty()) {
			p.reply(def);
		}
	}

};

static std::string get_nth_result(const std::string& query, size_t n) {
	std::string res = "Unknown.";

	if (n != 0) /* move n from 1-based to 0-based. */
		--n;    /* but only if n isn't 0 already (avoid underflow) */

	try {
		nlohmann::json data = nlohmann::json::parse(MyHTTP::get("http://api.urbandictionary.com/v0/define?term=" + MyHTTP::uri_encode(query)));
		if (data["result_type"] == "exact") {
			if (n >= data["list"].size()) {
				res = "No " + n;
				res += "th entry for " + query; // one-liner wasn't working :|
				return res;
			}
			res = data["list"].at(n)["definition"];

			std::string example = data["list"].at(n)["example"].get<std::string>();
			if (!example.empty())
				res += " [*] Ex. \x1D" + example + "\x1D";

			strip_line_endings(res);
		}
	} catch (std::exception& e) {
		std::cerr << "Failed in Urban::get_first_result: " << e.what() << '\n';
	}
	return res;
}

static void strip_line_endings(std::string& str) {
	size_t loc = 0;
	while ( (loc = str.find("\r\n", loc) ) != std::string::npos) {
		str.replace(loc, 2, " ");
	}
}

extern "C" IRC::CommandInterface* maker(IRC::Bot *b = nullptr) {
	return (IRC::CommandInterface*)(new UrbanCommand);
}
<commit_msg>fix critical error<commit_after>#include "../IRCBot/include/command-interface.hpp"
#include "../IRCBot/include/bot.hpp"
#include "../IRCBot/include/packet.hpp"

#include "./include/http.hpp"
#include "./include/json.hpp"

#include <string>
#include <stdexcept>

static void strip_line_endings(std::string& str);
static std::string get_nth_result(const std::string& query, int n);

class UrbanCommand : protected IRC::CommandInterface {

	static const size_t MAX_DEF_LEN = 420; /* Maximum character length of definition and example. */

  public:

	UrbanCommand()
		: CommandInterface("@urban ", "checks urban dictionary for a definition.") {}

	void run(const IRC::Packet& p) {

		std::string query = p.content.substr(this->trigger_string.length());

		size_t loc;
		int n = 1;
		if ((loc = query.find(" ")) != std::string::npos) {
			try {
				n = std::stoi(query);
				query = query.substr(loc + 1);
			} catch (...) {
				n = 1;
			}
		}

		// std::string def = get_first_result( query );
		std::string def = get_nth_result( query , n );

		if (def.length() >= MAX_DEF_LEN) {
			p.reply("Grr. See for yourself. https://www.urbandictionary.com/define.php?term=" + MyHTTP::uri_encode(query));
		} else if (!def.empty()) {
			p.reply(def);
		}
	}

};

static std::string get_nth_result(const std::string& query, int n) {
	std::string res = "Unknown.";

	n = std::max(0, n-1);

	try {
		nlohmann::json data = nlohmann::json::parse(MyHTTP::get("http://api.urbandictionary.com/v0/define?term=" + MyHTTP::uri_encode(query)));
		if (data["result_type"] == "exact") {
			if (n >= data["list"].size()) {
				res = "No " + n;
				res += "th entry for " + query; // one-liner wasn't working :|
				return res;
			}
			res = data["list"].at(n)["definition"];

			std::string example = data["list"].at(n)["example"].get<std::string>();
			if (!example.empty())
				res += " [*] Ex. \x1D" + example + "\x1D";

			strip_line_endings(res);
		}
	} catch (std::exception& e) {
		std::cerr << "Failed in Urban::get_first_result: " << e.what() << '\n';
	}
	return res;
}

static void strip_line_endings(std::string& str) {
	size_t loc = 0;
	while ( (loc = str.find("\r\n", loc) ) != std::string::npos) {
		str.replace(loc, 2, " ");
	}
}

extern "C" IRC::CommandInterface* maker(IRC::Bot *b = nullptr) {
	return (IRC::CommandInterface*)(new UrbanCommand);
}
<|endoftext|>


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

#include <iostream>

#include "common/logger.h"
#include "common/macros.h"
#include "index/btree_index.h"
#include "index/bwtree_index.h"
#include "index/index_factory.h"
#include "index/index_key.h"
#include "type/types.h"

namespace peloton {
namespace index {

Index *IndexFactory::GetIndex(IndexMetadata *metadata) {
  LOG_TRACE("Creating index %s", metadata->GetName().c_str());

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();
  LOG_TRACE("key_size : %d", key_size);
  LOG_TRACE("Indexed column count: %ld",
            metadata->key_schema->GetIndexedColumns().size());

  // Check whether the index key only has ints.
  // If so, then we can rock a specialized IntsKeyComparator
  // that is faster than the GenericComparator
  bool ints_only = false; // FIXME: Re-enable this once the new IntsKey is working
  for (auto column : metadata->key_schema->GetColumns()) {
    auto col_type = column.GetType();
    if (col_type != type::Type::TINYINT && col_type != type::Type::SMALLINT &&
        col_type != type::Type::INTEGER && col_type != type::Type::BIGINT) {
      ints_only = false;
      break;
    }
  }  // FOR

  // If we want to use a specialized IntsKey template, make sure that
  // we are not longer than the largest IntsKey that we have
  if (ints_only && key_size > sizeof(uint64_t) * INTSKEY_MAX_SLOTS) {
    ints_only = false;
  }

  auto index_type = metadata->GetIndexMethodType();
  Index *index = nullptr;
  LOG_TRACE("Index type : %d", index_type);

  // -----------------------
  // B+TREE
  // -----------------------
  if (index_type == INDEX_TYPE_BTREE) {
    if (ints_only) {
      index = IndexFactory::GetBTreeIntsKeyIndex(metadata);
    } else {
      index = IndexFactory::GetBTreeGenericKeyIndex(metadata);
    }

    // -----------------------
    // BW-TREE
    // -----------------------
  } else if (index_type == INDEX_TYPE_BWTREE) {
    if (ints_only) {
      index = IndexFactory::GetBwTreeIntsKeyIndex(metadata);
    } else {
      index = IndexFactory::GetBwTreeGenericKeyIndex(metadata);
    }

    // -----------------------
    // ERROR
    // -----------------------
  } else {
    throw IndexException("Unsupported index scheme.");
  }
  PL_ASSERT(index != nullptr);

  return (index);
}

Index *IndexFactory::GetBTreeIntsKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= sizeof(uint64_t)) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<1>";
#endif
    index = new BTreeIndex<CompactIntegerKey<1>, ItemPointer *, IntsComparator<1>,
                           IntsEqualityChecker<1>>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 2) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<2>";
#endif
    index = new BTreeIndex<CompactIntegerKey<2>, ItemPointer *, IntsComparator<2>,
                           IntsEqualityChecker<2>>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 3) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<3>";
#endif
    index = new BTreeIndex<CompactIntegerKey<3>, ItemPointer *, IntsComparator<3>,
                           IntsEqualityChecker<3>>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<4>";
#endif
    index = new BTreeIndex<CompactIntegerKey<4>, ItemPointer *, IntsComparator<4>,
                           IntsEqualityChecker<4>>(metadata);
  } else {
    throw IndexException("Unsupported IntsKey scheme");
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

Index *IndexFactory::GetBTreeGenericKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<4>";
#endif
    index = new BTreeIndex<GenericKey<4>, ItemPointer *, GenericComparator<4>,
                           GenericEqualityChecker<4>>(metadata);
  } else if (key_size <= 8) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<8>";
#endif
    index = new BTreeIndex<GenericKey<8>, ItemPointer *, GenericComparator<8>,
                           GenericEqualityChecker<8>>(metadata);
  } else if (key_size <= 16) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<16>";
#endif
    index = new BTreeIndex<GenericKey<16>, ItemPointer *, GenericComparator<16>,
                           GenericEqualityChecker<16>>(metadata);
  } else if (key_size <= 64) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<64>";
#endif
    index = new BTreeIndex<GenericKey<64>, ItemPointer *, GenericComparator<64>,
                           GenericEqualityChecker<64>>(metadata);
  } else if (key_size <= 256) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<256>";
#endif
    index =
        new BTreeIndex<GenericKey<256>, ItemPointer *, GenericComparator<256>,
                       GenericEqualityChecker<256>>(metadata);
  } else {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "TupleKey";
#endif
    index = new BTreeIndex<TupleKey, ItemPointer *, TupleKeyComparator,
                           TupleKeyEqualityChecker>(metadata);
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

Index *IndexFactory::GetBwTreeIntsKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= sizeof(uint64_t)) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<1>";
#endif
    index =
        new BWTreeIndex<CompactIntegerKey<1>, ItemPointer *, IntsComparator<1>,
                        IntsEqualityChecker<1>, IntsHasher<1>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 2) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<2>";
#endif
    index =
        new BWTreeIndex<CompactIntegerKey<2>, ItemPointer *, IntsComparator<2>,
                        IntsEqualityChecker<2>, IntsHasher<2>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 3) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<3>";
#endif
    index =
        new BWTreeIndex<CompactIntegerKey<3>, ItemPointer *, IntsComparator<3>,
                        IntsEqualityChecker<3>, IntsHasher<3>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<4>";
#endif
    index =
        new BWTreeIndex<CompactIntegerKey<4>, ItemPointer *, IntsComparator<4>,
                        IntsEqualityChecker<4>, IntsHasher<4>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else {
    throw IndexException("Unsupported IntsKey scheme");
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

Index *IndexFactory::GetBwTreeGenericKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<4>";
#endif
    index =
        new BWTreeIndex<GenericKey<4>, ItemPointer *, GenericComparator<4>,
                        GenericEqualityChecker<4>, GenericHasher<4>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 8) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<8>";
#endif
    index =
        new BWTreeIndex<GenericKey<8>, ItemPointer *, GenericComparator<8>,
                        GenericEqualityChecker<8>, GenericHasher<8>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 16) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<16>";
#endif
    index =
        new BWTreeIndex<GenericKey<16>, ItemPointer *, GenericComparator<16>,
                        GenericEqualityChecker<16>, GenericHasher<16>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 64) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<64>";
#endif
    index =
        new BWTreeIndex<GenericKey<64>, ItemPointer *, GenericComparator<64>,
                        GenericEqualityChecker<64>, GenericHasher<64>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 256) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<256>";
#endif
    index =
        new BWTreeIndex<GenericKey<256>, ItemPointer *, GenericComparator<256>,
                        GenericEqualityChecker<256>, GenericHasher<256>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "TupleKey";
#endif
    index =
        new BWTreeIndex<TupleKey, ItemPointer *, TupleKeyComparator,
                        TupleKeyEqualityChecker, TupleKeyHasher,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

std::string IndexFactory::GetInfo(IndexMetadata *metadata,
                                  std::string comparatorType) {
  std::ostringstream os;
  os << "Index '" << metadata->GetName() << "' => "
     << IndexTypeToString(metadata->GetIndexMethodType())
     << "::" << comparatorType << "(";
  bool first = true;
  for (auto column : metadata->key_schema->GetColumns()) {
    if (first == false) os << ", ";
    os << column.GetName();
    first = false;
  }
  os << ")";
  return (os.str());
}

}  // End index namespace
}  // End peloton namespace
<commit_msg>Change class name in index factory<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// index_factory.cpp
//
// Identification: src/index/index_factory.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <iostream>

#include "common/logger.h"
#include "common/macros.h"
#include "index/btree_index.h"
#include "index/bwtree_index.h"
#include "index/index_factory.h"
#include "index/index_key.h"
#include "type/types.h"

namespace peloton {
namespace index {

Index *IndexFactory::GetIndex(IndexMetadata *metadata) {
  LOG_TRACE("Creating index %s", metadata->GetName().c_str());

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();
  LOG_TRACE("key_size : %d", key_size);
  LOG_TRACE("Indexed column count: %ld",
            metadata->key_schema->GetIndexedColumns().size());

  // Check whether the index key only has ints.
  // If so, then we can rock a specialized IntsKeyComparator
  // that is faster than the GenericComparator
  bool ints_only = false; // FIXME: Re-enable this once the new IntsKey is working
  for (auto column : metadata->key_schema->GetColumns()) {
    auto col_type = column.GetType();
    if (col_type != type::Type::TINYINT && col_type != type::Type::SMALLINT &&
        col_type != type::Type::INTEGER && col_type != type::Type::BIGINT) {
      ints_only = false;
      break;
    }
  }  // FOR

  // If we want to use a specialized IntsKey template, make sure that
  // we are not longer than the largest IntsKey that we have
  if (ints_only && key_size > sizeof(uint64_t) * INTSKEY_MAX_SLOTS) {
    ints_only = false;
  }

  auto index_type = metadata->GetIndexMethodType();
  Index *index = nullptr;
  LOG_TRACE("Index type : %d", index_type);

  // -----------------------
  // B+TREE
  // -----------------------
  if (index_type == INDEX_TYPE_BTREE) {
    if (ints_only) {
      index = IndexFactory::GetBTreeIntsKeyIndex(metadata);
    } else {
      index = IndexFactory::GetBTreeGenericKeyIndex(metadata);
    }

    // -----------------------
    // BW-TREE
    // -----------------------
  } else if (index_type == INDEX_TYPE_BWTREE) {
    if (ints_only) {
      index = IndexFactory::GetBwTreeIntsKeyIndex(metadata);
    } else {
      index = IndexFactory::GetBwTreeGenericKeyIndex(metadata);
    }

    // -----------------------
    // ERROR
    // -----------------------
  } else {
    throw IndexException("Unsupported index scheme.");
  }
  PL_ASSERT(index != nullptr);

  return (index);
}

Index *IndexFactory::GetBTreeIntsKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= sizeof(uint64_t)) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<1>";
#endif
    index = new BTreeIndex<CompactIntegerKey<1>,
                           ItemPointer *,
                           CompactIntsComparator<1>,
                           CompactIntsEqualityChecker<1>>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 2) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<2>";
#endif
    index = new BTreeIndex<CompactIntegerKey<2>,
                           ItemPointer *,
                           CompactIntsComparator<2>,
                           CompactIntsEqualityChecker<2>>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 3) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<3>";
#endif
    index = new BTreeIndex<CompactIntegerKey<3>,
                           ItemPointer *,
                           CompactIntsComparator<3>,
                           CompactIntsEqualityChecker<3>>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<4>";
#endif
    index = new BTreeIndex<CompactIntegerKey<4>,
                           ItemPointer *,
                           CompactIntsComparator<4>,
                           CompactIntsEqualityChecker<4>>(metadata);
  } else {
    throw IndexException("Unsupported IntsKey scheme");
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

Index *IndexFactory::GetBTreeGenericKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<4>";
#endif
    index = new BTreeIndex<GenericKey<4>, ItemPointer *, GenericComparator<4>,
                           GenericEqualityChecker<4>>(metadata);
  } else if (key_size <= 8) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<8>";
#endif
    index = new BTreeIndex<GenericKey<8>, ItemPointer *, GenericComparator<8>,
                           GenericEqualityChecker<8>>(metadata);
  } else if (key_size <= 16) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<16>";
#endif
    index = new BTreeIndex<GenericKey<16>, ItemPointer *, GenericComparator<16>,
                           GenericEqualityChecker<16>>(metadata);
  } else if (key_size <= 64) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<64>";
#endif
    index = new BTreeIndex<GenericKey<64>, ItemPointer *, GenericComparator<64>,
                           GenericEqualityChecker<64>>(metadata);
  } else if (key_size <= 256) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<256>";
#endif
    index =
        new BTreeIndex<GenericKey<256>, ItemPointer *, GenericComparator<256>,
                       GenericEqualityChecker<256>>(metadata);
  } else {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "TupleKey";
#endif
    index = new BTreeIndex<TupleKey, ItemPointer *, TupleKeyComparator,
                           TupleKeyEqualityChecker>(metadata);
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

Index *IndexFactory::GetBwTreeIntsKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= sizeof(uint64_t)) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<1>";
#endif
    index = \
        new BWTreeIndex<CompactIntegerKey<1>,
                        ItemPointer *,
                        CompactIntsComparator<1>,
                        CompactIntsEqualityChecker<1>,
                        CompactIntsHasher<1>,
                        ItemPointerComparator,
                        ItemPointerHashFunc>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 2) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<2>";
#endif
    index = \
        new BWTreeIndex<CompactIntegerKey<2>,
                        ItemPointer *,
                        CompactIntsComparator<2>,
                        CompactIntsEqualityChecker<2>,
                        CompactIntsHasher<2>,
                        ItemPointerComparator,
                        ItemPointerHashFunc>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 3) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<3>";
#endif
    index = \
        new BWTreeIndex<CompactIntegerKey<3>,
                        ItemPointer *,
                        CompactIntsComparator<3>,
                        CompactIntsEqualityChecker<3>,
                        CompactIntsHasher<3>,
                        ItemPointerComparator,
                        ItemPointerHashFunc>(metadata);
  } else if (key_size <= sizeof(uint64_t) * 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "CompactIntegerKey<4>";
#endif
    index = \
        new BWTreeIndex<CompactIntegerKey<4>,
                        ItemPointer *,
                        CompactIntsComparator<4>,
                        CompactIntsEqualityChecker<4>,
                        CompactIntsHasher<4>,
                        ItemPointerComparator,
                        ItemPointerHashFunc>(metadata);
  } else {
    throw IndexException("Unsupported IntsKey scheme");
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

Index *IndexFactory::GetBwTreeGenericKeyIndex(IndexMetadata *metadata) {
  // Our new Index!
  Index *index = nullptr;

  // The size of the key in bytes
  const auto key_size = metadata->key_schema->GetLength();

// Debug Output
#ifdef LOG_TRACE_ENABLED
  std::string comparatorType;
#endif

  if (key_size <= 4) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<4>";
#endif
    index =
        new BWTreeIndex<GenericKey<4>, ItemPointer *, GenericComparator<4>,
                        GenericEqualityChecker<4>, GenericHasher<4>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 8) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<8>";
#endif
    index =
        new BWTreeIndex<GenericKey<8>, ItemPointer *, GenericComparator<8>,
                        GenericEqualityChecker<8>, GenericHasher<8>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 16) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<16>";
#endif
    index =
        new BWTreeIndex<GenericKey<16>, ItemPointer *, GenericComparator<16>,
                        GenericEqualityChecker<16>, GenericHasher<16>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 64) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<64>";
#endif
    index =
        new BWTreeIndex<GenericKey<64>, ItemPointer *, GenericComparator<64>,
                        GenericEqualityChecker<64>, GenericHasher<64>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else if (key_size <= 256) {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "GenericKey<256>";
#endif
    index =
        new BWTreeIndex<GenericKey<256>, ItemPointer *, GenericComparator<256>,
                        GenericEqualityChecker<256>, GenericHasher<256>,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  } else {
#ifdef LOG_TRACE_ENABLED
    comparatorType = "TupleKey";
#endif
    index =
        new BWTreeIndex<TupleKey, ItemPointer *, TupleKeyComparator,
                        TupleKeyEqualityChecker, TupleKeyHasher,
                        ItemPointerComparator, ItemPointerHashFunc>(metadata);
  }

#ifdef LOG_TRACE_ENABLED
  LOG_TRACE("%s", IndexFactory::GetInfo(metadata, comparatorType).c_str());
#endif
  return (index);
}

std::string IndexFactory::GetInfo(IndexMetadata *metadata,
                                  std::string comparatorType) {
  std::ostringstream os;
  os << "Index '" << metadata->GetName() << "' => "
     << IndexTypeToString(metadata->GetIndexMethodType())
     << "::" << comparatorType << "(";
  bool first = true;
  for (auto column : metadata->key_schema->GetColumns()) {
    if (first == false) os << ", ";
    os << column.GetName();
    first = false;
  }
  os << ")";
  return (os.str());
}

}  // End index namespace
}  // End peloton namespace
<|endoftext|>


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

#include "modules/map/relative_map/navigation_lane.h"

#include <algorithm>
#include <limits>

#include "modules/map/proto/map_lane.pb.h"

#include "modules/common/log.h"
#include "modules/common/math/math_utils.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/util/util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/map/relative_map/common/relative_map_gflags.h"

namespace apollo {
namespace relative_map {

using apollo::common::VehicleStateProvider;
using apollo::common::math::Vec2d;
using apollo::common::util::DistanceXY;
using apollo::hdmap::Lane;
using apollo::common::util::operator+;
using apollo::perception::PerceptionObstacles;

NavigationLane::NavigationLane(const NavigationLaneConfig &config)
    : config_(config) {}

void NavigationLane::SetConfig(const NavigationLaneConfig &config) {
  config_ = config;
}

bool NavigationLane::GeneratePath() {
  // original_pose is in world coordination: ENU
  original_pose_ = VehicleStateProvider::instance()->original_pose();

  navigation_path_.Clear();
  auto *path = navigation_path_.mutable_path();
  const auto &lane_marker = perception_obstacles_.lane_marker();

  // priority: merge > navigation line > perception lane marker
  if (FLAGS_enable_navigation_line &&
      navigation_info_.navigation_path_size() > 0) {
    ConvertNavigationLineToPath(path);
    if (path->path_point().size() <= 0) {
      ConvertLaneMarkerToPath(lane_marker, path);
    }
  } else {
    ConvertLaneMarkerToPath(lane_marker, path);
  }
  return true;
}

double NavigationLane::EvaluateCubicPolynomial(const double c0, const double c1,
                                               const double c2, const double c3,
                                               const double z) const {
  return ((c3 * z + c2) * z + c1) * z + c0;
}

void NavigationLane::MergeNavigationLineAndLaneMarker(
    const perception::LaneMarkers &lane_marker, common::Path *path) {
  CHECK_NOTNULL(path);

  common::Path navigation_path;
  ConvertNavigationLineToPath(&navigation_path);

  common::Path lane_marker_path;
  ConvertLaneMarkerToPath(perception_obstacles_.lane_marker(),
                          &lane_marker_path);

  const double len = std::fmin(
      navigation_path.path_point(navigation_path.path_point_size() - 1).s(),
      lane_marker_path.path_point(lane_marker_path.path_point_size() - 1).s());

  const double ds = 1.0;
  int navigation_index = 0;
  int lane_marker_index = 0;
  for (double s = 0.0; s < len; s += ds) {
    auto p1 = GetPathPointByS(navigation_path, navigation_index, s,
                              &navigation_index);
    auto p2 = GetPathPointByS(lane_marker_path, lane_marker_index, s,
                              &lane_marker_index);
    auto *p = path->add_path_point();
    const double kWeight = 0.9;
    *p = common::util::GetWeightedAverageOfTwoPathPoints(p1, p2, kWeight,
                                                         1 - kWeight);
  }
}

common::PathPoint NavigationLane::GetPathPointByS(const common::Path &path,
                                                  const int start_index,
                                                  const double s,
                                                  int *matched_index) {
  CHECK_NOTNULL(matched_index);

  constexpr double kEpsilon = 1e-9;
  if (std::fabs(path.path_point(start_index).s() - s) < kEpsilon) {
    *matched_index = start_index;
    return path.path_point(start_index);
  }
  int i = start_index;
  while (i + 1 < path.path_point_size() && path.path_point(i + 1).s() < s) {
    ++i;
  }
  *matched_index = i;

  // x, y, z, theta, kappa, s, dkappa, ddkappa
  const double r = (s - path.path_point(i).s()) /
                   (path.path_point(i + 1).s() - path.path_point(i).s());
  auto p = common::util::GetWeightedAverageOfTwoPathPoints(
      path.path_point(i), path.path_point(i + 1), 1 - r, r);
  return p;
}

void NavigationLane::ConvertNavigationLineToPath(common::Path *path) {
  CHECK_NOTNULL(path);
  if (navigation_info_.navigation_path_size() == 0 ||
      !navigation_info_.navigation_path(0).has_path() ||
      navigation_info_.navigation_path(0).path().path_point_size() == 0) {
    // path is empty
    return;
  }
  path->set_name("Path from navigation.");
  if (!UpdateProjectionIndex()) {
    return;
  }

  // TODO(All): support multiple navigation path
  // currently, only 1 navigation path is supported
  const auto &navigation_path = navigation_info_.navigation_path(0).path();
  int curr_project_index = last_project_index_;

  double dist =
      navigation_path.path_point(navigation_path.path_point_size() - 1).s() -
      navigation_path.path_point(curr_project_index).s();
  if (dist < 20) {
    return;
  }

  // offset between the current vehicle state and navigation line
  const double dx = -original_pose_.position().x();
  const double dy = -original_pose_.position().y();
  const double ref_s = navigation_path.path_point(curr_project_index).s();
  for (int i = std::max(0, curr_project_index - 3);
       i < navigation_path.path_point_size(); ++i) {
    auto *point = path->add_path_point();
    point->CopyFrom(navigation_path.path_point(i));

    // shift to (0, 0)
    double enu_x = point->x() + dx;
    double enu_y = point->y() + dy;

    double flu_x = 0.0;
    double flu_y = 0.0;
    common::math::RotateAxis(original_pose_.heading(), enu_x, enu_y, &flu_x,
                             &flu_y);

    point->set_x(flu_x);
    point->set_y(flu_y);
    point->set_theta(common::math::NormalizeAngle(
        common::math::NormalizeAngle(point->theta())
            - original_pose_.heading()));
    const double accumulated_s = navigation_path.path_point(i).s() - ref_s;
    point->set_s(accumulated_s);

    if (accumulated_s > FLAGS_max_len_from_navigation_line) {
      break;
    }
  }

  const perception::LaneMarkers &lane_marker =
      perception_obstacles_.lane_marker();
  const auto &left_lane = lane_marker.left_lane_marker();
  const auto &right_lane = lane_marker.right_lane_marker();
  left_width_ = (std::fabs(left_lane.c0_position()) +
                 std::fabs(right_lane.c0_position())) /
                2.0;
  right_width_ = left_width_;
}

// project adc_state_ onto path
bool NavigationLane::UpdateProjectionIndex() {
  // TODO(All): support multiple navigation path
  // currently, only 1 navigation path is supported
  const auto &path = navigation_info_.navigation_path(0).path();
  int index = 0;
  double min_d = std::numeric_limits<double>::max();
  for (int i = last_project_index_; i + 1 < path.path_point_size(); ++i) {
    const double d = DistanceXY(original_pose_.position(), path.path_point(i));
    if (d < min_d) {
      min_d = d;
      index = i;
    }
    const double kMaxDistance = 50.0;
    if (last_project_index_ != 0 && d > kMaxDistance) {
      break;
    }
  }
  if (min_d < FLAGS_max_distance_to_navigation_line) {
    return false;
  }
  last_project_index_ = index;
  return true;
}

void NavigationLane::ConvertLaneMarkerToPath(
    const perception::LaneMarkers &lane_marker, common::Path *path) {
  CHECK_NOTNULL(path);

  path->set_name("Path from lane markers.");
  const auto &left_lane = lane_marker.left_lane_marker();
  const auto &right_lane = lane_marker.right_lane_marker();

  double path_c0 = (left_lane.c0_position() + right_lane.c0_position()) / 2.0;

  double left_quality = left_lane.quality() + 0.001;
  double right_quality = right_lane.quality() + 0.001;

  double quality_divider = left_quality + right_quality;

  double path_c1 = (left_lane.c1_heading_angle() * left_quality +
                    right_lane.c1_heading_angle() * right_quality) /
                   quality_divider;

  double path_c2 = (left_lane.c2_curvature() * left_quality +
                    right_lane.c2_curvature() * right_quality) /
                   quality_divider;

  double path_c3 =
      (left_lane.c3_curvature_derivative() * left_quality +
       right_lane.c3_curvature_derivative() * right_quality) /
      quality_divider;

  const double current_speed =
      VehicleStateProvider::instance()->vehicle_state().linear_velocity();
  double path_range = current_speed * FLAGS_ratio_navigation_lane_len_to_speed;
  if (path_range <= FLAGS_min_len_for_navigation_lane) {
    path_range = FLAGS_min_len_for_navigation_lane;
  } else {
    path_range = FLAGS_max_len_for_navigation_lane;
  }

  const double unit_z = 1.0;
  const double start_s = -2.0;
  double accumulated_s = start_s;
  for (double z = start_s; z <= path_range; z += unit_z) {
    double x_l = EvaluateCubicPolynomial(path_c0, path_c1, path_c2, path_c3, z);

    double x1 = z;
    double y1 = x_l;

    auto *point = path->add_path_point();
    point->set_x(x1);
    point->set_y(y1);

    if (path->path_point_size() > 1) {
      auto &pre_point = path->path_point(path->path_point_size() - 2);
      accumulated_s += std::hypot(x1 - pre_point.x(), y1 - pre_point.y());
    }
    point->set_s(accumulated_s);
  }

  left_width_ = (std::fabs(left_lane.c0_position()) +
                 std::fabs(right_lane.c0_position())) /
                2.0;
  right_width_ = left_width_;
}

bool NavigationLane::CreateMap(const MapGenerationParam &map_config,
                               MapMsg *map_msg) const {
  auto *navigation_info = map_msg->mutable_navigation_path();
  auto *hdmap = map_msg->mutable_hdmap();
  auto *lane_marker = map_msg->mutable_lane_marker();

  lane_marker->CopyFrom(perception_obstacles_.lane_marker());

  const auto &path = navigation_path_.path();
  if (path.path_point_size() < 2) {
    AERROR << "The path length is invalid";
    return false;
  }
  auto *lane = hdmap->add_lane();
  lane->mutable_id()->set_id(std::to_string(navigation_path_.path_priority()) +
                             "_" + path.name());
  (*navigation_info)[lane->id().id()] = navigation_path_;
  // lane types
  lane->set_type(Lane::CITY_DRIVING);
  lane->set_turn(Lane::NO_TURN);

  // speed limit
  lane->set_speed_limit(map_config.default_speed_limit());

  // center line
  auto *curve_segment = lane->mutable_central_curve()->add_segment();
  curve_segment->set_heading(path.path_point(0).theta());
  auto *line_segment = curve_segment->mutable_line_segment();
  // left boundary
  auto *left_boundary = lane->mutable_left_boundary();
  auto *left_boundary_type = left_boundary->add_boundary_type();
  left_boundary->set_virtual_(false);
  left_boundary_type->set_s(0.0);
  left_boundary_type->add_types(
      perception_obstacles_.lane_marker().left_lane_marker().lane_type());
  auto *left_segment =
      left_boundary->mutable_curve()->add_segment()->mutable_line_segment();
  // right boundary
  auto *right_boundary = lane->mutable_right_boundary();
  auto *right_boundary_type = right_boundary->add_boundary_type();
  right_boundary->set_virtual_(false);
  right_boundary_type->set_s(0.0);
  right_boundary_type->add_types(
      perception_obstacles_.lane_marker().right_lane_marker().lane_type());
  auto *right_segment =
      right_boundary->mutable_curve()->add_segment()->mutable_line_segment();
  const double lane_left_width =
      left_width_ > 0 ? left_width_ : map_config.default_left_width();
  const double lane_right_width =
      right_width_ > 0 ? right_width_ : map_config.default_right_width();
  for (const auto &path_point : path.path_point()) {
    auto *point = line_segment->add_point();
    point->set_x(path_point.x());
    point->set_y(path_point.y());
    point->set_z(path_point.z());
    auto *left_sample = lane->add_left_sample();
    left_sample->set_s(path_point.s());
    left_sample->set_width(lane_left_width);
    left_segment->add_point()->CopyFrom(
        *point +
        lane_left_width * Vec2d::CreateUnitVec2d(path_point.theta() + M_PI_2));
    auto *right_sample = lane->add_right_sample();
    right_sample->set_s(path_point.s());
    right_sample->set_width(lane_right_width);
    right_segment->add_point()->CopyFrom(
        *point +
        lane_right_width * Vec2d::CreateUnitVec2d(path_point.theta() - M_PI_2));
  }

  return true;
}

}  // namespace relative_map
}  // namespace apollo
<commit_msg>navi: fixed a bug in navigation lane.<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/map/relative_map/navigation_lane.h"

#include <algorithm>
#include <limits>

#include "modules/map/proto/map_lane.pb.h"

#include "modules/common/log.h"
#include "modules/common/math/math_utils.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/util/util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/map/relative_map/common/relative_map_gflags.h"

namespace apollo {
namespace relative_map {

using apollo::common::VehicleStateProvider;
using apollo::common::math::Vec2d;
using apollo::common::util::DistanceXY;
using apollo::hdmap::Lane;
using apollo::common::util::operator+;
using apollo::perception::PerceptionObstacles;

NavigationLane::NavigationLane(const NavigationLaneConfig &config)
    : config_(config) {}

void NavigationLane::SetConfig(const NavigationLaneConfig &config) {
  config_ = config;
}

bool NavigationLane::GeneratePath() {
  // original_pose is in world coordination: ENU
  original_pose_ = VehicleStateProvider::instance()->original_pose();

  navigation_path_.Clear();
  auto *path = navigation_path_.mutable_path();
  const auto &lane_marker = perception_obstacles_.lane_marker();

  // priority: merge > navigation line > perception lane marker
  if (FLAGS_enable_navigation_line &&
      navigation_info_.navigation_path_size() > 0) {
    ConvertNavigationLineToPath(path);
    if (path->path_point().size() <= 0) {
      ConvertLaneMarkerToPath(lane_marker, path);
    }
  } else {
    ConvertLaneMarkerToPath(lane_marker, path);
  }
  return true;
}

double NavigationLane::EvaluateCubicPolynomial(const double c0, const double c1,
                                               const double c2, const double c3,
                                               const double z) const {
  return ((c3 * z + c2) * z + c1) * z + c0;
}

void NavigationLane::MergeNavigationLineAndLaneMarker(
    const perception::LaneMarkers &lane_marker, common::Path *path) {
  CHECK_NOTNULL(path);

  common::Path navigation_path;
  ConvertNavigationLineToPath(&navigation_path);

  common::Path lane_marker_path;
  ConvertLaneMarkerToPath(perception_obstacles_.lane_marker(),
                          &lane_marker_path);

  const double len = std::fmin(
      navigation_path.path_point(navigation_path.path_point_size() - 1).s(),
      lane_marker_path.path_point(lane_marker_path.path_point_size() - 1).s());

  const double ds = 1.0;
  int navigation_index = 0;
  int lane_marker_index = 0;
  for (double s = 0.0; s < len; s += ds) {
    auto p1 = GetPathPointByS(navigation_path, navigation_index, s,
                              &navigation_index);
    auto p2 = GetPathPointByS(lane_marker_path, lane_marker_index, s,
                              &lane_marker_index);
    auto *p = path->add_path_point();
    const double kWeight = 0.9;
    *p = common::util::GetWeightedAverageOfTwoPathPoints(p1, p2, kWeight,
                                                         1 - kWeight);
  }
}

common::PathPoint NavigationLane::GetPathPointByS(const common::Path &path,
                                                  const int start_index,
                                                  const double s,
                                                  int *matched_index) {
  CHECK_NOTNULL(matched_index);

  constexpr double kEpsilon = 1e-9;
  if (std::fabs(path.path_point(start_index).s() - s) < kEpsilon) {
    *matched_index = start_index;
    return path.path_point(start_index);
  }
  int i = start_index;
  while (i + 1 < path.path_point_size() && path.path_point(i + 1).s() < s) {
    ++i;
  }
  *matched_index = i;

  // x, y, z, theta, kappa, s, dkappa, ddkappa
  const double r = (s - path.path_point(i).s()) /
                   (path.path_point(i + 1).s() - path.path_point(i).s());
  auto p = common::util::GetWeightedAverageOfTwoPathPoints(
      path.path_point(i), path.path_point(i + 1), 1 - r, r);
  return p;
}

void NavigationLane::ConvertNavigationLineToPath(common::Path *path) {
  CHECK_NOTNULL(path);
  if (navigation_info_.navigation_path_size() == 0 ||
      !navigation_info_.navigation_path(0).has_path() ||
      navigation_info_.navigation_path(0).path().path_point_size() == 0) {
    // path is empty
    return;
  }
  path->set_name("Path from navigation.");
  if (!UpdateProjectionIndex()) {
    return;
  }

  // TODO(All): support multiple navigation path
  // currently, only 1 navigation path is supported
  const auto &navigation_path = navigation_info_.navigation_path(0).path();
  int curr_project_index = last_project_index_;

  double dist =
      navigation_path.path_point(navigation_path.path_point_size() - 1).s() -
      navigation_path.path_point(curr_project_index).s();
  if (dist < 20) {
    return;
  }

  // offset between the current vehicle state and navigation line
  const double dx = -original_pose_.position().x();
  const double dy = -original_pose_.position().y();
  const double ref_s = navigation_path.path_point(curr_project_index).s();
  for (int i = std::max(0, curr_project_index - 3);
       i < navigation_path.path_point_size(); ++i) {
    auto *point = path->add_path_point();
    point->CopyFrom(navigation_path.path_point(i));

    // shift to (0, 0)
    double enu_x = point->x() + dx;
    double enu_y = point->y() + dy;

    double flu_x = 0.0;
    double flu_y = 0.0;
    common::math::RotateAxis(original_pose_.heading(), enu_x, enu_y, &flu_x,
                             &flu_y);

    point->set_x(flu_x);
    point->set_y(flu_y);
    point->set_theta(common::math::NormalizeAngle(
        common::math::NormalizeAngle(point->theta())
            - original_pose_.heading()));
    const double accumulated_s = navigation_path.path_point(i).s() - ref_s;
    point->set_s(accumulated_s);

    if (accumulated_s > FLAGS_max_len_from_navigation_line) {
      break;
    }
  }

  const perception::LaneMarkers &lane_marker =
      perception_obstacles_.lane_marker();
  const auto &left_lane = lane_marker.left_lane_marker();
  const auto &right_lane = lane_marker.right_lane_marker();
  left_width_ = (std::fabs(left_lane.c0_position()) +
                 std::fabs(right_lane.c0_position())) /
                2.0;
  right_width_ = left_width_;
}

// project adc_state_ onto path
bool NavigationLane::UpdateProjectionIndex() {
  // TODO(All): support multiple navigation path
  // currently, only 1 navigation path is supported
  const auto &path = navigation_info_.navigation_path(0).path();
  int index = 0;
  double min_d = std::numeric_limits<double>::max();
  for (int i = last_project_index_; i + 1 < path.path_point_size(); ++i) {
    const double d = DistanceXY(original_pose_.position(), path.path_point(i));
    if (d < min_d) {
      min_d = d;
      index = i;
    }
    const double kMaxDistance = 50.0;
    if (last_project_index_ != 0 && d > kMaxDistance) {
      break;
    }
  }
  if (min_d > FLAGS_max_distance_to_navigation_line) {
    return false;
  }
  last_project_index_ = index;
  return true;
}

void NavigationLane::ConvertLaneMarkerToPath(
    const perception::LaneMarkers &lane_marker, common::Path *path) {
  CHECK_NOTNULL(path);

  path->set_name("Path from lane markers.");
  const auto &left_lane = lane_marker.left_lane_marker();
  const auto &right_lane = lane_marker.right_lane_marker();

  double path_c0 = (left_lane.c0_position() + right_lane.c0_position()) / 2.0;

  double left_quality = left_lane.quality() + 0.001;
  double right_quality = right_lane.quality() + 0.001;

  double quality_divider = left_quality + right_quality;

  double path_c1 = (left_lane.c1_heading_angle() * left_quality +
                    right_lane.c1_heading_angle() * right_quality) /
                   quality_divider;

  double path_c2 = (left_lane.c2_curvature() * left_quality +
                    right_lane.c2_curvature() * right_quality) /
                   quality_divider;

  double path_c3 =
      (left_lane.c3_curvature_derivative() * left_quality +
       right_lane.c3_curvature_derivative() * right_quality) /
      quality_divider;

  const double current_speed =
      VehicleStateProvider::instance()->vehicle_state().linear_velocity();
  double path_range = current_speed * FLAGS_ratio_navigation_lane_len_to_speed;
  if (path_range <= FLAGS_min_len_for_navigation_lane) {
    path_range = FLAGS_min_len_for_navigation_lane;
  } else {
    path_range = FLAGS_max_len_for_navigation_lane;
  }

  const double unit_z = 1.0;
  const double start_s = -2.0;
  double accumulated_s = start_s;
  for (double z = start_s; z <= path_range; z += unit_z) {
    double x_l = EvaluateCubicPolynomial(path_c0, path_c1, path_c2, path_c3, z);

    double x1 = z;
    double y1 = x_l;

    auto *point = path->add_path_point();
    point->set_x(x1);
    point->set_y(y1);

    if (path->path_point_size() > 1) {
      auto &pre_point = path->path_point(path->path_point_size() - 2);
      accumulated_s += std::hypot(x1 - pre_point.x(), y1 - pre_point.y());
    }
    point->set_s(accumulated_s);
  }

  left_width_ = (std::fabs(left_lane.c0_position()) +
                 std::fabs(right_lane.c0_position())) /
                2.0;
  right_width_ = left_width_;
}

bool NavigationLane::CreateMap(const MapGenerationParam &map_config,
                               MapMsg *map_msg) const {
  auto *navigation_info = map_msg->mutable_navigation_path();
  auto *hdmap = map_msg->mutable_hdmap();
  auto *lane_marker = map_msg->mutable_lane_marker();

  lane_marker->CopyFrom(perception_obstacles_.lane_marker());

  const auto &path = navigation_path_.path();
  if (path.path_point_size() < 2) {
    AERROR << "The path length is invalid";
    return false;
  }
  auto *lane = hdmap->add_lane();
  lane->mutable_id()->set_id(std::to_string(navigation_path_.path_priority()) +
                             "_" + path.name());
  (*navigation_info)[lane->id().id()] = navigation_path_;
  // lane types
  lane->set_type(Lane::CITY_DRIVING);
  lane->set_turn(Lane::NO_TURN);

  // speed limit
  lane->set_speed_limit(map_config.default_speed_limit());

  // center line
  auto *curve_segment = lane->mutable_central_curve()->add_segment();
  curve_segment->set_heading(path.path_point(0).theta());
  auto *line_segment = curve_segment->mutable_line_segment();
  // left boundary
  auto *left_boundary = lane->mutable_left_boundary();
  auto *left_boundary_type = left_boundary->add_boundary_type();
  left_boundary->set_virtual_(false);
  left_boundary_type->set_s(0.0);
  left_boundary_type->add_types(
      perception_obstacles_.lane_marker().left_lane_marker().lane_type());
  auto *left_segment =
      left_boundary->mutable_curve()->add_segment()->mutable_line_segment();
  // right boundary
  auto *right_boundary = lane->mutable_right_boundary();
  auto *right_boundary_type = right_boundary->add_boundary_type();
  right_boundary->set_virtual_(false);
  right_boundary_type->set_s(0.0);
  right_boundary_type->add_types(
      perception_obstacles_.lane_marker().right_lane_marker().lane_type());
  auto *right_segment =
      right_boundary->mutable_curve()->add_segment()->mutable_line_segment();
  const double lane_left_width =
      left_width_ > 0 ? left_width_ : map_config.default_left_width();
  const double lane_right_width =
      right_width_ > 0 ? right_width_ : map_config.default_right_width();
  for (const auto &path_point : path.path_point()) {
    auto *point = line_segment->add_point();
    point->set_x(path_point.x());
    point->set_y(path_point.y());
    point->set_z(path_point.z());
    auto *left_sample = lane->add_left_sample();
    left_sample->set_s(path_point.s());
    left_sample->set_width(lane_left_width);
    left_segment->add_point()->CopyFrom(
        *point +
        lane_left_width * Vec2d::CreateUnitVec2d(path_point.theta() + M_PI_2));
    auto *right_sample = lane->add_right_sample();
    right_sample->set_s(path_point.s());
    right_sample->set_width(lane_right_width);
    right_segment->add_point()->CopyFrom(
        *point +
        lane_right_width * Vec2d::CreateUnitVec2d(path_point.theta() - M_PI_2));
  }

  return true;
}

}  // namespace relative_map
}  // namespace apollo
<|endoftext|>


<commit_before>#pragma once

#include <type_traits>
#include <functional>
#include <utility>
#include <memory>
#include <uv.h>
#include "loop.hpp"
#include "util.hpp"

namespace uvw {

template<typename>
struct HandleType { };

template<typename>
class Handle;

namespace details {

template<typename T> void* get(T *handle) { return handle->data; }
void* get(uv_connect_t *conn) { return conn->handle->data; }

template<typename T, typename F>
struct UVCallbackFactory;

template<typename T,typename H,  typename... Args>
struct UVCallbackFactory<T, void(H, Args...)> {
    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static auto once(T &, std::function<void(UVWError, T &)>);

    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static auto on(T &, std::function<void(UVWError, T &)>);

private:
    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static void protoOnce(H, Args...);

    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static void protoOn(H, Args...);
};

}

template<typename T>
class Handle: public std::enable_shared_from_this<T> {
    template<typename, typename>
    friend struct details::UVCallbackFactory;

    static void closeCallback(T &t, std::function<void(UVWError, T &)> &cb, uv_handle_t*) {
        cb(UVWError{}, t);
    }

protected:
    template<typename F>
    using CallbackFactory = details::UVCallbackFactory<T, F>;

    template<typename U>
    explicit Handle(HandleType<U>, std::shared_ptr<Loop> r)
        : uvHandle{std::make_shared<U>()}, pLoop{std::move(r)}
    { }

    void error(int error) {
        auto ptr = std::static_pointer_cast<T>(leak);
        auto cb = std::move(callback);
        leak.reset();
        cb(UVWError{error}, *ptr);
    }

    template<typename U>
    U* get() const noexcept { return reinterpret_cast<U*>(uvHandle.get()); }

    uv_loop_t* parent() const noexcept { return pLoop->loop.get(); }

public:
    explicit Handle(const Handle &) = delete;
    explicit Handle(Handle &&) = delete;

    ~Handle() { static_assert(std::is_base_of<Handle<T>, T>::value, "!"); }

    void operator=(const Handle &) = delete;
    void operator=(Handle &&) = delete;

    Resource<T> resource() noexcept { return pLoop->resource(Handle<T>::shared_from_this()); }
    Loop& loop() const noexcept { return *pLoop; }

    bool active() const noexcept { return !(uv_is_active(get<uv_handle_t>()) == 0); }
    bool closing() const noexcept { return !(uv_is_closing(get<uv_handle_t>()) == 0); }

    void reference() noexcept { uv_ref(get<uv_handle_t>()); }
    void unreference() noexcept { uv_ref(get<uv_handle_t>()); }
    bool referenced() const noexcept { return !(uv_has_ref(get<uv_handle_t>()) == 0); }

    void close(std::function<void(UVWError, T &)> cb) noexcept {
        using CBF = CallbackFactory<void(uv_handle_t*)>;
        auto func = CBF::template once<&Handle<T>::closeCallback>(*static_cast<T*>(this), std::move(cb));
        uv_close(get<uv_handle_t>(), func);
    }

private:
    std::shared_ptr<void> uvHandle;
    std::shared_ptr<Loop> pLoop;
    std::shared_ptr<void> leak;
    std::function<void(UVWError, T &)> callback;
};

namespace details {

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
auto UVCallbackFactory<T, void(H, Args...)>::once(T &ref, std::function<void(UVWError, T &)> cb) {
    Handle<T> &res = ref;
    res.callback = std::move(cb);
    res.leak = res.shared_from_this();
    res.template get<uv_handle_t>()->data = &ref;
    return &UVCallbackFactory<T, void(H, Args...)>::protoOnce<F>;
}

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
auto UVCallbackFactory<T, void(H, Args...)>::on(T &ref, std::function<void(UVWError, T &)> cb) {
    Handle<T> &res = ref;
    res.callback = std::move(cb);
    res.leak = res.shared_from_this();
    res.template get<uv_handle_t>()->data = &ref;
    return &UVCallbackFactory<T, void(H, Args...)>::protoOn<F>;
}

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
void UVCallbackFactory<T, void(H, Args...)>::protoOnce(H handle, Args... args) {
    T &ref = *(static_cast<T*>(details::get(handle)));
    auto ptr = std::static_pointer_cast<T>(ref.leak);
    auto cb = std::move(ref.callback);
    ref.leak.reset();
    F(*ptr, cb, handle, std::forward<Args>(args)...);
}

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
void UVCallbackFactory<T, void(H, Args...)>::protoOn(H handle, Args... args) {
    T &ref = *(static_cast<T*>(details::get(handle)));
    F(ref, ref.callback, handle, std::forward<Args>(args)...);
}

}

}
<commit_msg>bug fixing<commit_after>#pragma once

#include <type_traits>
#include <functional>
#include <utility>
#include <memory>
#include <uv.h>
#include "loop.hpp"
#include "util.hpp"

namespace uvw {

template<typename>
struct HandleType { };

template<typename>
class Handle;

namespace details {

template<typename T> void* get(T *handle) { return handle->data; }
void* get(uv_connect_t *conn) { return conn->handle->data; }

template<typename T, typename F>
struct UVCallbackFactory;

template<typename T,typename H,  typename... Args>
struct UVCallbackFactory<T, void(H, Args...)> {
    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static auto once(T &, std::function<void(UVWError, T &)>);

    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static auto on(T &, std::function<void(UVWError, T &)>);

private:
    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static void protoOnce(H, Args...);

    template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
    static void protoOn(H, Args...);
};

}

template<typename T>
class Handle: public std::enable_shared_from_this<T> {
    template<typename, typename>
    friend struct details::UVCallbackFactory;

    static void closeCallback(T &t, std::function<void(UVWError, T &)> &cb, uv_handle_t*) {
        cb(UVWError{}, t);
    }

protected:
    template<typename F>
    using CallbackFactory = details::UVCallbackFactory<T, F>;

    template<typename U>
    explicit Handle(HandleType<U>, std::shared_ptr<Loop> r)
        : uvHandle{std::make_shared<U>()}, pLoop{std::move(r)}
    { }

    void error(int error) {
        auto ptr = std::static_pointer_cast<T>(leak);
        auto cb = std::move(callback);
        leak.reset();
        cb(UVWError{error}, *ptr);
    }

    template<typename U>
    U* get() const noexcept { return reinterpret_cast<U*>(uvHandle.get()); }

    uv_loop_t* parent() const noexcept { return pLoop->loop.get(); }

public:
    explicit Handle(const Handle &) = delete;
    explicit Handle(Handle &&) = delete;

    ~Handle() { static_assert(std::is_base_of<Handle<T>, T>::value, "!"); }

    void operator=(const Handle &) = delete;
    void operator=(Handle &&) = delete;

    Resource<T> resource() noexcept { return pLoop->resource(Handle<T>::shared_from_this()); }
    Loop& loop() const noexcept { return *pLoop; }

    bool active() const noexcept { return !(uv_is_active(get<uv_handle_t>()) == 0); }
    bool closing() const noexcept { return !(uv_is_closing(get<uv_handle_t>()) == 0); }

    void reference() noexcept { uv_ref(get<uv_handle_t>()); }
    void unreference() noexcept { uv_unref(get<uv_handle_t>()); }
    bool referenced() const noexcept { return !(uv_has_ref(get<uv_handle_t>()) == 0); }

    void close(std::function<void(UVWError, T &)> cb) noexcept {
        using CBF = CallbackFactory<void(uv_handle_t*)>;
        auto func = CBF::template once<&Handle<T>::closeCallback>(*static_cast<T*>(this), std::move(cb));
        uv_close(get<uv_handle_t>(), func);
    }

private:
    std::shared_ptr<void> uvHandle;
    std::shared_ptr<Loop> pLoop;
    std::shared_ptr<void> leak;
    std::function<void(UVWError, T &)> callback;
};

namespace details {

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
auto UVCallbackFactory<T, void(H, Args...)>::once(T &ref, std::function<void(UVWError, T &)> cb) {
    Handle<T> &res = ref;
    res.callback = std::move(cb);
    res.leak = res.shared_from_this();
    res.template get<uv_handle_t>()->data = &ref;
    return &UVCallbackFactory<T, void(H, Args...)>::protoOnce<F>;
}

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
auto UVCallbackFactory<T, void(H, Args...)>::on(T &ref, std::function<void(UVWError, T &)> cb) {
    Handle<T> &res = ref;
    res.callback = std::move(cb);
    res.leak = res.shared_from_this();
    res.template get<uv_handle_t>()->data = &ref;
    return &UVCallbackFactory<T, void(H, Args...)>::protoOn<F>;
}

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
void UVCallbackFactory<T, void(H, Args...)>::protoOnce(H handle, Args... args) {
    T &ref = *(static_cast<T*>(details::get(handle)));
    auto ptr = std::static_pointer_cast<T>(ref.leak);
    auto cb = std::move(ref.callback);
    ref.leak.reset();
    F(*ptr, cb, handle, std::forward<Args>(args)...);
}

template<typename T, typename H, typename... Args>
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
void UVCallbackFactory<T, void(H, Args...)>::protoOn(H handle, Args... args) {
    T &ref = *(static_cast<T*>(details::get(handle)));
    F(ref, ref.callback, handle, std::forward<Args>(args)...);
}

}

}
<|endoftext|>


<commit_before>/**
 * @file ranker.cpp
 * @author Sean Massung
 */

#include "index/ranker/ranker.h"

namespace meta {
namespace index {

std::vector<std::pair<doc_id, double>> ranker::score(inverted_index & idx,
                                                 corpus::document & query) const
{
    if(query.frequencies().empty())
        idx.tokenize(query);

    score_data sd{idx,
                  idx.avg_doc_length(),
                  idx.num_docs(),
                  idx.total_corpus_terms(),
                  query
    };

    std::unordered_map<doc_id, double> results;
    for(auto & tpair: query.frequencies())
    {
        sd.t_id = tpair.first;
        sd.query_term_count = tpair.second;
        sd.idf = idx.idf(tpair.first);
        sd.corpus_term_count = idx.total_num_occurences(sd.t_id);
        for(auto & dpair: idx.counts(tpair.first))
        {
            sd.d_id = dpair.first;
            sd.doc_term_count = dpair.second;
            sd.doc_size = idx.doc_size(dpair.first);
            sd.doc_unique_terms = idx.unique_terms(dpair.first);
            results[dpair.first] += score_one(sd);
        }
    }

    using doc_pair = std::pair<doc_id, double>;
    std::vector<doc_pair> final_results{results.begin(), results.end()};
    std::sort(final_results.begin(), final_results.end(),
        [](const doc_pair & a, const doc_pair & b) {
            return a.second > b.second;
        }
    );

    return final_results;
}

}
}
<commit_msg>Minor performance increase in ranker.<commit_after>/**
 * @file ranker.cpp
 * @author Sean Massung
 */

#include "index/ranker/ranker.h"

namespace meta {
namespace index {

std::vector<std::pair<doc_id, double>> ranker::score(inverted_index & idx,
                                                 corpus::document & query) const
{
    if(query.frequencies().empty())
        idx.tokenize(query);

    score_data sd{idx,
                  idx.avg_doc_length(),
                  idx.num_docs(),
                  idx.total_corpus_terms(),
                  query
    };

    std::unordered_map<doc_id, double> results;
    for(auto & tpair: query.frequencies())
    {
        sd.t_id = tpair.first;
        sd.query_term_count = tpair.second;
        sd.idf = idx.idf(tpair.first);
        sd.corpus_term_count = idx.total_num_occurences(sd.t_id);
        auto pdata = idx.search_primary(tpair.first);
        for(auto & dpair: pdata->counts())
        {
            sd.d_id = dpair.first;
            sd.doc_term_count = dpair.second;
            sd.doc_size = idx.doc_size(dpair.first);
            sd.doc_unique_terms = idx.unique_terms(dpair.first);
            results[dpair.first] += score_one(sd);
        }
    }

    using doc_pair = std::pair<doc_id, double>;
    std::vector<doc_pair> final_results{results.begin(), results.end()};
    std::sort(final_results.begin(), final_results.end(),
        [](const doc_pair & a, const doc_pair & b) {
            return a.second > b.second;
        }
    );

    return final_results;
}

}
}
<|endoftext|>