1

I'm trying to implement a very basic clone of redis in C++. So when I get the queries, I need to parse those. Right now I am doing this:

void Query::buildQuery(){
        std::string query_type = lower(args[0]);
        if(query_type == "get"){ //do something }
        else if(query_type == "set"){ //do something }
        else if(query_type == "getbit"){ //do something }
        else if(query_type == "setbit"){ //do something }
        else if(query_type == "zadd"){ //do something }
        else if(query_type == "zcard"){ //do something }
        else if(query_type == "zcount"){ //do something }
        else if(query_type == "zrange"){ //do something }
        else if(query_type == "save"){ //do something }
        else { throw(QueryException("Invalid query type")); }
}

Is there any other, shorter way to do this? I don't want to include any other library than the STL.

Ayush Gupta
  • 1,589
  • 3
  • 13
  • 23
  • this answer is the way to use a switch to replace the `if()else if()...` [Evaluate a string with a switch in C++ [duplicate]](http://stackoverflow.com/a/16388594/5852567) – DIEGO CARRASCAL Mar 07 '16 at 18:37
  • @DIEGOCARRASCAL Actually, no. I wasn't looking for a way to change if else to switch. I'm looking for a method other than these 2(if any) that could somehow do the required. – Ayush Gupta Mar 07 '16 at 18:55

3 Answers3

3

If those do_somethings can be extracted into separate methods, then you could create a pre-initialized hash map (unordered_map) from string to pointer to member function and do something like

(this->*queryHandlers[query_type])();

You'll have to choose between lots of functions and one large function, though.

Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
0

Without if...else if, you can do this by switch statement. Like:

void Query::buildQuery(){
        std::string query_type = lower(args[0]);
        switch(str2int(query_type) ){
            case str2int("set"):// do something 
                break;
            case str2int("getbit"):// do something 
                break;
            ................
            ..........
            default:
                throw(QueryException("Invalid query type")); 
        }
}

According to Serhiy where str2int is like:

constexpr unsigned int str2int(const char* str, int h = 0)
{
    return !str[h] ? 5381 : (str2int(str, h+1)*33) ^ str[h];
}
Community
  • 1
  • 1
Sakib Ahammed
  • 2,452
  • 2
  • 25
  • 29
0

If you're running on an Intel/AMD processor and feeling 'brave' you might like to take a look at these implementations of strcmp, strlen, etc that use SSE instructions. That'd be quicker.

As for the general structure, you could turn "set" & "do something" into an class which has a test method and a do-something method. Have an array of those, and iterate across it calling the test method passing query_type. The test method for the object would automatically call the do-something method if it matches the string.

bazza
  • 7,580
  • 15
  • 22