ztsdb
valuevar.hpp
1 // (C) 2016 Leonardo Silvestri
2 //
3 // This file is part of ztsdb.
4 //
5 // ztsdb is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // ztsdb is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with ztsdb. If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 #ifndef VALUEVAR_HPP
20 #define VALUEVAR_HPP
21 
22 #include <string>
23 #include <vector>
24 #include <map>
25 #include <set>
26 #include <sstream>
27 #include <functional>
28 #include <memory>
29 #include <cassert>
30 #include <netinet/in.h>
31 #include <sys/timerfd.h>
32 #include "juice/variant.hpp"
33 #include "juice/variant_binary.hpp"
34 #include "ast.hpp"
35 #include "string.hpp"
36 #include "array.hpp"
37 #include "zts.hpp"
38 #include "globals.hpp"
39 #include "cow_ptr.hpp"
40 #include "timezone/interval.hpp"
41 #include "type_utils.hpp"
42 #include "main_parser/location.hpp"
43 #include "period.hpp"
44 
45 
46 using namespace Juice;
47 using namespace arr;
48 using namespace std;
49 namespace zcore {
50  struct InterpCtx;
51 }
52 
53 
54 // forward declarations:
55 namespace interp {
56  struct BaseFrame; // to avoid dependency with env.hpp
57  struct ArgFrame; // to avoid dependency with env.hpp
58  struct BuiltinFrame; // to avoid dependency with env.hpp
59  struct ClosureFrame; // to avoid dependency with env.hpp
60 }
61 
63 namespace val {
64 
65  struct VList;
66  struct VBuiltinG;
67  struct VNamed;
68  struct VClos;
69  struct VCode;
70  struct VFuture;
71  struct VTimer;
72  struct VPtr;
73  struct VConn;
74 
75  struct VNull { };
76 
77  typedef Vector<size_t> VI;
78  typedef std::shared_ptr<VI> SpVI;
79 
80  typedef Array<double> VArrayD;
81  typedef Array<zstring> VArrayS;
82  typedef Array<bool> VArrayB;
87  typedef cow_ptr<VArrayD> SpVAD;
88  typedef cow_ptr<VArrayS> SpVAS;
89  typedef cow_ptr<VArrayB> SpVAB;
90  typedef cow_ptr<VArrayDT> SpVADT;
94  typedef cow_ptr<zts> SpZts; // zts, time series, not an Array, defined in its own header
95  typedef cow_ptr<VList> SpVList;
96  typedef shared_ptr<VFuture> SpFuture;
97  typedef shared_ptr<VTimer> SpTimer;
98  typedef shared_ptr<VBuiltinG> SpBuiltin;
99  typedef shared_ptr<VConn> SpConn;
100 
101  struct VConn {
102  VConn(const string& ip_p, int port_p, Global::conn_id_t id_p);
103 
104  void setId(Global::conn_id_t id_p);
105 
106  string ip; // set this const? LLL
107  int port; // set this const? LLL
108  Global::conn_id_t id;
109 
110  ~VConn() { } // on deletion has to close the connection!!!
111  };
112 
113  struct VTimer {
114  VTimer(const uint64_t nanosecs_p,
115  shared_ptr<E> loop_p,
116  shared_ptr<E> once_p,
117  size_t loop_max_p);
118  void start();
119  void stop();
120  ~VTimer();
121 
122  uint64_t nanosecs;
123  shared_ptr<E> loop;
124  shared_ptr<E> once;
125  size_t loop_max;
126 
127  size_t loop_n;
128  size_t loop_failed_n;
129 
130  int fd;
131  bool done_first;
132  };
133 
134  struct VError {
135  zstring what;
136  };
137 
138  // these are the values that will be given back by Value::which:
139  enum ValType {
140  vt_std_string,
141  vt_std_int,
142 
143  vt_double,
144  vt_bool,
145  vt_time,
146  vt_duration,
147  vt_interval,
148  vt_period,
149  vt_string,
150  vt_zts,
151  vt_list,
152  vt_null,
153  vt_code,
154  vt_clos,
155  vt_builting,
156  vt_future,
157  vt_connection,
158  vt_timer,
159  vt_named, // used exclusively by encode to transmit name/value pairs
160  vt_error, // used exclusively to transmit an error over TCP
161  vt_ptr // used exclusively by interpreter to keep original address
162  };
163 
164 
165  const map<int, string> vt_to_string = {
166  {0, "encode_std_string"},
167  {1, "encode_std_int"},
168  {2, "double"},
169  {3, "logical"},
170  {4, "datetime"},
171  {5, "duration"},
172  {6, "interval"},
173  {7, "period"},
174  {8, "string"},
175  {9, "zts"},
176  {10, "list"},
177  {11, "NULL"},
178  {12, "expression"},
179  {13, "closure"},
180  {14, "builtin"},
181  {15, "future"},
182  {16, "connection"},
183  {17, "timer"},
184  {18, "named"},
185  {19, "error"},
186  {20, "vptr"}
187  };
188 
189 
191  template<val::ValType V> struct gettype { }; // fails when trying to get TP
192  template<> struct gettype<vt_double> { typedef SpVAD TP; };
193  template<> struct gettype<vt_bool> { typedef SpVAB TP; };
194  template<> struct gettype<vt_time> { typedef SpVADT TP; };
195  template<> struct gettype<vt_duration> { typedef SpVADUR TP; };
196  template<> struct gettype<vt_interval> { typedef SpVAIVL TP; };
197  template<> struct gettype<vt_period> { typedef SpVAPRD TP; };
198  template<> struct gettype<vt_string> { typedef SpVAS TP; };
199  template<> struct gettype<vt_zts> { typedef SpZts TP; };
200  template<> struct gettype<vt_list> { typedef SpVList TP; };
201  template<> struct gettype<vt_null> { typedef VNull TP; };
202 
203  template<val::ValType V> struct getelttype { }; // fails when trying to get TP
204  template<> struct getelttype<vt_double> { typedef double TP; };
205  template<> struct getelttype<vt_bool> { typedef bool TP; };
206  template<> struct getelttype<vt_time> { typedef Global::dtime TP; };
207  template<> struct getelttype<vt_duration> { typedef Global::duration TP; };
208  template<> struct getelttype<vt_interval> { typedef tz::interval TP; };
209  template<> struct getelttype<vt_period> { typedef tz::period TP; };
210  template<> struct getelttype<vt_string> { typedef arr::zstring TP; };
211 
212  template<typename T> struct rmptr { }; // fails when trying to get TP
213  template<> struct rmptr<SpVAD> { typedef VArrayD TP; };
214  template<> struct rmptr<SpVAB> { typedef VArrayB TP; };
215  template<> struct rmptr<SpVADT> { typedef VArrayDT TP; };
216  template<> struct rmptr<SpVADUR> { typedef VArrayDUR TP; };
217  template<> struct rmptr<SpVAIVL> { typedef VArrayIVL TP; };
218  template<> struct rmptr<SpVAPRD> { typedef VArrayPRD TP; };
219  template<> struct rmptr<SpVAS> { typedef VArrayS TP; };
220  template<> struct rmptr<SpZts> { typedef zts TP; };
221  template<> struct rmptr<SpVList> { typedef VList TP; };
222 
223  typedef int64_t integer_t;
224 
225  typedef Variant<std::string
226  ,SpVI
227  ,SpVAD
228  ,SpVAB
229  ,SpVADT
230  ,SpVADUR
231  ,SpVAIVL
232  ,SpVAPRD
233  ,SpVAS
234  ,SpZts
235  ,SpVList
236  ,VNull
237  ,recursive_wrapper<VCode> // probably does not need wrapper LLL
238  ,std::shared_ptr<VClos>
239  ,SpBuiltin
240  ,SpFuture
241  ,VConn
242  ,SpTimer
243  ,recursive_wrapper<VNamed>
244  ,VError
245  ,recursive_wrapper<VPtr>
246  > Value;
247 
248 
250  struct VCode {
251  VCode(const E* e) : expr(e->clone()) { }
252  VCode(shared_ptr<E> e) : expr(e) { }
253  shared_ptr<E> expr;
254  };
255 
256 
257  struct VPtr {
258  VPtr(Value& val) {
259  if (val.which() == vt_ptr) {
260  auto& vp = get<VPtr>(val);
261  p = vp.p;
262  }
263  else {
264  p = &val;
265  }
266  }
267  Value* p;
268  };
269 
270 
271 #ifdef ZTSDB_CLIENT
272  struct VBuiltinG {
273  VBuiltinG() : _signature(0), signature(&_signature) { }
274  int _signature;
275  int* signature; // so display will work
276  };
277 #else
278  #include "valuevar_ic.hpp"
279 #endif
280 
281 
284  struct VClos { // call it VFun now it's not a closure LLL
285  VClos(const Function* f_a /*, BaseFrame* r_a */);
286 
287  VClos(const VClos& v) {
288  //cout << "calling VClos copy constructor" << endl;
289  f = v.f;
290  argMap = v.argMap;
291  ellipsisPos = v.ellipsisPos;
292  // r = v.r;
293  }
294 
295  VClos(VClos&& v) {
296  //cout << "calling VClos move constructor" << endl;
297  swap(v);
298  }
299 
300  VClos& operator=(const VClos& v) {
301  //cout << "calling VClos copy assignment" << endl;
302  f = v.f;
303  argMap = v.argMap;
304  ellipsisPos = v.ellipsisPos;
305  // r = v.r;
306  return *this;
307  }
308 
309  VClos& operator=(VClos&& v) {
310  //cout << "calling VClos move assignment" << endl;
311  return swap(v);
312  }
313 
314  VClos& swap(VClos& v) {
315  f = v.f;
316  v.f = nullptr;
317  std::swap(argMap, v.argMap);
318  std::swap(ellipsisPos, v.ellipsisPos);
319  // std::swap(r, v.r);
320  return *this;
321  }
322 
323  std::shared_ptr<Function> f;
324  map<string, int> argMap;
325  int ellipsisPos;
326 
327  // For the time being at least, no closures. It complicates memory
328  // management very significantly and in the context of a database
329  // manipulation language I don't see any big advantage:
330 
331  // BaseFrame* r;
332  };
333 
334 
335  // Note that a future is never sent over (a request is, but not a future!)
336  struct VFuture {
342  VFuture() : val(nullptr) { }
343 
344  void setvalptr(val::Value& val_p, const std::shared_ptr<interp::BaseFrame>& frame_p);
345 
346  Value* getvalptr();
347 
348  std::string to_string() const;
349 
350  // private:
351  Value* val;
352 
353  // it is important to not have shared_ptr here because else a
354  // circular reference can be introduced when a future is created
355  // in a nested frame:
356  std::weak_ptr<interp::BaseFrame> frame;
357  };
358 
359 
360  struct VList {
361  VList();
362  VList(const Array<Value>& a_p);
363  VList(const VList& l);
364 
365  inline void push_back(pair<string, Value> p) { a.concat(p.second, p.first); }
366  inline size_t size() const { return a.size(); }
367 
369  inline VList subsetRows(idx_type from, idx_type to, bool addrownums=false) const {
370  return VList(a.subsetRows(from, to, addrownums));
371  }
372  inline const Vector<idx_type>& getdim() const { return a.getdim(); }
373  inline const idx_type getdim(idx_type d) const { return a.getdim(d); }
374  inline Vector<zstring> getNamesVector(idx_type d) const { return a.getNamesVector(d); }
375 
376  VList& remove(arr::idx_type i);
377 
378  void at(arr::idx_type i, const val::Value& v);
379  void at(arr::idx_type i, val::Value&& v);
380  inline Value operator[](arr::idx_type i) const {
381  return a[i];
382  }
383  Value operator[](const std::string& s);
384 
385  Array<Value> a;
386  };
387 
388 
389  struct VNamed {
390  Value name;
391  Value val;
392  };
393 
394 
395  // end of type definitions
396 
397  template<class UnaryPredicate>
398  bool any_of(const val::Value& v, UnaryPredicate p) {
399  if (v.which() == vt_list) {
400  const auto& vl = get<val::SpVList>(v);
401  for (size_t i=0; i<vl->size(); ++i) {
402  auto res = any_of((vl->a)[i], p);
403  if (res) {
404  return true;
405  }
406  }
407  }
408  else {
409  return p(v);
410  }
411  return false;
412  }
413 
414  // ------------------------------------------------
415 
416  struct Typeof {
417  typedef string result_type;
418  string operator()(const SpVList&) const { return "list"; }
419  string operator()(const VNull&) const { return "NULL"; }
420  string operator()(const VCode&) const { return "expression"; }
421  string operator()(const std::shared_ptr<VClos>&) const { return "function"; }
422  string operator()(const VConn&) const { return "connection"; }
423  string operator()(const VTimer&) const { return "timer"; }
424  string operator()(const SpBuiltin&) const { return "builtin"; }
425  string operator()(const SpFuture&) const { return "future"; }
426  string operator()(const SpVAD&) const { return "double"; }
427  string operator()(const SpVAS&) const { return "character"; }
428  string operator()(const SpVAB&) const { return "logical"; }
429  string operator()(const SpVADT&) const { return "nanotime"; }
430  string operator()(const SpVADUR&) const { return "nanoduration"; }
431  string operator()(const SpVAIVL&) const { return "nanoival"; }
432  string operator()(const SpVAPRD&) const { return "nanoperiod"; }
433  string operator()(const SpZts&) const { return "zts"; }
434 
435  string operator()(const VArrayD&) const { return "double"; }
436  string operator()(const VArrayS&) const { return "character"; }
437  string operator()(const VArrayB&) const { return "logical"; }
438  string operator()(const VArrayDT&) const { return "nanotime"; }
439  string operator()(const VArrayDUR&) const { return "nanoduration"; }
440  string operator()(const VArrayIVL&) const { return "nanoival"; }
441  string operator()(const VArrayPRD&) const { return "nanoperiod"; }
442  string operator()(const arr::zts&) const { return "zts"; }
443  string operator()(const VList&) const { return "list"; }
444  string operator()(const VClos&) const { return "function"; }
445  string operator()(const VError&) const { return "error"; }
446 
447  template <typename T>
448  string operator()(const T& t) const { return "unknown"; }
449  };
450 
451  struct SizeOf {
452  typedef size_t result_type;
453  size_t operator()(const VNull& x) const { return 0; }
454  size_t operator()(const SpVList& x) const { return x->size(); }
455  size_t operator()(const SpVAD& x) const { return x->size(); }
456  size_t operator()(const SpVAS& x) const { return x->size(); }
457  size_t operator()(const SpVAB& x) const { return x->size(); }
458  size_t operator()(const SpVADT& x) const { return x->size(); }
459  size_t operator()(const SpVADUR& x) const { return x->size(); }
460  size_t operator()(const SpVAIVL& x) const { return x->size(); }
461  size_t operator()(const SpVAPRD& x) const { return x->size(); }
462  size_t operator()(const SpZts& x) const { return x->size(); }
463 
464  template <typename T>
465  size_t operator()(const T&) const { return 1; }
466  };
467 
468  inline bool operator==(const VNamed& p1, const VNamed& p2) {
469  return p1.name == p2.name && p1.val == p2.val;
470  }
471  inline bool operator==(const VNull& p1, const VNull& p2) { return true; }
472  inline bool operator==(const VFuture& p1, const VFuture& p2) { return false; }
473  inline bool operator==(const SpVList& p1, const SpVList& p2) { return p1->a == p2->a; }
474  inline bool operator==(const VError& p1, const VError& p2) { return p1.what == p2.what; }
475 
476  // for these it's preferable to throw "not implemented"
477  inline bool operator==(const VCode& p1, const VCode& p2) { return false; }
478  inline bool operator==(const VClos& p1, const VClos& p2) { return false; }
479  inline bool operator==(const VConn& p1, const VConn& p2) { return false; }
480  inline bool operator==(const VTimer& p1, const VTimer& p2) { return false; }
481  inline bool operator==(const VBuiltinG& p1, const VBuiltinG& p2) { return false; }
482  inline bool operator==(const VPtr& p1, const VPtr& p2) { return false; }
483 
484  inline size_t size(const val::Value& v) { return apply_visitor(val::SizeOf(), v); }
485 
487  template<typename T>
488  inline arr::cow_ptr<arr::Array<T>> make_array(const T& t) {
489  return arr::make_cow<arr::Array<T>>(false,
491  arr::Vector<T>{t},
492  vector<arr::Vector<arr::zstring>>());
493  }
494 
495  template<typename T>
496  inline T get_scalar(const Value& v) {
497  const auto& a = get<arr::cow_ptr<arr::Array<T>>>(v);
498  if (a->size() != 1) {
499  throw std::out_of_range("expecting scalar value");
500  }
501  return (*a)[0];
502  }
503 
504  void setTmp(Value& v);
505  void resetTmp(Value& v);
506  void setConst(Value& v);
507  void setLast(Value& v);
508  void setLock(Value& v);
509  void resetLock(Value& v);
510  void setRef(Value& v);
511  void resetRef(Value& v);
512  bool isLocked(const Value& v);
513  bool isRef(const Value& v);
514  bool isTmp(const Value& v);
515  bool isConst(const Value& v);
516 
517 } // end namespace val
518 
519 
520 namespace arr {
521  template<>
522  inline val::Value getInitValue() {
523  return val::VNull();
524  }
525 
526  TYPE_NB(val::Value, 7);
527  TYPE_NAME(val::Value, "Value");
528 
529  template<>
530  inline val::Value convert(const val::Value& u) {
531  return u;
532  }
533 
534  template<typename T>
535  inline bool operator==(const cow_ptr<Array<T>>& a1, const cow_ptr<Array<T>>& a2) {
536  return *a1 == *a2;
537  }
538 
539  inline bool operator==(const val::SpZts& a1, const val::SpZts& a2) { return *a1 == *a2; }
540 
541  inline bool operator==(const val::SpVI& a1, const val::SpVI& a2) { return *a1 == *a2; }
542 
543  inline bool operator!=(const val::Value& v1, const val::Value& v2) { return !(v1 == v2); }
544 
545 } // end namespace arr
546 
547 // In the same spirit as the above definition, we include here the
548 // specialization of 'Vector<T>' for T = 'Value'. Indeed, 'Value' has
549 // members that allocate memory (e.g. through smart pointers), so
550 // memory freeing would not work properly without this specialization.
551 #include "valuevector.hpp"
552 
553 #endif
E
Definition: ast.hpp:76
val::VNull
Definition: valuevar.hpp:75
val::gettype
Mapping from ValType to type.
Definition: valuevar.hpp:191
arr::cow_ptr
Definition: cow_ptr.hpp:42
tz::period
Definition: period.hpp:30
arr::Vector< size_t >
val::getelttype
Definition: valuevar.hpp:203
arr::ZString
Definition: string.hpp:33
val
Contains the types that constitute the output of an evaluation by the interpreter.
Definition: display.hpp:31
val::VFuture
Definition: valuevar.hpp:336
val::VCode
Code value. This type contains code (as a result).
Definition: valuevar.hpp:250
val::Typeof
Definition: valuevar.hpp:416
val::VClos
Definition: valuevar.hpp:284
val::VTimer
Definition: valuevar.hpp:113
tz::interval
Definition: interval.hpp:31
val::VList
Definition: valuevar.hpp:360
val::rmptr
Definition: valuevar.hpp:212
val::VNamed
Definition: valuevar.hpp:389
val::VList::subsetRows
VList subsetRows(idx_type from, idx_type to, bool addrownums=false) const
These allow 'VList' to be used in a template the same way as 'Array<T>':
Definition: valuevar.hpp:369
Function
Definition: ast.hpp:449
val::VFuture::VFuture
VFuture()
Definition: valuevar.hpp:342
val::VError
Definition: valuevar.hpp:134
arr::zts
Definition: zts.hpp:35
location.hpp
arr
Contains the classes and functions that implement a multidimentional array type.
Definition: allocator.hpp:29
val::VConn
Definition: valuevar.hpp:101
val::SizeOf
Definition: valuevar.hpp:451
interp
Struct and functions implementing the interpreter.
Definition: env.hpp:36
arr::convert
val::Value convert(const double &u)
these are the set of "conversions" of a type to itself
Definition: base_funcs_array.cpp:61
arr::Array
Definition: array.hpp:109
VBuiltinG
Definition: valuevar_ic.hpp:23
val::VPtr
Definition: valuevar.hpp:257