summaryrefslogtreecommitdiff
path: root/Ix/CPP/samples/SampleCppLinq/SampleCppLinq.cpp
blob: e459e4baa96ccb343cff99c9debb03cef94a1cc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

// SampleCppLinq.cpp : Defines the entry point for the console application.
//

#include <cpplinq\linq.hpp>

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <exception>
#include <regex>
#include <cmath>
#include <algorithm>
#include <numeric>

using namespace std;

vector<string> load_data();
string extract_value(const string& input, const string& key);


void run()
{
    using namespace cpplinq;

    struct item {
        string args;
        int    concurrency;
        double time;

        item(const string& input) {
            args =              extract_value(input, "args");
            concurrency = atoi( extract_value(input, "concurrency").c_str() );
            time =        atof( extract_value(input, "time").c_str() );
        }
    };

    auto data_unparsed = load_data();
    auto data_parsed = 
        from(data_unparsed)
        .select([](const string& line) { return item(line); })
        .to_vector();
    
    cout << "data loaded" << endl;

    auto data = 
        from(data_parsed)        
        .groupby([](const item& i) { return i.args; });
    
    for (auto giter = data.begin(), end = data.end(); giter != end; ++giter)
    {
        auto& g = *giter;

        cout << "arguments: " << g.key << endl;

        cout << "concurrency, mean, |, raw_data," << endl;
        auto seq =
            from(g)
            .groupby([](const item& i) { return i.concurrency; });

        for (auto giter = seq.begin(), end = seq.end(); giter != end; ++giter)
        {
            auto& g = *giter;

            cout << g.key << ", ";
            
            auto times = from(g).select([](const item& i) { return i.time; });
            
            auto n = from(g).count();
            auto sum = std::accumulate(times.begin(), times.end(), 0.0);

            cout << (sum / n) << ", |";

            for (auto timeIter = times.begin(), end = times.end();
                timeIter != end;
                ++timeIter)
            {
                cout << ", " << *timeIter;
            }
            cout << endl;
        }
    }
}


int main()
{
    try {
        run();
    } catch (exception& e) {
        cerr << "exception: " << e.what() << endl;
    }
}

vector<string> load_data()
{
	ifstream datafile("data.txt");
    vector<string> v;
    string line;

    if (datafile.fail())
        throw logic_error("could not find file");

    while(getline(datafile, line))
        v.push_back(line);

    return v;
}

regex key_value_pair("'([^\']*)'\\s*[:,]\\s*(\\d+(?:\\.\\d+)?|'[^']*')");

string extract_value(const string& input, const string& key)
{
    const std::sregex_iterator end;
    for (std::sregex_iterator i(input.cbegin(), input.cend(), key_value_pair);
        i != end;
        ++i)
    {
        if ((*i)[1] == key)
        {
            return (*i)[2];
        }
    }
    throw std::range_error("search key not found");
}