Skip to content

Commit

Permalink
changed work member allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
freezer333 committed Dec 9, 2015
1 parent 79a7ae6 commit 0482fef
Showing 1 changed file with 24 additions and 26 deletions.
50 changes: 24 additions & 26 deletions cpp/rainfall_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ struct Work {
uv_work_t request;
Persistent<Function> callback;

std::vector<location> * locations;
std::vector<rain_result> * results;
std::vector<location> locations;
std::vector<rain_result> results;
};

// called by libuv worker in separate thread
Expand All @@ -36,9 +36,8 @@ static void WorkAsync(uv_work_t *req)
// this is the worker thread, lets build up the results
// allocated results from the heap because we'll need
// to access in the event loop later to send back
work->results = new std::vector<rain_result>();
work->results->resize(work->locations->size());
std::transform(work->locations->begin(), work->locations->end(), work->results->begin(), calc_rain_stats);
work->results.resize(work->locations.size());
std::transform(work->locations.begin(), work->locations.end(), work->results.begin(), calc_rain_stats);


// that wasn't really that long of an operation, so lets pretend it took longer...
Expand All @@ -49,55 +48,54 @@ static void WorkAsync(uv_work_t *req)
static void WorkAsyncComplete(uv_work_t *req,int status)
{
Isolate * isolate = Isolate::GetCurrent();

// Fix for Node 4.x - thanks to https://github.com/nwjs/blink/commit/ecda32d117aca108c44f38c8eb2cb2d0810dfdeb
v8::HandleScope handleScope(isolate);

Local<Array> result_list = Array::New(isolate);
Work *work = static_cast<Work *>(req->data);

// the work has been done, and now we pack the results
// vector into a Local array on the event-thread's stack.
for (unsigned int i = 0; i < work->results->size(); i++ ) {

for (unsigned int i = 0; i < work->results.size(); i++ ) {
Local<Object> result = Object::New(isolate);
pack_rain_result(isolate, result, (*(work->results))[i]);
pack_rain_result(isolate, result, work->results[i]);
result_list->Set(i, result);
}

// set up return arguments
Handle<Value> argv[] = { result_list };

// execute the callback
// https://stackoverflow.com/questions/13826803/calling-javascript-function-from-a-c-callback-in-v8/28554065#28554065
Local<Function>::New(isolate, work->callback)->Call(isolate->GetCurrentContext()->Global(), 1, argv);
delete work;

}

void CalculateResultsAsync(const v8::FunctionCallbackInfo<v8::Value>&args) {
Isolate* isolate = args.GetIsolate();

Work * work = new Work();
work->request.data = work;

// extract each location (its a list) and store it in the work package
// locations is on the heap, accessible in the libuv threads
work->locations = new std::vector<location>();
Local<Array> input = Local<Array>::Cast(args[0]);
unsigned int num_locations = input->Length();
for (unsigned int i = 0; i < num_locations; i++) {
work->locations->push_back(unpack_location(isolate, Local<Object>::Cast(input->Get(i))));
work->locations.push_back(unpack_location(isolate, Local<Object>::Cast(input->Get(i))));
}

// store the callback from JS in the work package so we can
// store the callback from JS in the work package so we can
// invoke it later
Local<Function> callback = Local<Function>::Cast(args[1]);
work->callback.Reset(isolate, callback);

// kick of the worker thread
uv_queue_work(uv_default_loop(),&work->request,WorkAsync,WorkAsyncComplete);


args.GetReturnValue().Set(Undefined(isolate));

Expand All @@ -110,7 +108,7 @@ void CalculateResults(const v8::FunctionCallbackInfo<v8::Value>&args) {
Isolate* isolate = args.GetIsolate();
std::vector<location> locations;
std::vector<rain_result> results;

// extract each location (its a list)
Local<Array> input = Local<Array>::Cast(args[0]);
unsigned int num_locations = input->Length();
Expand Down Expand Up @@ -148,7 +146,7 @@ void pack_rain_result(v8::Isolate* isolate, v8::Local<v8::Object> & target, rain

void RainfallData(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();

location loc = unpack_location(isolate, Handle<Object>::Cast(args[0]));
rain_result result = calc_rain_stats(loc);

Expand All @@ -170,7 +168,7 @@ sample unpack_sample(Isolate * isolate, const Handle<Object> sample_obj) {

v8::String::Utf8Value utfValue(date_Value);
s.date = std::string(*utfValue);

// Unpack the numeric rainfall amount directly from V8 value
s.rainfall = rainfall_Value->NumberValue();
return s;
Expand All @@ -180,7 +178,7 @@ sample unpack_sample(Isolate * isolate, const Handle<Object> sample_obj) {

location unpack_location(Isolate * isolate, const Handle<Object> location_obj) {
location loc;

Handle<Value> lat_Value = location_obj->Get(String::NewFromUtf8(isolate,"latitude"));
Handle<Value> lon_Value = location_obj->Get(String::NewFromUtf8(isolate,"longitude"));
loc.latitude = lat_Value->NumberValue();
Expand All @@ -197,7 +195,7 @@ location unpack_location(Isolate * isolate, const Handle<Object> location_obj) {

void AvgRainfall(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();

location loc = unpack_location(isolate, Handle<Object>::Cast(args[0]));
double avg = avg_rainfall(loc);

Expand All @@ -212,7 +210,7 @@ void init(Handle <Object> exports, Handle<Object> module) {
NODE_SET_METHOD(exports, "data_rainfall", RainfallData);
NODE_SET_METHOD(exports, "calculate_results", CalculateResults);
NODE_SET_METHOD(exports, "calculate_results_async", CalculateResultsAsync);

}

NODE_MODULE(rainfall, init)

0 comments on commit 0482fef

Please sign in to comment.