2

I have a use case where I have to store the following represented in the form of a table in a data structure implemented in C++ and support certain set of queries

[ "Col1", "Col2", "Col3", "Col4", "Col5" ]

[ "V1", "V2", "V3", "V4", "Value1"]

etc

Col1, Col2, Col3, Col4, Col5 together form a primary key. Also Col1, 2 are of string type and 2, 4 and 5 are of integer type.

The data structure should support the following operations:

  1. Support insert operations for each row.

  2. Given the values for Col1, Col2, Col3, Col4 find the value of Col5

  3. Given Col1, Col2, COl3, Col4 update Col5

I'm thinking of implementing a tree and support lookups. Is there a standard algorithms/a simpler way to solve this problem ?

Pseudo code/Code will be appreciated.

Thanks.

5
  • 1
    what have you tried? Commented May 3, 2013 at 21:26
  • 1
    Maybe Boost.MultiIndex? Commented May 3, 2013 at 21:26
  • What, you mean some kind of std::map? However, you second constraint seems to hint that you need something custom. Commented May 3, 2013 at 21:27
  • Would std::map<std::vector<std::string>, std::string> work? Commented May 3, 2013 at 21:43
  • Well, this approach would work but have very high cost of look ups. Commented May 3, 2013 at 22:20

1 Answer 1

3

You might want to make a std::map with the first 4 columns as key, and the 5th as value. I've taken columns to be of mixed std::string and int type, but you could generalize that to whatever you like.

#include <map> #include <utility> #include <tuple> #include <iostream> #include <string> typedef std::map< std::tuple<std::string, std::string, int, int>, int> Table; int main() { Table my_table; std::string a = "Kode", b = "Warrior"; int c = 3, d = 4, e = 5; // 1. Support insert operations for each row. my_table.insert(std::make_pair(std::make_tuple(a, b, c, d), e)); // 2. Given the values for Col1, Col2, Col3, Col4 find the value of Col5 auto it = my_table.find(std::make_tuple(a, b, c, d)); std::cout << it->second; // prints e // 3. Given Col1, Col2, COl3, Col4 update Col5 it->second = 6; // assign some other value } 

Output on Ideone.

One big drawback (but it wasn't in your requirements): it does not support column insertion, so it's not a good model for a spreadsheet. You could try to use a std::map< std::vector<std::string>, std::string> for that as mentioned by @NarutSereewattanawoot in the comments. You can modify your code to support that but you need some initializer-list mechanics to get a make_vector to have compact lookup syntax. OTOH, the drawback of a std::vector as a key is that you need type homogeneity which std::tuple avoids. If you want to get really fancy pancy, you could have a std::vector<boost::any> as the key which is both type-flexible and column-size flexible.

Sign up to request clarification or add additional context in comments.

10 Comments

That's a nifty solution. Thanks. This is a c++11 specific feature and we use a older version of the compiler. Also the columns can be a mixture of ints and strings ( I will update the question ).
At some point you might be better off with a C++ interface to a relational database that does the data storage / persistence / transactions etc.
Yes but it's going to be huge overhead to query the db for each lookup.
I like you solution. I'm worried of the cost of lookups in this case. Essentially we are comparing vectors which is very expensive.
@KodeWarrior but the writers of a C++ database library would have thought about that, implementing caching strategies that you might never think of. Look, if the database is small, then it doesn't matter what you do, but if it's really big, you do probably have it on disk and now you have to worry about paging, persistence, transactional semantics etc. I'd go for a library for anything big.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.