File: odc_index.cc

package info (click to toggle)
odc 1.6.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,140 kB
  • sloc: cpp: 21,984; f90: 3,707; sh: 966; ansic: 477; python: 389; makefile: 33
file content (110 lines) | stat: -rw-r--r-- 2,943 bytes parent folder | download
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
/**
 * To build this program, please make sure to reference linked libraries:
 *
 *     g++ -std=c++11 -leckit -lodccore -o odc-cpp-index odc_index.cc
 */

#include "eckit/runtime/Main.h"

#include "odc/api/Odb.h"

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <vector>

using namespace odc::api;

void usage() {
    std::cerr << "Usage:\n    odc-cpp-index <odb2 file>" << std::endl << std::endl;
}

class Printer : public SpanVisitor {
    template <typename T>
    void prnt(const std::string& columnName, const std::set<T>& vals) {
        ASSERT(vals.size() == 1);
        std::cout << columnName << "=" << *vals.begin() << " ";
    }
    void operator()(const std::string& columnName, const std::set<long>& vals) override { prnt(columnName, vals); }
    void operator()(const std::string& columnName, const std::set<double>& vals) override { prnt(columnName, vals); }
    void operator()(const std::string& columnName, const std::set<std::string>& vals) override {
        prnt(columnName, vals);
    }
};

void write_index(Span& span, long offset, long length) {
    std::cout << "Archival unit: offset=" << offset << " length=" << length << std::endl;
    std::cout << "  Key: ";

    // Dump the index values without decoding the frame data
    Printer p;
    span.visit(p);

    std::cout << std::endl;
}

int main(int argc, char** argv) {
    if (argc != 2) {
        usage();
        return 1;
    }

    char* path = argv[1];

    eckit::Main::initialise(argc, argv);

    // Initialise library
    odc::api::Settings::treatIntegersAsDoubles(false);

    bool aggregated = false;

    // Open supplied path in non-aggregated mode
    Reader reader(path, aggregated);

    // Define which columns will be used as index keys
    std::vector<std::string> index_keys{"key1", "key2", "key3"};

    Frame frame;
    Span lastSpan;
    long offset = 0;
    long length = 0;
    bool first  = true;

    // Iterate over frames
    while ((frame = reader.next())) {

        // Enforce the constant values constraint
        bool mustBeConstant = true;

        // Get index values for the frame
        Span span = frame.span(index_keys, mustBeConstant);

        // If the index values are the same, just increase the length
        if (span == lastSpan || first) {
            length += span.length();

            // Remember the first set of index values
            if (first)
                std::swap(lastSpan, span);
        }

        // If the index values differ, output the last set
        else {
            write_index(lastSpan, offset, length);

            // Reset offset and length counters
            offset = span.offset();
            length = span.length();

            // Remember the current set of index values
            std::swap(lastSpan, span);
        }

        first = false;
    }

    // Output last set of index values
    write_index(lastSpan, offset, length);

    return 0;
}