xref: /5.5.2/couchdb/src/mapreduce/mapreduce.h (revision 49e10b8b)
1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/**
3 * @copyright 2012 Couchbase, Inc.
4 *
5 * @author Filipe Manana  <filipe@couchbase.com>
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8 * use this file except in compliance with the License. You may obtain a copy of
9 * the License at
10 *
11 *  http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 * License for the specific language governing permissions and limitations under
17 * the License.
18 **/
19
20#ifndef _MAPREDUCE_H
21#define _MAPREDUCE_H
22
23#include <cstddef>
24#include <iostream>
25#include <string>
26#include <list>
27#include <vector>
28#include <atomic>
29#include <include/v8.h>
30#include <platform/platform.h>
31
32#include "erl_nif_compat.h"
33#include "nif_stl_allocator.h"
34
35class MapReduceError;
36
37typedef std::list<ErlNifBinary, NifStlAllocator<ErlNifBinary> >  json_results_list_t;
38typedef std::list<ErlNifBinary, NifStlAllocator<ErlNifBinary> >  log_results_list_t;
39typedef std::pair<ErlNifBinary, ErlNifBinary>  kv_pair_t;
40typedef std::list< kv_pair_t, NifStlAllocator< kv_pair_t > >  kv_pair_list_t;
41
42typedef enum {
43    VIEW_INDEX_TYPE_MAPREDUCE,
44    VIEW_INDEX_TYPE_SPATIAL
45}  view_index_type_t;
46
47typedef enum {
48    MAP_KVS,
49    MAP_ERROR
50} map_result_type_t;
51
52typedef struct {
53    map_result_type_t type;
54    union {
55        kv_pair_list_t *kvs;
56        ErlNifBinary *error;
57    } result;
58} map_result_t;
59
60typedef std::list< map_result_t,
61                   NifStlAllocator< map_result_t > >  map_results_list_t;
62
63typedef std::vector< v8::Persistent<v8::Function>*,
64                     NifStlAllocator< v8::Persistent<v8::Function>* > >  function_vector_t;
65
66typedef std::basic_string< char,
67                           std::char_traits<char>,
68                           NifStlAllocator<char> >  function_source_t;
69
70typedef std::list< function_source_t,
71                   NifStlAllocator< function_source_t > >  function_sources_list_t;
72
73class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
74public:
75    virtual void* Allocate(size_t length) {
76        void* data = AllocateUninitialized(length);
77        return data == NULL ? data : memset(data, 0, length);
78    }
79
80    virtual void* AllocateUninitialized(size_t length) {
81        return malloc(length);
82    }
83
84    virtual void Free(void* data, size_t) {
85        free(data);
86    }
87};
88
89typedef struct {
90    v8::Persistent<v8::Context>                  jsContext;
91    v8::Isolate                                  *isolate;
92    ArrayBufferAllocator                         *bufAllocator;
93    function_vector_t                            *functions;
94    kv_pair_list_t                               *kvs;
95    unsigned int                                 key;
96    ErlNifEnv                                    *env;
97    std::atomic<hrtime_t>                        taskStartTime;
98    int                                          emitKvSize;
99    int                                          maxEmitKvSize;
100    bool                                         isDocUsed;
101    log_results_list_t                           *logResults;
102    view_index_type_t                            viewType;
103} map_reduce_ctx_t;
104
105
106void initContext(map_reduce_ctx_t *ctx, const function_sources_list_t &funs,
107                 const view_index_type_t viewType);
108void destroyContext(map_reduce_ctx_t *ctx);
109
110map_results_list_t mapDoc(map_reduce_ctx_t *ctx,
111                          const ErlNifBinary &doc,
112                          const ErlNifBinary &meta);
113
114json_results_list_t runReduce(map_reduce_ctx_t *ctx,
115                              const json_results_list_t &keys,
116                              const json_results_list_t &values);
117
118ErlNifBinary runReduce(map_reduce_ctx_t *ctx, int reduceFunNum,
119                       const json_results_list_t &keys,
120                       const json_results_list_t &values);
121
122ErlNifBinary runRereduce(map_reduce_ctx_t *ctx,
123                         int reduceFunNum,
124                         const json_results_list_t &reductions);
125
126void terminateTask(map_reduce_ctx_t *ctx);
127
128/**
129* This API needs to be called once per process to initialize
130* v8 javascript engine. This needs to be called before
131* any v8 APIs like creating v8 isolate and v8 context.
132**/
133void initV8();
134
135/**
136* This API needs to be called once per process to cleanup
137* v8 resources. This needs to be called after disposing all
138* v8 thread contexts like v8 isolate and v8 context.
139**/
140void deinitV8();
141
142void setOptimizeDocLoadFlag(const char *);
143
144class MapReduceError {
145public:
146    MapReduceError(const char *msg) : _msg(msg) {
147    }
148
149    MapReduceError(const std::string &msg) : _msg(msg) {
150    }
151
152    const std::string& getMsg() const {
153        return _msg;
154    }
155
156private:
157    const std::string _msg;
158};
159
160
161#endif
162