-
Notifications
You must be signed in to change notification settings - Fork 4
/
wrapper.h
159 lines (143 loc) · 4.74 KB
/
wrapper.h
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* Wrapper.h
*
* A wrapper whichs wraps the php object with the mapreduce implementation to the
* actual Yothalot::MapReduce class.
*
* @author Toon Schoenmakers <[email protected]>
* @copyright 2015 - 2016 Copernica BV
*/
/**
* Include guard
*/
#pragma once
/**
* Dependencies
*/
#include <yothalot.h>
#include <phpcpp.h>
#include "reducer.h"
#include "writer.h"
#include "values.h"
#include "record.h"
/**
* Class definition
*/
class Wrapper : public Yothalot::MapReduce
{
private:
/**
* The PHP "Yothalot\MapReduce" object that holds the implementation to all methods
* @var Php::Object
*/
Php::Object _object;
/**
* What sort of implementation do we have?
* @var enum
*/
enum {
record_reduce,
map_reduce
} _type = map_reduce;
/**
* Function to map a record
* @param record
* @param reducer
*/
virtual void map(const Yothalot::Record &record, Yothalot::Reducer &reducer) override
{
// pass to base if there is no custom
if (_type != record_reduce) return Yothalot::MapReduce::map(record, reducer);
// prevent PHP exceptions from bubbling up
try
{
// turn the record and the reducer into php objects
// @todo is it possible to skip turning the record into a shared-ptr?
Php::Object phprecord("Yothalot\\Record", new Record(std::make_shared<Yothalot::Record>(record)));
Php::Object phpreducer("Yothalot\\Reducer", new Reducer(reducer));
// forward the map call to php, don't forget to unserialize the data though
_object.call("map", phprecord, phpreducer);
}
catch (const Php::Exception &exception)
{
// this is a big problem!
Php::error << exception.what() << std::flush;
}
}
/**
* Function to map a key-value to a key/value pair
* @param key
* @param value
* @param reducer
*/
virtual void map(const Yothalot::Key &key, const Yothalot::Value &value, Yothalot::Reducer &reducer) override
{
// prevent PHP exceptions from bubbling up
try
{
// forward the map call to php, don't forget to unserialize the data though
_object.call("map", Tuple::Php(key), Tuple::Php(value), Php::Object("Yothalot\\Reducer", new Reducer(reducer)));
}
catch (const Php::Exception &exception)
{
// this is a big problem!
Php::error << exception.what() << std::flush;
}
}
/**
* Function to reduce a key that comes with a number of values
* @param key The key that should be reduced
* @param values Iteratable object with values that come with this key
* @param writer The result object to which more key/value pairs can be mapped
*/
virtual void reduce(const Yothalot::Key &key, const Yothalot::Values &values, Yothalot::Writer &writer) override
{
// prevent PHP exceptions from bubbling up
try
{
// forward the reduce call to php, the tuple will only convert the tuple to a Php::Array
_object.call("reduce", Tuple::Php(key), Php::Object("Yothalot\\Values", new Values(values)), Php::Object("Yothalot\\Writer", new Writer(writer)));
}
catch (const Php::Exception &exception)
{
// this is a big problem!
Php::error << exception.what() << std::flush;
}
}
/**
* Function to write the final result
* @param key The key for which a single value was found
* @param value The found value
*/
virtual void write(const Yothalot::Key &key, const Yothalot::Value &value) override
{
// prevent PHP exceptions from bubbling up
try
{
// forward the write call to php
_object.call("write", Tuple::Php(key), Tuple::Php(value));
}
catch (const Php::Exception &exception)
{
// this is a big problem!
Php::error << exception.what() << std::flush;
}
}
public:
/**
* Constructor
* @param object The PHP object with the implementation
*/
Wrapper(Php::Object &&object) : _object(std::move(object))
{
// make sure we're the correct type
if (_object.instanceOf("Yothalot\\MapReduce")) _type = map_reduce;
else if (_object.instanceOf("Yothalot\\RecordReduce")) _type = record_reduce;
// report an error
else Php::error << "Failed to unserialize to Yothalot\\MapReduce object" << std::flush;
}
/**
* Destructor
*/
virtual ~Wrapper() = default;
};