function constructor() { list($body, $source) = args(func_get_args(), 2); $this->source = $source['source']; $this->guard = isset($source['guard']) ? $source['guard'] : NULL; $this->step = isset($source['step']) ? $source['step'] : NULL; $this->name = isset($source['name']) ? $source['name'] : NULL; $this->index = isset($source['index']) ? $source['index'] : NULL; $this->body = yy_Block::wrap(array($body)); $this->own = isset($source['own']) && $source['own']; $this->object = isset($source['object']) && $source['object']; if ($this->object) { $tmp = $this->name; $this->name = $this->index; $this->index = $tmp; } if ($this->index instanceof yy_Value) { throw SyntaxError('index cannot be a pattern matching expression'); } $this->range = $this->source instanceof yy_Value && $this->source->base instanceof yy_Range && !count($this->source->properties); $this->pattern = $this->name instanceof yy_Value; if ($this->range && $this->index) { throw SyntaxError('indexes do not apply to range loops'); } if ($this->range && $this->pattern) { throw SyntaxError('cannot pattern match over range loops'); } $this->returns = FALSE; return $this; }
function constructor() { list($condition, $options) = args(func_get_args(), 0, array(NULL, NULL)); $this->condition = isset($options['invert']) && $options['invert'] ? $condition->invert() : $condition; $this->guard = isset($options['guard']) ? $options['guard'] : NULL; return $this; }
function _defineStdMathFunction($name, $args, $ret, $lib) { $f = function () use($name, $args, $ret, $lib) { $inputs = []; $count = 0; foreach ($args as $arg) { $inputs['arg' . $count] = lookupType($arg); $count += 1; } $retType = lookupType($ret); $hash = \grokit\hashComplex(['BASE::' . $name, $args, $ret]); ?> inline <?php echo $retType; ?> <?php echo $name; ?> ( <?php echo typed_args($inputs); ?> ) { return std::<?php echo $name; ?> (<?php echo args($inputs); ?> ); } <?php return ['kind' => 'FUNCTION', 'name' => $name, 'input' => $inputs, 'result' => $retType, 'deterministic' => true, 'system_headers' => $lib, 'hash' => $hash]; }; declareFunction($name, $args, $f); }
function assigns() { list($name) = args(func_get_args(), 1); if ($this->context === 'object') { return $this->value->assigns($name); } else { return $this->variable->assigns($name); } }
/** * Return single arg with index starting at zero */ function arg($index) { $args = args(); if (array_key_exists($index, $args)) { return $args[$index]; } else { error('Missing Argument'); exit; } }
/** * A GLA that determines the distinct values of a dataset. */ function Distinct(array $t_args, array $input, array $output) { grokit_assert(\count($input) == \count($output), 'Distinct must have the same outputs as inputs.'); $outputsToInputs = []; $i = 0; foreach ($input as $name => $type) { $outputsToInputs[array_keys($output)[$i]] = $name; array_set_index($output, $i++, $type); } $useMCT = get_default($t_args, 'use.mct', true); $initSize = get_default($t_args, 'init.size', 65536); $keepHashes = get_default($t_args, 'mct.keep.hashes', false); $fragmentSize = get_default($t_args, 'fragment.size', 100000); $nullCheck = get_default($t_args, 'null.check', false); grokit_assert(is_bool($useMCT), 'Distinct use.mct argument must be boolean'); grokit_assert(is_integer($initSize), 'Distinct init.size argument must be an integer'); grokit_assert($initSize > 0, 'Distinct init.size argument must be positive'); grokit_assert(is_bool($keepHashes), 'Distinct mct.keep.hashes argument must be boolean'); grokit_assert(is_integer($fragmentSize), 'Distinct fragment.size argument must be integral'); grokit_assert($fragmentSize > 0, 'Distinct fragment.size argumenst must be positive'); $nullable = []; if (is_bool($nullCheck)) { foreach ($input as $name => $type) { $nullable[$name] = $nullCheck; } } else { if (is_array($nullCheck)) { foreach ($input as $name => $type) { $nullable[$name] = false; } foreach ($nullCheck as $index => $n) { grokit_assert(is_string($n), 'Distinct null.check has invalid value at position ' . $index); grokit_assert(array_key_exists($n, $nullable), 'Distinct null.check has unknown input ' . $n . ' at position ' . $index); $nullable[$n] = true; } } else { grokit_error('Distinct null.check must be boolean or list of inputs to check for nulls'); } } $keepHashesText = $keepHashes ? 'true' : 'false'; $system_headers = ['cinttypes', 'functional', 'vector']; if ($useMCT) { $system_headers[] = 'mct/hash-set.hpp'; $definedSet = "mct::closed_hash_set<Key, HashKey, std::equal_to<Key>, std::allocator<Key>, {$keepHashesText}>"; } else { $system_headers[] = 'unordered_map'; $definedSet = "std::unordered_set<Key, HashKey, std::equal_to<Key>, std::allocator<Key>>"; } $className = generate_name('Distinct'); ?> class <?php echo $className; ?> { public: // Value being placed into the set. struct Key { <?php foreach ($input as $name => $type) { ?> <?php echo $type; ?> <?php echo $name; ?> ; <?php } // for each input ?> // Construct the value by copying all of the attributes. Key(<?php echo const_typed_ref_args($input); ?> ) : <?php $first = true; foreach ($input as $name => $type) { ?> <?php echo $first ? ' ' : ','; ?> <?php echo $name; ?> (<?php echo $name; ?> ) <?php $first = false; } // for each input ?> { } bool operator==(const Key & o ) const { return true <?php echo array_template("&& ({key} == o.{key})", ' ', $input); ?> ; } size_t hash_value() const { uint64_t hash = H_b; <?php foreach ($input as $name => $type) { ?> hash = CongruentHash(Hash(<?php echo $name; ?> ), hash); <?php } // for each input ?> return size_t(hash); } }; // Hashing functor for our value struct HashKey { size_t operator()(const Key& o) const { return o.hash_value(); } }; using Set = <?php echo $definedSet; ?> ; // Iterator object used in multi and fragment result types class Iterator { public: using iterator_t = Set::const_iterator; private: iterator_t start; iterator_t end; public: Iterator() : start(), end() { } Iterator( const iterator_t & _start, const iterator_t & _end ) : start(_start), end(_end) { } Iterator( const Iterator & o ) : start(o.start), end(o.end) { } bool GetNextResult(<?php echo typed_ref_args($output); ?> ) { if( start != end ) { <?php foreach ($output as $name => $type) { ?> <?php echo $name; ?> = start-><?php echo $outputsToInputs[$name]; ?> ; <?php } // for each output ?> start++; return true; } else { return false; } } }; private: // Constants static constexpr size_t INIT_SIZE = <?php echo $initSize; ?> ; static constexpr size_t FRAG_SIZE = <?php echo $fragmentSize; ?> ; // Member variables uint64_t count; // Total # tuples seen Set distinct; // Set of distinct values using IteratorList = std::vector<Iterator>; Iterator multiIterator; // Internal iterator for multi result type IteratorList fragments; // Iterator for fragments public: <?php echo $className; ?> () : count(0), distinct(INIT_SIZE), multiIterator(), fragments() { } ~<?php echo $className; ?> () { } void Reset(void) { count = 0; distinct.clear(); } void AddItem(<?php echo const_typed_ref_args($input); ?> ) { count++; <?php foreach ($nullable as $name => $check) { if ($check) { ?> if( IsNull( <?php echo $name; ?> ) ) return; <?php } // if checking for nulls } // foreach input ?> Key key(<?php echo args($input); ?> ); distinct.insert(key); /* auto it = distinct.find(key); if( it == distinct.end() ) { distinct.insert(key); } */ } void AddState( <?php echo $className; ?> & other ) { for( auto & elem : other.distinct ) { distinct.insert(elem); /* auto it = distinct.find(elem); if( it == distinct.end() ) { distinct.insert(elem); } */ } count += other.count; } // Multi interface void Finalize(void) { multiIterator = Iterator(distinct.cbegin(), distinct.cend()); } bool GetNextResult(<?php echo typed_ref_args($output); ?> ) { return multiIterator.GetNextResult(<?php echo args($output); ?> ); } // Fragment interface int GetNumFragments(void) { fragments.clear(); int nFrag = 0; Iterator::iterator_t prev = distinct.cbegin(); Iterator::iterator_t end = distinct.cend(); Iterator::iterator_t next = prev; while( next != end ) { for( size_t i = 0; next != end && FRAG_SIZE > i; i++ ) { next++; } Iterator nIter(prev, next); fragments.push_back(nIter); prev = next; nFrag++; } return nFrag; } Iterator * Finalize(int fragment) { return new Iterator(fragments[fragment]); } bool GetNextResult(Iterator * it, <?php echo typed_ref_args($output); ?> ) { return it->GetNextResult(<?php echo args($output); ?> ); } // General methods uint64_t get_count() const { return count; } uint64_t get_countDistinct() const { return distinct.size(); } const Set & get_distinct() const { return distinct; } }; typedef <?php echo $className; ?> ::Iterator <?php echo $className; ?> _Iterator; <?php return ['kind' => 'GLA', 'name' => $className, 'input' => $input, 'output' => $output, 'result_type' => ['multi', 'fragment'], 'user_headers' => ['HashFunctions.h'], 'system_headers' => $system_headers, 'properties' => ['resettable']]; }
function Multiplexer(array $t_args, array $inputs, array $outputs) { $className = generate_name('Multiplexer'); if (\count($inputs) == 0) { grokit_assert(array_key_exists('input', $t_args), 'No inputs specified for Multiplexer'); $inputs = $t_args['input']; foreach ($t_args['inputs'] as $name => &$type) { if (is_identifier($type)) { $type = lookupType(strval($type)); } grokit_assert(is_datatype($type), 'Only types may be specified as inputs to Multiplexer.'); } $inputs = ensure_valid_names($inputs, 'multi_input'); } $glas = get_first_key($t_args, ['glas', 0]); grokit_assert(\count($glas) > 0, 'No GLAs specified for Multiplexer.'); $myGLAs = []; $glaInputs = []; $glaOutputs = []; $resultType = 'multi'; $usedOutputs = []; $libraries = []; $glaGenStates = []; $glaReqStates = []; $configurable = false; $constArgs = []; $genStates = []; $reqStates = []; $iterable = null; foreach ($glas as $name => $glaInfo) { grokit_assert(is_array($glaInfo), 'Template argument \'glas\' must be an array'); grokit_assert(array_key_exists('gla', $glaInfo), 'No GLA given for glas[' . $name . ']'); grokit_assert(array_key_exists('inputs', $glaInfo), 'No inputs given for glas[' . $name . ']'); grokit_assert(array_key_exists('outputs', $glaInfo), 'No outputs given for glas[' . $name . ']'); $gla = $glaInfo['gla']; $glaInAtts = $glaInfo['inputs']; $glaOutAtts = $glaInfo['outputs']; grokit_assert(is_gla($gla), 'Non-GLA given for glas[' . $name . '][gla]'); grokit_assert(is_array($glaInAtts), 'Non-array given for inputs for gla ' . $name); grokit_assert(is_array($glaOutAtts), 'Non-array given for outputs for gla ' . $name); $glaInAtts = array_map('strval', $glaInAtts); $glaOutAtts = array_map('strval', $glaOutAtts); $glaName = "innerGLA_" . $name; $glaInputs[$glaName] = []; $glaOutputs[$glaName] = []; foreach ($glaInAtts as $att) { grokit_assert(array_key_exists($att, $inputs), 'Input ' . $att . ' for GLA ' . $name . ' not found in inputs'); $glaInputs[$glaName][$att] = $inputs[$att]; } foreach ($glaOutAtts as $att) { grokit_assert(array_key_exists($att, $outputs), 'Output ' . $att . ' for GLA ' . $name . ' not found in outputs'); grokit_assert(!in_array($att, $usedOutputs), 'Output ' . $att . ' used by multiple GLAs'); $usedOutputs[] = $att; $glaOutputs[$glaName][$att] = $outputs[$att]; } //fwrite(STDERR, "Inputs for GLA " . $glaName . ": " . print_r($glaInputs[$glaName], true) . PHP_EOL ); //fwrite(STDERR, "Outputs for GLA " . $glaName . ": " . print_r($glaOutputs[$glaName], true) . PHP_EOL ); $gla = $gla->apply($glaInputs[$glaName], $glaOutputs[$glaName]); $myGLAs[$glaName] = $gla; $glaRez[$glaName] = get_first_value($gla->result_type(), ['multi', 'single', 'state']); $libraries = array_merge($libraries, $gla->libraries()); if ($glaRez[$glaName] == 'state') { grokit_assert(\count($glaOutputs[$glaName]) == 1, "GLA {$glaName} is produced as state, and thus must have exactly 1 output."); $stateType = lookupType('base::STATE', ['type' => $gla]); $glaOutputs[$glaName] = array_combine(array_keys($glaOutputs[$glaName]), [$stateType]); } else { grokit_assert(\count($glaOutputs[$glaName]) == \count($gla->output()), 'GLA ' . $glaName . ' produces different number of outputs than expected'); $glaOutputs[$glaName] = array_combine(array_keys($glaOutputs[$glaName]), $gla->output()); } // Set types for our output foreach ($glaOutputs[$glaName] as $attName => $type) { $outputs[$attName] = $type; } if (is_null($iterable)) { $iterable = $gla->iterable(); } else { grokit_assert($iterable == $gla->iterable(), 'Multiplexer does not support mixing iterable and non-iterable GLAs'); } $glaReqStates[$glaName] = $gla->req_states(); foreach ($gla->req_states() as $rstate) { $reqStates[] = $rstate; } $glaGenStates[$glaName] = $gla->state(); // TODO: Support constant states grokit_assert(!$gla->has_state(), 'Multiplexer currently does not support constant states.'); } $libraries = array_unique($libraries); $extra = ['glas' => $myGLAs]; ?> class <?php echo $className; ?> { <?php foreach ($myGLAs as $name => $type) { ?> <?php echo $type; ?> <?php echo $name; ?> ; <?php } // foreach inner gla ?> class Iterator { bool _gotResultsOnce; bool _valid; <?php foreach ($myGLAs as $name => $type) { ?> <?php echo $type; ?> * it_<?php echo $name; ?> ; <?php } // foreach inner gla ?> public: Iterator(void) : _gotResultsOnce(false), _valid(false), <?php echo array_template('it_{key}(nullptr)', ', ', $myGLAs); ?> { } Iterator(<?php echo typed_ref_args($myGLAs); ?> ) : _gotResultsOnce(false), _valid(true), <?php echo array_template('it_{key}(&{key})', ', ', $myGLAs); ?> { <?php foreach ($myGLAs as $name => $type) { if ($glaRez[$name] == 'multi') { ?> <?php echo $name; ?> .Finalize(); <?php } // if inner GLA is multi } // foreach inner gla ?> } Iterator( const Iterator & other) = default; ~Iterator() { } bool GetNextResult( <?php echo typed_ref_args($outputs); ?> ) { FATALIF(!_valid, "Tried to get results from an invalid iterator."); bool ret = !_gotResultsOnce; _gotResultsOnce = true; <?php foreach ($myGLAs as $name => $type) { if ($glaRez[$name] == 'multi') { ?> ret |= it_<?php echo $name; ?> ->GetNextResult(<?php echo args($glaOutputs[$name]); ?> ); <?php } // if inner GLA is multi } // foreach inner gla ?> if( ret ) { <?php foreach ($myGLAs as $name => $type) { if ($glaRez[$name] == 'single') { ?> it_<?php echo $name; ?> ->GetResult(<?php echo args($glaOutputs[$name]); ?> ); <?php } else { if ($glaRez[$name] == 'state') { $stateVar = array_keys($glaOutputs[$name])[0]; $stateType = $glaOutputs[$name][$stateVar]; ?> <?php echo $stateVar; ?> = <?php echo $stateType; ?> (it_<?php echo $name; ?> ); <?php } } // if inner GLA is state } // foreach inner gla ?> } return ret; } }; Iterator multiIterator; public: <?php echo $className; ?> () { } ~<?php echo $className; ?> () { } void AddItem(<?php echo const_typed_ref_args($inputs); ?> ) { // Call AddItem individually on each GLA. <?php foreach ($myGLAs as $gName => $gType) { ?> <?php echo $gName; ?> .AddItem(<?php echo args($glaInputs[$gName]); ?> ); <?php } // foreach inner gla ?> } void AddState( <?php echo $className; ?> & other ) { // Call AddState individually on each GLA. <?php foreach ($myGLAs as $gName => $gType) { ?> <?php echo $gName; ?> .AddState(other.<?php echo $gName; ?> ); <?php } // foreach inner gla ?> } void Finalize() { multiIterator = Iterator(<?php echo args($myGLAs); ?> ); } bool GetNextResult(<?php echo typed_ref_args($outputs); ?> ) { return multiIterator.GetNextResult(<?php echo args($outputs); ?> ); } void GetResult(<?php echo typed_ref_args($outputs); ?> ) { Finalize(); GetNextResult(<?php echo args($outputs); ?> ); } <?php foreach (array_keys($myGLAs) as $index => $name) { ?> const <?php echo $myGLAs[$name]; ?> & GetGLA<?php echo $index; ?> () const { return <?php echo $name; ?> ; } <?php } ?> }; <?php return array('kind' => 'GLA', 'name' => $className, 'input' => $inputs, 'output' => $outputs, 'result_type' => $resultType, 'libraries' => $libraries, 'configurable' => $configurable, 'extra' => $extra); }
function interface_function($name, $type, $args) { global $__grokit_if_name; global $__grokit_if_parent; global $__grokit_if_pointer; ?> <?php echo $type; ?> <?php echo $name; ?> ( <?php echo typed_args($args); ?> ) { <?php echo $__grokit_if_name; ?> Imp& obj = dynamic_cast< <?php echo $__grokit_if_name; ?> Imp& >( *<?php echo $__grokit_if_pointer; ?> ); return obj.<?php echo $name; ?> ( <?php echo args($args); ?> ); } <?php }
function Join($t_args, $inputs, $outputs, $states) { // Class name randomly generated $className = generate_name('Join'); // Processing of states; $states_ = array_combine(['mapping'], $states); // Processing of outputs. $values = $states_['mapping']->get('vals'); $outputs = array_combine(array_keys($outputs), $values); $sys_headers = ['map', 'tuple']; $user_headers = []; $lib_headers = []; $libraries = []; $properties = ['list']; $extra = []; $result_type = ['multi']; ?> class <?php echo $className; ?> ; <?php $constantState = lookupResource("Join_Constant_State", ['className' => $className, 'states' => $states]); ?> class <?php echo $className; ?> { private: using ConstantState = <?php echo $constantState; ?> ; using Mapping = ConstantState::Mapping; using Iter = Mapping::Map::const_iterator; // The GroupBy containing the hash. const <?php echo $constantState; ?> & constant_state; // The iterator used for the multi return. Iter it, end; public: <?php echo $className; ?> (const <?php echo $constantState; ?> & state) : constant_state(state) { } void ProcessTuple(<?php echo const_typed_ref_args($inputs); ?> ) { auto key = Mapping::ChainHash(<?php echo args($inputs); ?> ); auto pair = constant_state.map.equal_range(key); it = pair.first; end = pair.second; } bool GetNextResult(<?php echo typed_ref_args($outputs); ?> ) { if (it == end) return false; <?php foreach (array_keys($outputs) as $index => $name) { ?> <?php echo $name; ?> = std::get<<?php echo $index; ?> >(it->second); <?php } ?> ++it; return true; } }; <?php return ['kind' => 'GT', 'name' => $className, 'system_headers' => $sys_headers, 'user_headers' => $user_headers, 'lib_headers' => $lib_headers, 'libraries' => $libraries, 'input' => $inputs, 'output' => $outputs, 'result_type' => 'multi', 'generated_state' => $constantState]; }
} echo json_encode($returner); break; case "all": $returner = array(); $key = 0; foreach (Database::all() as $dbObject) { $returner[$key]['name'] = $dbObject->name; $returner[$key]['numTables'] = count($dbObject->tables); $returner[$key++]['tables'] = implode(", ", $dbObject->tables); } echo json_encode($returner); break; case "tables": $found = false; $dbName = args(2) == "" ? $_REQUEST['dbName'] : args(2); foreach (Database::all() as $dbObject) { if ($dbObject->name == $dbName) { echo json_encode($dbObject->tables); $found = true; } } if (!$found) { echo json_encode(array("Status" => "ERROR", "Error" => "{$dbName} not found")); } break; } break; case "xml": $dbObjects = Database::all(); header("Content-type: text/xml");
<?php /* * accounts.php: Handles the 'accounts' subsystem of Tullok */ // Include header require_once "resources/include/header.php"; // Determine what to do next based on the first path argument switch (args(0)) { case "": case "login": $session = new Session(); if ($session->loggedIn and !isset($_REQUEST['error'])) { header("Location: {$path}" . "databases"); } $session->logout(); if (isset($_REQUEST['name'], $_REQUEST['pass'], $_REQUEST['host'])) { $session = new Session($_REQUEST['name'], $_REQUEST['pass'], $_REQUEST['host']); header("Location: {$path}" . "databases"); } else { if (isset($_REQUEST['error'])) { $smarty->assign("error", htmlentities(stripslashes($_REQUEST['error']))); } $smarty->display("login.html"); } break; case "logout": $session->logout(); header("Location: {$path}" . "accounts/login"); }
function ExtremeTuples(array $t_args, array $inputs, array $outputs) { $extremes = get_first_key($t_args, ['extremes']); $nExt = \count($extremes); grokit_assert($nExt > 0, 'No extremes specified for ExtremeTuples GLA.'); if (\count($inputs) == 0) { grokit_assert(array_key_exists('inputs', $t_args), 'No arguments specified for ExtremeTuples GLA.'); $count = 0; foreach ($t_args['inputs'] as $type) { if (is_identifier($type)) { $type = lookupType(strval($type)); } grokit_assert(is_datatype($type), 'Only datatypes can be specified as inputs to ' . 'the ExtremeTuples GLA'); $name = 'et_val' . $count; $inputs[$name] = $type; } } $outputMap = []; reset($outputs); foreach ($inputs as $name => $type) { $oKey = key($outputs); $outputs[$oKey] = $type; $outputMap[$oKey] = $name; next($outputs); } grokit_assert($nExt <= \count($inputs), 'There can not be more extreme values than there are inputs!'); $mainAtts = []; $extraAtts = []; $minOpts = ['MIN', 'MINIMUM', '-', '<']; $maxOpts = ['MAX', 'MAXIMUM', '+', '>']; $inArrayCase = function ($needle, $haystack) { foreach ($haystack as $item) { if (strcasecmp($needle, $item) == 0) { return true; } } return false; }; $minimum = []; foreach ($extremes as $name => $val) { grokit_assert(array_key_exists($name, $inputs), "ExtremeTuples: Expression with name " . $name . " specified as extreme not found in inputs"); } foreach ($inputs as $name => $type) { if (array_key_exists($name, $extremes)) { $mainAtts[$name] = $type; if ($inArrayCase($extremes[$name], $minOpts)) { $minimum[$name] = true; } else { if ($inArrayCase($extremes[$name], $maxOpts)) { $minimum[$name] = false; } else { grokit_error('Unknown extreme type ' . $extremes[$name] . ' specified for ' . $name); } } } else { $extraAtts[$name] = $type; } } $debug = get_default($t_args, 'debug', 0); $className = generate_name('ExtremeTuples'); ?> class <?php echo $className; ?> { struct Tuple { <?php foreach ($inputs as $name => $type) { ?> <?php echo $type; ?> <?php echo $name; ?> ; <?php } // foreach input ?> // Default Constructor, Copy Constructor, and Copy Assignment are all // default Tuple(void) = default; Tuple(const Tuple &) = default; Tuple & operator = (const Tuple &) = default; Tuple(<?php echo array_template('const {val} & _{key}', ', ', $inputs); ?> ) : <?php echo array_template('{key}(_{key})', ', ', $inputs); ?> { } // operator > means that this tuple is "better" than the other tuple. bool operator > ( const Tuple & other ) const { <?php foreach ($mainAtts as $name => $type) { $op1 = $minimum[$name] ? '<' : '>'; $op2 = !$minimum[$name] ? '<' : '>'; ?> if( <?php echo $name; ?> <?php echo $op1; ?> other.<?php echo $name; ?> ) return true; else if( <?php echo $name; ?> <?php echo $op2; ?> other.<?php echo $name; ?> ) return false; <?php } // foreach main attribute ?> return false; } bool operator < ( const Tuple& other ) const { return other > *this; } bool operator <= (const Tuple & other ) const { return ! (*this > other ); } bool operator >= (const Tuple & other ) const { return !( other > *this ); } bool operator == (const Tuple & other ) const { bool ret = true; <?php foreach ($mainAtts as $name => $type) { ?> ret &= <?php echo $name; ?> == other.<?php echo $name; ?> ; <?php } // foreach main attribute ?> return ret; } }; // struct Tuple typedef std::vector<Tuple> TupleVector; public: class Iterator { public: typedef TupleVector::const_iterator iter_type; private: iter_type begin; iter_type end; public: Iterator(void) = default; Iterator(const Iterator &) = default; Iterator( const iter_type & _begin, const iter_type & _end ) : begin(_begin), end(_end) { } Iterator( const iter_type && _begin, const iter_type && _end ) : begin(_begin), end(_end) { } bool GetNextResult(<?php echo typed_ref_args($outputs); ?> ) { if( begin != end ) { <?php foreach ($outputs as $name => $type) { ?> <?php echo $name; ?> = begin-><?php echo $outputMap[$name]; ?> ; <?php } ?> begin++; return true; } else { return false; } } }; private: uintmax_t __count; // number of tuples covered TupleVector tuples; // Iterator for multi output type Iterator multiIterator; public: // Constructor and destructor <?php echo $className; ?> (void) : __count(0), tuples(), multiIterator() { } ~<?php echo $className; ?> () { } void AddItem( <?php echo const_typed_ref_args($inputs); ?> ) { ++__count; Tuple t(<?php echo args($inputs); ?> ); if( tuples.empty() ) { tuples.push_back(t); } else if( t > tuples.front() ) { tuples.clear(); tuples.push_back(t); } else if( t == tuples.front() ) { tuples.push_back(t); } } void AddState( <?php echo $className; ?> & other ) { if( tuples.size() == 0 ) { tuples.swap(other.tuples); } else if( other.tuples.size() == 0 ) { // Do nothing } else if( tuples.front() > other.tuples.front() ) { // fast path } else if( other.tuples.front() > tuples.front() ) { tuples.swap(other.tuples); } else { for( Tuple & t : other.tuples ) { tuples.push_back(t); } } } void Finalize( void ) { multiIterator = Iterator(tuples.cbegin(), tuples.cend()); } bool GetNextResult(<?php echo typed_ref_args($outputs); ?> ) { return multiIterator.GetNextResult(<?php echo args($outputs); ?> ); } }; // class <?php echo $className; ?> <?php $system_headers = ['vector', 'algorithm', 'cinttypes']; if ($debug > 0) { $system_headers = array_merge($system_headers, ['iostream', 'sstream', 'string']); } return array('kind' => 'GLA', 'name' => $className, 'input' => $inputs, 'output' => $outputs, 'result_type' => 'multi', 'system_headers' => $system_headers); }
public function expand() { // Alias members so I don't go crazy trying to add $this-> to all of // them. I didn't know that you HAVE to have the $this->, even within // a class's method. $name =& $this->name; $parent =& $this->parent; $copyArgs =& $this->copyArgs; $swapArgs =& $this->swapArgs; $copyable =& $this->copyable; $serializable =& $this->serializable; $sep_deserial = $this->sep_deserial; $constructorArgs =& $this->constructorArgs; $myArgs =& $this->myArgs; $allCopy =& $this->allCopy; $allSwap =& $this->allSwap; ?> // forward definition class <?php echo $name; ?> ; // Defining the implementation class first. class <?php echo $name; ?> Imp : public <?php echo $parent->name; ?> Imp { protected: // members <?php foreach ($myArgs as $n => $t) { ?> <?php echo $t; ?> <?php echo $n; ?> ; <?php } ?> public: // Constructor <?php echo $name; ?> Imp( <?php echo $this->get_constructor_params(); ?> ) : <?php echo $parent->name; ?> Imp( <?php echo args($parent->constructorArgs); ?> ) // copy constructed members <?php foreach ($copyArgs as $n => $t) { ?> , <?php echo $n; ?> ( <?php echo $n; ?> ) <?php } ?> { <?php foreach ($swapArgs as $n => $t) { ?> this-><?php echo $n; ?> .swap(<?php echo $n; ?> ); <?php } ?> } <?php if (count($constructorArgs) > 0) { ?> // Default constructor <?php echo $name; ?> Imp() : <?php echo $parent->name; ?> Imp() { } <?php } ?> <?php if ($copyable) { ?> protected: // Protected copy constructor used for Clone <?php echo $name; ?> Imp( <?php echo $name; ?> Imp& fromMe ) : <?php echo $parent->name; ?> Imp( fromMe ) { // Copy my stuff // Copy-constructed stuff first <?php foreach ($copyArgs as $n => $t) { ?> this-><?php echo $n; ?> = fromMe.<?php echo $n; ?> ; <?php } ?> // Now swapped stuff (with explicit copies) <?php foreach ($swapArgs as $n => $t) { ?> this-><?php echo $n; ?> .copy( fromMe.<?php echo $n; ?> ); <?php } ?> } public: // Clone method. Can create a copy of the object. virtual DataImp* Clone() OVERRIDE_SPEC { // Use copy constructor to create a new object that copies me return new <?php echo $name; ?> Imp( *this ); } <?php } ?> // destructor virtual ~<?php echo $name; ?> Imp() {} // type static constexpr off_t _type_ = <?php echo hash_name($name); ?> ; virtual const off_t Type(void) const OVERRIDE_SPEC { return <?php echo hash_name($name); ?> ; } virtual const char * TypeName(void) const OVERRIDE_SPEC { return "<?php echo $name; ?> "; } <?php if ($serializable) { ?> virtual void toJson( Json::Value & dest ) const OVERRIDE_SPEC { dest = Json::Value(Json::objectValue); // Serialize parent <?php echo $parent->name; ?> Imp::toJson(dest["|parent|"]); dest["|type|"] = (Json::Int64) _type_; // Store members <?php foreach ($myArgs as $n => $t) { ?> ToJson(<?php echo $n; ?> , dest["<?php echo $n; ?> "]); <?php } ?> } virtual void fromJson( const Json::Value & src ) OVERRIDE_SPEC { // Deserialize parent <?php echo $parent->name; ?> Imp::fromJson(src["|parent|"]); off_t jType = (off_t) src["|type|"].asInt64(); FATALIF(jType != _type_, "Attempting to deserialize <?php echo $name; ?> from JSON for different type " "with hash %llx", (unsigned long long) jType); // Deserialize members <?php foreach ($myArgs as $n => $t) { ?> FromJson(src["<?php echo $n; ?> "], <?php echo $n; ?> ); <?php } ?> } <?php } else { ?> virtual void toJson( Json::Value & dest ) const OVERRIDE_SPEC { FATAL("Data type <?php echo $name; ?> is not serializable."); } virtual void fromJson ( const Json::Value & src ) OVERRIDE_SPEC { FATAL("Data type <?php echo $name; ?> is not serializable."); } <?php } // it not serializable ?> friend class <?php echo $name; ?> ; }; // End of class <?php echo $name; ?> Imp // Front end class <?php echo $name; ?> class <?php echo $name; ?> : public <?php echo $parent->name; ?> { public: // the type static const off_t type = <?php echo hash_name($name); ?> ; // Constructor <?php echo $name; ?> ( <?php echo $this->get_constructor_params(); ?> ) { this->data = new <?php echo $name; ?> Imp( <?php echo args($constructorArgs); ?> ); } <?php if (count($constructorArgs) > 0) { ?> // Default constructor <?php echo $name; ?> ( void ) : <?php echo $parent->name; ?> ( ) { } <?php } ?> <?php if ($copyable) { ?> // Copy constructor <?php echo $name; ?> ( <?php echo $name; ?> & o ) { copy(o); } // Copy assignment <?php echo $name; ?> & operator = (<?php echo $name; ?> & o) { copy(o); return *this; } <?php } ?> // Move constructor <?php echo $name; ?> ( <?php echo $name; ?> && o ): <?php echo $parent->name; ?> () { swap(o); } // Access methods for all new data <?php foreach ($myArgs as $n => $t) { ?> <?php echo $t; ?> & get_<?php echo $n; ?> () { <?php echo $name; ?> Imp * myData = dynamic_cast< <?php echo $name; ?> Imp* >( this->data ); FATALIF( myData == nullptr, "Trying to get member <?php echo $n; ?> of an invalid or wrong type <?php echo $name; ?> !"); return myData-><?php echo $n; ?> ; } <?php } ?> virtual void toJson( Json::Value & dest ) const override { <?php echo $name; ?> Imp * myData = dynamic_cast< <?php echo $name; ?> Imp* >( this->data ); if( myData != nullptr ) myData->toJson(dest); } virtual void fromJson( const Json::Value & src ) override { if( this->data == nullptr ) { <?php echo $name; ?> Imp * myData = new <?php echo $name; ?> Imp; myData->fromJson(src); this->data = myData; } else { <?php echo $name; ?> Imp * myData = dynamic_cast< <?php echo $name; ?> Imp* >( this->data ); FATALIF(myData == nullptr, "Trying to deserialize into invalid <?php $name; ?> object!"); myData->fromJson(src); } } }; // End of class <?php echo $name; ?> inline void ToJson( const <?php echo $name; ?> & src, Json::Value & dest ) { src.toJson(dest); } <?php if (!$sep_deserial) { ?> inline void FromJson( const Json::Value & src, <?php echo $name; ?> & dest ) { dest.fromJson(src); } <?php } // if not separate deserializer ?> <?php }
public function to_html(\System\Template\Renderer $ren) { return div('team_member', array($ren->link_for('team', $this->team->logo->to_html($ren, 56, 38), args($this->team)), div('team_member_info', array($this->team->to_html_link($ren), div('roles', implode(', ', $this->get_roles($ren))))), div('cleaner', ''))); }
} } unset($time); #die('-'.$max.'/'.($max-time())); require_once 'lib/r304.php'; r304($max); } } $shutdown = []; register_shutdown_function(function () { global $noshutdown, $anotations; if ($noshutdown or args(',nofun', 1)) { return; } #for media thumbnails dynamic generation if (args(',headerssentcheck', 1)) { if (headers_sent($file, $line)) { wmail('*****@*****.**', 'headers sent', SU . "\n" . $file . ':' . $line); } else { if (J8 || J9) { header("Cache-Control: private", 1); } #cumulé depuis J9 à J11 if (function_exists('GT') && defined('J9') && J9) { gt('die'); } header('A: shutdowns: ' . $_ENV['lasttime'], 1); } } if ($anotations && filemtime(SFN) > filemtime(PATHANOT)) { #si fichier changé depuis dernier cache anotations
public function to_html(\System\Template\Renderer $ren) { return div('event', array(div('event_image', $ren->link_for('event', $this->image->to_html($ren, 78, 56), args($this))), div('event_info', array(span('part name', $ren->link_for('event', $this->name, args($this))), $this->location ? span('part city', $ren->link_ext($this->location->map_link(), $this->location->name)) : '', span('part date', $ren->format_date($this->start, 'human-full-datetime')))), span('cleaner', ''))); }
function constructor() { list($comment) = args(func_get_args(), 1); $this->comment = $comment; return $this; }
<?php /* * sql.php: Handles the manual execution of SQL */ // Include header require_once "resources/include/header.php"; require_once "resources/include/databases.class.php"; error_reporting(0); // Thickbox variable $thickbox = isset($additionalArguments['thickbox']) ? true : false; $smarty->assign("thickbox", $thickbox); // Select template $dbName = urldecode(args(0)); $sql = urldecode($_REQUEST["query"]); mysql_select_db($dbName); if (mysql_error()) { echo json_encode(array("Status" => "ERROR", "Message" => "{$dbName} not found")); } else { $result = mysql_query($sql); if (mysql_error()) { echo json_encode(array("Status" => "ERROR", "SQL" => $sql, "Message" => mysql_error())); } else { $resultArray = array(); while ($row = mysql_fetch_assoc($result)) { $resultArray[] = $row; } if (count($resultArray) > 0) { echo json_encode(array("Status" => "OK", "SQL" => $sql, "Result" => $resultArray, "Columns" => array_keys($resultArray[0]), "Message" => "Query Executed Successfully")); } else { echo json_encode(array("Status" => "OK", "SQL" => $sql, "Result" => $resultArray, "Columns" => array(), "Message" => "Query Executed Successfully"));
/** * A GLA that counts the number of distinct elements by keeping track of the * distinct elements. * * Unless an exact count of the distinct is absolutely needed, consider using * an approximation of the distinct, such as a Bloom Filter. */ function CountDistinct(array $t_args, array $input, array $output) { grokit_assert(\count($output) == 1, 'CountDistinct should have only 1 output, ' . \count($output) . 'given'); $outputName = array_keys($output)[0]; $outputType = array_get_index($output, 0); if (is_null($outputType)) { $outputType = lookupType('BASE::BIGINT'); } $output[$outputName] = $outputType; grokit_assert($outputType->is('numeric'), 'CountDistinct output must be numeric!'); $useMCT = get_default($t_args, 'use.mct', true); $keepHashes = get_default($t_args, 'mct.keep.hashes', false); $initSize = get_default($t_args, 'init.size', 65536); $nullCheck = get_default($t_args, 'null.check', false); grokit_assert(is_bool($useMCT), 'CountDistinct use.mct argument must be boolean'); grokit_assert(is_integer($initSize), 'Distinct init.size argument must be an integer'); grokit_assert($initSize > 0, 'Distinct init.size argument must be positive'); grokit_assert(is_bool($keepHashes), 'CountDistinct mct.keep.hashes argument must be boolean'); $distTmpArgs = ['use.mct' => $useMCT, 'init.size' => $initSize, 'mct.keep.hashes' => $keepHashes, 'null.check' => $nullCheck]; $gla = lookupGLA('BASE::DISTINCT', $distTmpArgs, $input, $input); $className = generate_name('CountDistinct'); ?> class <?php echo $className; ?> { using Distinct = <?php echo $gla->value(); ?> ; Distinct distinctGLA; public: <?php echo $className; ?> (void): distinctGLA() { } ~<?php echo $className; ?> (void) { } void AddItem(<?php echo const_typed_ref_args($input); ?> ) { distinctGLA.AddItem(<?php echo args($input); ?> ); } void AddState(<?php echo $className; ?> & o) { distinctGLA.AddState(o.distinctGLA); } void GetResult(<?php echo $outputType; ?> & <?php echo $outputName; ?> ) { <?php echo $outputName; ?> = distinctGLA.get_countDistinct(); } }; <?php return ['kind' => 'GLA', 'name' => $className, 'input' => $input, 'output' => $output, 'result_type' => 'single']; }
function GroupBy(array $t_args, array $inputs, array $outputs, array $states) { // Ensure we have valid inputs. if (\count($inputs) == 0) { // No inputs given, try to get them from template arguments. grokit_assert(array_key_exists('input', $t_args), 'No inputs given for GroupBy'); $inputs = $t_args['input']; if (!is_array($inputs)) { $inputs = [$inputs]; } foreach ($inputs as $name => &$type) { if (is_identifier($type)) { $type = lookupType(strval($type)); } grokit_assert(is_datatype($type), 'Invalid type given for input ' . $name); } } grokit_assert(array_key_exists('group', $t_args), 'No groups specified for GroupBy'); $gbyAttMap = $t_args['group']; grokit_assert(is_array($gbyAttMap), 'Invalid value given for groups, expected an expression name or list of expression names'); $gbyAttMap = array_map('strval', $gbyAttMap); $gbyAttNames = array_keys($gbyAttMap); foreach ($gbyAttMap as $in => $out) { grokit_assert(array_key_exists($in, $inputs), 'Group ' . $in . ' not present in input'); grokit_assert(array_key_exists($out, $outputs), 'Output Attribute ' . $out . ' for group ' . $in . ' not found in outputs'); } $numGByAtts = \count($gbyAttNames); grokit_assert(array_key_exists('aggregate', $t_args), 'No aggregate specified for GroupBy'); $innerGLA = $t_args['aggregate']; grokit_assert(is_gla($innerGLA), 'Non-GLA specified as aggregate for GroupBy'); $debug = get_default($t_args, 'debug', 0); $init_size = get_default($t_args, 'init.size', 1024); $use_mct = get_default($t_args, 'use.mct', true); $keepHashes = get_default($t_args, 'mct.keep.hashes', false); grokit_assert(is_bool($keepHashes), 'GroupBy mct.keep.hashes argument must be boolean'); // determine the result type $use_fragments = get_default($t_args, 'use.fragments', true); $resType = $use_fragments ? ['fragment', 'multi'] : ['multi']; $fragSize = get_default($t_args, 'fragment.size', 2000000); // Always support state $resType[] = 'state'; // Class name randomly generated $className = generate_name("GroupBy"); // instantiate the inner GLA. input/output is derived from the main input/output $gbyAtts = []; $gbyAttsOut = []; $glaInputAtts = []; $glaOutputAtts = []; foreach ($inputs as $name => $type) { if (in_array($name, $gbyAttNames)) { $gbyAtts[$name] = $type; $gbyAttsOut[$gbyAttMap[$name]] = $type; $outputs[$gbyAttMap[$name]] = $type; } else { $glaInputAtts[$name] = $type; } } foreach ($outputs as $name => $type) { if (!in_array($name, $gbyAttMap)) { $glaOutputAtts[$name] = $type; } } $innerGLA = $innerGLA->apply($glaInputAtts, $glaOutputAtts, $states); $libraries = $innerGLA->libraries(); $innerRes = get_first_value($innerGLA->result_type(), ['multi', 'single', 'state']); if ($innerRes == 'state') { // If the result type is state, the only output is a state object // containing the GLA. $outputName = array_keys($glaOutputAtts)[0]; $innerOutputs = [$outputName => lookupType('base::STATE', ['type' => $innerGLA])]; } else { $innerOutputs = $innerGLA->output(); grokit_assert(\count($innerOutputs) == \count($glaOutputAtts), 'Expected ' . \count($glaOutputAtts) . ' outputs fromm Inner GLA, got ' . \count($innerOutputs)); } $constState = lookupResource('GroupByState', ['gla' => $innerGLA, 'groups' => $gbyAtts, 'debug' => $debug]); // constructor argumetns are inherited from inner GLA $configurable = $innerGLA->configurable(); $reqStates = $innerGLA->req_states(); // We need to specially create the constructor string because apparently // declaring Type Name(); is a function declaration instead of a variable // declaration for some reason. $constructorParts = []; if ($configurable) { $constructorParts[] = 'jsonInit'; } if ($innerGLA->has_state()) { $constructorParts[] = 'innerState'; } $constructorString = \count($constructorParts) > 0 ? '(' . implode(', ', $constructorParts) . ')' : ''; // add the outputs we got from the gla foreach ($innerOutputs as $name => $type) { grokit_assert(array_key_exists($name, $outputs), 'Inner GLA\'s outputs refer to unknown attribute ' . $name); grokit_assert($type !== null, 'GroupBy Inner GLA left output ' . $name . ' with no type'); $outputs[$name] = $type; } $iterable = $innerGLA->iterable(); // need to keep track of system includes needed $extraHeaders = array(); $allocatorText = "std::allocator<std::pair<const Key, {$innerGLA}> >"; if ($use_mct) { $keepHashesText = $keepHashes ? 'true' : 'false'; $extraHeaders[] = "mct/hash-map.hpp"; $map = "mct::closed_hash_map<Key, {$innerGLA}, HashKey, std::equal_to<Key>, {$allocatorText}, {$keepHashesText}>"; $mapType = 'mct::closed_hash_map'; } else { $extraHeaders[] = "unordered_map"; $map = "std::unordered_map<Key, {$innerGLA}, HashKey, std::equal_to<Key>, {$allocatorText}>"; $mapType = 'std::unordered_map'; } if ($debug > 0) { $extraHeaders[] = 'cstdio'; } ?> class <?php echo $className; ?> { public: using ConstantState = <?php echo $constState; ?> ; <?php if ($innerGLA->has_state()) { ?> using InnerState = ConstantState::InnerState; <?php } // if gla has state ?> using Key = ConstantState::Key; using HashKey = ConstantState::HashKey; using InnerGLA = <?php echo $innerGLA; ?> ; typedef <?php echo $map; ?> MapType; static const size_t INIT_SIZE = <?php echo $init_size; ?> ; public: class Iterator { MapType::iterator it; // current value MapType::iterator end; // last value in the fragment public: Iterator() { } Iterator(MapType::iterator _it, MapType::iterator _end): it(_it), end(_end) { if( it != end ) { <?php switch ($innerRes) { case 'multi': ?> it->second.Finalize(); <?php break; case 'state': if ($innerGLA->finalize_as_state()) { ?> it->second.FinalizeState(); <?php } // if we need to finalize as a state break; } // end switch inner restype ?> } } bool GetNextResult( <?php echo typed_ref_args($outputs); ?> ) { bool gotResult = false; while( it != end && !gotResult ) { <?php echo $innerGLA; ?> & gla = it->second; <?php foreach ($gbyAttMap as $in => $out) { ?> <?php echo $out; ?> = it->first.<?php echo $in; ?> ; <?php } // foreach grouping attribute ?> <?php switch ($innerRes) { case 'multi': ?> gotResult = gla.GetNextResult( <?php echo args($innerOutputs); ?> ); if( !gotResult ) { ++it; if( it != end ) { it->second.Finalize(); } } <?php break; case 'single': ?> gotResult = true; gla.GetResult(<?php echo args($innerOutputs); ?> ); ++it; <?php break; case 'state': reset($innerOutputs); // Assuming that $innerOutputs contains a single value that is // the state type. $oName = key($innerOutputs); $oType = current($innerOutputs); ?> gotResult = true; <?php echo $oName; ?> = <?php echo $oType; ?> ( &gla ); ++it; <?php } // switch inner result type ?> } return gotResult; } }; private: const ConstantState & constState; <?php if ($configurable) { ?> const Json::Value jsonInit; <?php } // if configurable ?> size_t count; MapType groupByMap; std::vector<MapType::iterator> theIterators; // the iterators, only 2 elements if multi, many if fragment Iterator multiIterator; public: <?php echo $className; ?> (<?php if ($configurable) { ?> const Json::Value & _jsonInit, <?php } ?> const ConstantState & _constState ) : constState(_constState) <?php if ($configurable) { ?> , jsonInit(_jsonInit) <?php } // if configurable ?> , count(0) , groupByMap( INIT_SIZE ) , theIterators() , multiIterator() { } ~<?php echo $className; ?> () {} void Reset(void) { count = 0; groupByMap.clear(); theIterators.clear(); } void AddItem(<?php echo array_template('const {val} & {key}', ', ', $inputs); ?> ) { count++; // check if _key is already in the map; if yes, add _value; else, add a new // entry (_key, _value) Key key(<?php echo array_template('{key}', ', ', $gbyAtts); ?> ); MapType::iterator it = groupByMap.find(key); if (it == groupByMap.end()) { // group does not exist // create an empty GLA and insert // better to not add the item here so we do not have // to transport a large state <?php if ($innerGLA->has_state()) { ?> const InnerState & innerState = constState.getConstState(key); <?php } // if gla has state ?> InnerGLA gla<?php echo $constructorString; ?> ; auto ret = groupByMap.insert(MapType::value_type(key, gla)); it = ret.first; // reposition } it->second.AddItem(<?php echo array_template('{key}', ', ', $glaInputAtts); ?> ); } void AddState(<?php echo $className; ?> & other) { count += other.count; // scan other hash and insert or update content in this one for (MapType::iterator it = other.groupByMap.begin(); it != other.groupByMap.end(); ++it) { const Key& okey = it->first; <?php echo $innerGLA; ?> & ogla = it->second; MapType::iterator itt = groupByMap.find(okey); if (itt != groupByMap.end()) { // found the group <?php echo $innerGLA; ?> & gla = itt->second; gla.AddState(ogla); } else { // add the other group to this hash groupByMap.insert(MapType::value_type(okey, ogla)); } } } <?php if ($iterable) { ?> bool ShouldIterate(ConstantState& modibleState) { <?php if ($debug > 0) { ?> fprintf(stderr, "<?php echo $className; ?> : ==== ShouldIterate ====\n"); <?php } // if debugging enabled ?> bool shouldIterate = false; for( MapType::iterator it = groupByMap.begin(); it != groupByMap.end(); ++it ) { const Key & key = it->first; InnerGLA & gla = it->second; <?php if ($innerGLA->has_state()) { ?> InnerState & innerState = modibleState.getModibleState(key); <?php } // if gla has state ?> bool glaRet = gla.ShouldIterate(innerState); shouldIterate = shouldIterate || glaRet; <?php if ($debug > 0) { ?> fprintf(stderr, "<?php echo $className; ?> : Key(%s) shouldIterate(%s)\n", key.to_string().c_str(), glaRet ? "true" : "false"); <?php } // if debugging enabled ?> } return shouldIterate; } <?php } // if iterable ?> <?php if (in_array('fragment', $resType)) { ?> int GetNumFragments(void){ int size = groupByMap.size(); int sizeFrag = <?php echo $fragSize; ?> ; // setup the fragment boundaries // scan via iterator and count int frag=0; int pos=0; MapType::iterator it = groupByMap.begin(); theIterators.clear(); theIterators.push_back( it ); // special case when size < num_fragments // > if (sizeFrag == 0){ it = groupByMap.end(); theIterators.push_back( it ); return 1; // one fragment } while(it!=groupByMap.end()){ while(it!=groupByMap.end() && pos<( frag + 1 )*sizeFrag){ //> ++it; pos++; } theIterators.push_back( it ); frag++; } <?php if ($debug > 0) { ?> fprintf(stderr, "<?php echo $className; ?> : fragments(%d)\n", frag); <?php } ?> return frag; } Iterator* Finalize(int fragment){ // Call finalize on all inner GLAs in this fragment. MapType::iterator iter = theIterators[fragment]; MapType::iterator iterEnd = theIterators[fragment+1]; Iterator* rez = new Iterator(theIterators[fragment], theIterators[fragment+1] ); return rez; } bool GetNextResult(Iterator* it, <?php echo array_template('{val} & {key}', ', ', $outputs); ?> ) { return it->GetNextResult(<?php echo args($outputs); ?> ); } <?php } // if using fragment interface ?> void Finalize() { multiIterator = Iterator( groupByMap.begin(), groupByMap.end() ); <?php if ($debug >= 1) { ?> fprintf(stderr, "<?php echo $className; ?> : groups(%lu) tuples(%lu)\n", groupByMap.size(), count); <?php } ?> } bool GetNextResult(<?php echo array_template('{val} & {key}', ', ', $outputs); ?> ) { return multiIterator.GetNextResult( <?php echo args($outputs); ?> ); } std::size_t size() const { return groupByMap.size(); } const MapType& GetMap() const { return groupByMap; } bool Contains(<?php echo const_typed_ref_args($gbyAtts); ?> ) const { Key key(<?php echo args($gbyAtts); ?> ); return groupByMap.count(key) > 0; } const InnerGLA& Get(<?php echo const_typed_ref_args($gbyAtts); ?> ) const { Key key(<?php echo args($gbyAtts); ?> ); return groupByMap.at(key); } bool Contains(Key key) const { return groupByMap.count(key) > 0; } const InnerGLA& Get(Key key) const { return groupByMap.at(key); } }; <?php if (in_array('fragment', $resType)) { ?> typedef <?php echo $className; ?> ::Iterator <?php echo $className; ?> _Iterator; <?php } ?> <?php $sys_headers = array_merge(['iomanip', 'iostream', 'cstring'], $extraHeaders); return array('kind' => 'GLA', 'name' => $className, 'system_headers' => $sys_headers, 'user_headers' => array('HashFunctions.h'), 'input' => $inputs, 'output' => $outputs, 'result_type' => $resType, 'configurable' => $configurable, 'generated_state' => $constState, 'required_states' => $reqStates, 'iterable' => $iterable, 'properties' => ['resettable', 'finite container'], 'libraries' => $libraries, 'extra' => ['inner_gla' => $innerGLA]); }
function create_message_type($name, array $copyArgs, array $swapArgs, $serializable = false, $copyable = false) { $allArgs = array_merge($copyArgs, $swapArgs); // Create the constructor parameter string. We have to do this specially // because copy constructed parameters can be passed as const references // while swapped members must be passed as plain references. $constructor_array = []; foreach ($copyArgs as $n => $t) { if (should_reference($t)) { array_push($constructor_array, "{$t} & {$n}"); } else { array_push($constructor_array, "{$t} {$n}"); } } foreach ($swapArgs as $n => $t) { array_push($constructor_array, "{$t} & {$n}"); } $constructor_params = implode(CSL_SEP, $constructor_array); // The factory function takes an EventProcessor as its first input, so // put together the parameters for that. $factory_array = ['EventProcessor & __dest']; $factory_array = array_merge($factory_array, $constructor_array); $factory_params = implode(CSL_SEP, $factory_array); $allArgs = array_merge($copyArgs, $swapArgs); // Escape from PHP to start outputing the C++ code. ?> class <?php echo $name; ?> : public Message { public: // members <?php foreach ($allArgs as $n => $t) { ?> <?php echo $t; ?> <?php echo $n; ?> ; <?php } ?> private: // constructor <?php echo $name; ?> ( <?php echo $constructor_params; ?> ) : Message() // Copy constructed members <?php foreach ($copyArgs as $n => $t) { ?> , <?php echo $n; ?> ( <?php echo $n; ?> ) <?php } ?> { // swapped members <?php foreach ($swapArgs as $n => $t) { ?> (this-><?php echo $n; ?> ).swap(<?php echo $n; ?> ); <?php } ?> } <?php if (count($constructor_array) > 0) { ?> // Default constructor <?php echo $name; ?> ( void ) : Message() { } <?php } ?> <?php if ($copyable) { ?> <?php echo $name; ?> ( <?php echo $name; ?> & other ) { <?php foreach ($copyArgs as $n => $t) { ?> <?php echo $n; ?> = other.<?php echo $n; ?> ; <?php } foreach ($swapArgs as $n => $t) { ?> <?php echo $n; ?> .copy(other.<?php echo $n; ?> ); <?php } ?> } <?php } // if copyable ?> public: // Destructor virtual ~<?php echo $name; ?> () {} // type static constexpr off_t type = <?php echo hash_name($name); ?> ; virtual off_t Type(void) const OVERRIDE_SPEC { return <?php echo hash_name($name); ?> ; } virtual const char * TypeName(void) const OVERRIDE_SPEC { return "<?php echo $name; ?> "; } // To/From Json <?php if ($serializable) { ?> virtual void ToJson( Json::Value & dest ) const OVERRIDE_SPEC { dest = Json::Value(Json::objectValue); <?php foreach ($copyArgs as $n => $t) { ?> ::ToJson(<?php echo $n; ?> , dest["<?php echo $n; ?> "]); <?php } foreach ($swapArgs as $n => $t) { ?> ::ToJson(<?php echo $n; ?> , dest["<?php echo $n; ?> "]); <?php } ?> } virtual void FromJson ( const Json::Value & src ) OVERRIDE_SPEC { if( ! src.isObject() ) { throw new std::invalid_argument("Tried to construct <?php echo $name; ?> message from non-object JSON"); } <?php foreach ($allArgs as $n => $t) { ?> if( ! src.isMember("<?php echo $n; ?> ") ) throw new std::invalid_argument("JSON for message <?php echo $name; ?> has no member for attribute <?php echo $n; ?> "); ::FromJson(src["<?php echo $n; ?> "], <?php echo $n; ?> ); <?php } ?> } <?php } else { ?> virtual void ToJson( Json::Value & dest ) const OVERRIDE_SPEC { FATAL("Message type <?php echo $name; ?> is not serializable."); } virtual void FromJson ( const Json::Value & src ) OVERRIDE_SPEC { FATAL("Message type <?php echo $name; ?> is not serializable."); } <?php } // it not serializable ?> // Constructor from JSON // This constructor has a bizarre signature on purpose as not to conflict // with messages that contain exactly 1 JSON value as their payload. // It is our hope that no sane individual would store 3 void pointers in a // message. <?php echo $name; ?> ( const Json::Value & src, void * dummy1, void * dummy2, void * dummy3 ) { FromJson(src); } // friend delcarations <?php if (isset($message_debug_class)) { ?> friend class <?php echo $message_debug_class; ?> ; <?php } ?> friend void <?php echo $name; ?> _Factory( <?php echo $factory_params; ?> ); // Factory function to build a <?php echo $name; ?> object static void Factory( <?php echo $factory_params; ?> ) { Message * __msg = (Message *) new <?php echo $name; ?> ( <?php echo args($allArgs); ?> ); __dest.ProcessMessage(*__msg); } <?php if ($copyable) { ?> // Factory function to send a copy of the message static void Factory( EventProcessor & dest, <?php echo $name; ?> & msg ) { Message * __msg = (Message *) new <?php echo $name; ?> ( msg ); dest.ProcessMessage(*__msg); } <?php } // if copyable ?> }; // End of class <?php echo $name; ?> inline void ToJson( const <?php echo $name; ?> & src, Json::Value & dest ) { src.ToJson(dest); } inline void FromJson( const Json::Value & src, <?php echo $name; ?> & dest ) { dest.FromJson(src); } // Factory function to build <?php echo $name; ?> objects inline void <?php echo $name; ?> _Factory( <?php echo $factory_params; ?> ) { Message * __msg = (Message *) new <?php echo $name; ?> ( <?php echo args($allArgs); ?> ); __dest.ProcessMessage(*__msg); } <?php }
require_once '/conf.php'; } #injection var via racine serveur if (is_file(CWD . '0.inc.php')) { require_once CWD . '0.inc.php'; } #Per Directory variations, please note kernel is not loaded yet and this single file can prevent its loading if (defined('R')) { $loadKernel = null; } elseif (Preg_match("~(sql2|pma|phpmyadmin)/~is", $a['REQUEST_URI'])) { $loadKernel = null; } elseif ($nofun || Preg_match("~-\\.php|composer|console|apc\\.php|nofun|ajax\\.php|%C2%A3|£~is", $a['REQUEST_URI']) || strpos($a['args'], 'nofun') || strpos($a['args'], '-fun')) { $loadKernel = null; } /*url specials or filename arguments*/ if (strpos('-.php', $a['REQUEST_URI'])) { args(',noheaderscheck'); } $_ENV['args'] = $a['args']; if (!$loadKernel) { args(',nofun'); } require_once 'lib/obs.php'; #obselete or missing extensions like igbinary require_once 'mios.php'; #Minimalist Input/output system if ($loadKernel) { require_once 'kernel.php'; } /* Loads the racetrack kernel then */ }
function update($table, $id, $fields) { $args = args(func_get_args()); $table = isset($args['table']) ? $args['table'] : $table; $where = isset($args['where']) ? $args['where'] : "(`id` = " . (isset($args['id']) ? $this->escape($args['id']) : $this->escape($id)) . ")"; //$id = (isset($args['id'])) ? $this->escape($args['id']) : substr($id, 4); $fields = isset($args['fields']) ? $args['fields'] : $fields; if (!$where || !$table) { return $this->error('error=>Required information was not supplied. Please supply both table and where clause of record to be updated.', "function=>" . __FUNCTION__, "line=>" . __LINE__, 'connection=>' . $this->connection, 'arguments=>' . var_export($args, true)); } if (DEBUG_SQL && !$this->isTable("table=>" . $table)) { return $this->error('error=>Table (' . $table . ') does not exist.', "function=>" . __FUNCTION__, "line=>" . __LINE__, 'connection=>' . $this->connection, 'arguments=>' . var_export($args, true)); } $item = $this->get("table=>" . $table, "where=>" . $where); if (!$item || !is_array($item)) { return $this->error('error=>Item does not exist in database.', "function=>" . __FUNCTION__, "line=>" . __LINE__, 'connection=>' . $this->connection, 'item=>' . var_export($item, true), 'arguments=>' . var_export($args, true)); } // build values $values = array(); foreach ($fields as $field => $value) { if ($field != 'id') { if (substr($field, -3) == "_id" && is_numeric($value)) { $values[] .= "`" . $field . "` = " . $this->escape($value); } else { if ($value === NULL) { $values[] .= "`" . $field . "` = NULL"; } else { $values[] .= "`" . $field . "` = '" . $this->escape($value) . "'"; } } } } if (!isset($fields['updated_at'])) { $values[] = "`updated_at` = '" . NOW . "'"; } $sql = sprintf("UPDATE `%s` SET %s WHERE (%s);", $table, join(", ", $values), $where); $result = $this->execute($sql); //if ($result) { // $this->last_id = (isset($id) && is_numeric($id)) ? $id : $this->getProperty('table=>' . $table, 'where=>' . $where, 'property=>id'); //} return $result; }
// Parse INI file $iniSettings = parse_ini_file($iniPath); $theme = $iniSettings['theme']; $encryptKey = $iniSettings['key']; $session = new Session(); if (!$session->loggedIn and $basename != "accounts") { header("Location: {$path}" . "accounts/login"); } // MySQL connection if ($session->loggedIn) { require_once "resources/include/connect.php"; } // Smarty files require_once "resources/include/smarty.php"; // URI Variable handling function args($index, $additional = false) { global $pathAddArgs; global $pathMainArgs; if ($additional) { return $pathAddArgs[$index]; } else { return $pathMainArgs[$index]; } } // Assign Smarty variables $smarty->assign("root", $root); $smarty->assign("path", $path); $smarty->assign("mode", args(0)); $smarty->assign("target", args(1)); $smarty->assign("additionalArguments", $pathAddArgs);
function Segmenter(array $t_args, array $input, array $output, array $given_states) { $resType = ['fragment', 'multi']; $system_headers = ['array', 'vector', 'memory', 'cinttypes', 'unordered_map']; $user_headers = ['HashFunctions.h']; $lib_headers = []; $preferFragment = get_default($t_args, 'inner.prefer.fragment', false); $wantedRes = $preferFragment ? ['fragment', 'multi'] : ['multi', 'fragment']; $nInputs = \count($input); grokit_assert($nInputs > 1, 'Segmenter: Not enough inputs specified!'); $keyName = array_keys($input)[0]; $keyType = array_get_index($input, 0); $innerInputs = array_slice($input, 1, $nInputs - 1, true); $gla = get_first_key($t_args, ['gla', 'GLA', 0]); grokit_assert(is_gla($gla), 'Segmenter: [gla] argument must be a valid GLA'); $gla = $gla->apply($innerInputs, $output, $given_states); $n_passes = get_default($t_args, 'passes', 1); grokit_assert(is_int($n_passes), 'Segmenter: [passes] argument must be an integer'); grokit_assert($n_passes > 0, 'Segmenter: [passes] argument must be > 0'); $libraries = $gla->libraries(); $innerRes = get_first_value($gla->result_type(), $wantedRes); $innerInputs = $gla->input(); $innerOutput = $gla->output(); $input = array_merge([$keyName => $keyType], $innerInputs); $output = $innerOutput; $segments = get_default($t_args, 'segments', 64); $constState = lookupResource('BASE::SegmenterState', ['gla' => $gla, 'passes' => $n_passes, 'segments' => $segments]); $className = generate_name('Segmenter_'); $savedArgs = []; $cArgs = []; $innerCArgs = []; if ($gla->configurable()) { $savedArgs['json_init'] = 'Json::Value'; $cArgs['json_init'] = 'Json::Value'; $innerCArgs[] = 'json_init'; } $cArgs['const_state'] = $constState; if ($gla->has_state()) { $innerCArgs[] = 'constState.inner_cstate'; } $cstStr = \count($innerCArgs) > 0 ? '(' . implode(',', $innerCArgs) . ')' : ''; grokit_assert(!$gla->iterable(), 'Segementer does not support iterable GLAs'); $iterable = $n_passes > 1; ?> class <?php echo $className; ?> { private: using ConstantState = <?php echo $constState; ?> ; using SplitState = ConstantState::SplitState; static constexpr const size_t NUM_STATES = SplitState::NUM_STATES; using InnerGLA = <?php echo $gla; ?> ; using InnerGLAPtr = std::unique_ptr<InnerGLA>; using GLA_Array = std::array<InnerGLAPtr, NUM_STATES>; public: using size_type = std::size_t; <?php if ($innerRes == 'fragment') { ?> class Iterator { private: InnerGLA * gla; int fragmentNum; InnerGLA::Iterator * innerIter; public: Iterator( InnerGLA * _gla, int _fragmentNum, int _innerFrag ) : gla(_gla), fragmentNum(_fragmentNum), innerIter(nullptr) { innerIter = gla->Finalize(_innerFrag); } ~Iterator(void) { if( innerIter != nullptr ) { delete innerIter; innerIter = nullptr; } } bool GetNextResult( <?php echo typed_ref_args($gla->output()); ?> ) { return innerIter->GetNextResult(<?php echo args($gla->output()); ?> ); } int FragmentNumber() { return fragmentNum; } }; <?php } else { // if inner result type is fragment ?> class Iterator { private: InnerGLA * gla; int fragmentNum; public: Iterator( InnerGLA * _gla, int fragNo ) : gla(_gla), fragmentNum(fragNo) { gla->Finalize(); } ~Iterator(void) { } bool GetNextResult( <?php echo typed_ref_args($gla->output()); ?> ) { return gla->GetNextResult(<?php echo args($gla->output()); ?> ); } int FragmentNumber() { return fragmentNum; } }; <?php } // if inner result type is multi ?> private: const ConstantState & constState; GLA_Array localState; // Iteration state for multi result type int numFrags; int multiFragNo; Iterator * multiIter; <?php if ($innerRes == 'fragment') { ?> using frag_info = std::pair<int, int>; using frag_map_t = std::unordered_map<int, frag_info>; frag_map_t fragMap; <?php } ?> <?php foreach ($savedArgs as $name => $type) { ?> const <?php echo $type; ?> <?php echo $name; ?> ; <?php } // foreach saved arg ?> public: // Constructor <?php echo $className; ?> ( <?php echo const_typed_ref_args($cArgs); ?> ) : constState(const_state) , localState() , numFrags(0) , multiFragNo(0) , multiIter(nullptr) <?php if ($innerRes == 'fragment') { ?> , fragMap() <?php } foreach ($savedArgs as $name => $type) { ?> , <?php echo $name; ?> (<?php echo $name; ?> ) <?php } // foreach constructor arg to save ?> { for( auto & elem : localState ) { elem.reset(new InnerGLA<?php echo $cstStr; ?> ); } } void AddItem( <?php echo const_typed_ref_args($input); ?> ) { uint64_t hashVal = CongruentHash(Hash(<?php echo $keyName; ?> ), H_b + 1); uint64_t passNum = (hashVal / NUM_STATES) % ConstantState::N_PASSES; uint64_t segNum = hashVal % NUM_STATES; <?php if ($n_passes > 1) { ?> if( passNum != constState.pass ) { return; } <?php } // more than 1 pass ?> localState[segNum]->AddItem(<?php echo args($innerInputs); ?> ); } void ChunkBoundary(void) { // Merge local states into the global state SplitState & globalStates = constState.segments; int theseAreOk[NUM_STATES]; for( int i = 0; NUM_STATES > i; i++ ) { theseAreOk[i] = 1; } int segsLeft = NUM_STATES; while( segsLeft > 0 ) { InnerGLA * checkedOut = nullptr; int whichOne = globalStates.CheckOutOne( theseAreOk, checkedOut ); if( checkedOut == NULL ) { checkedOut = new InnerGLA<?php echo $cstStr; ?> ; } checkedOut->AddState( *(localState[whichOne]) ); globalStates.CheckIn( whichOne, checkedOut ); theseAreOk[whichOne] = 0; segsLeft--; } // Re-initialize the local states for( auto & elem : localState ) { <?php if ($gla->is('resettable')) { ?> elem->Reset(); <?php } else { // if resettable ?> elem.reset(new InnerGLA<?php echo $cstStr; ?> ); <?php } // if not resettable ?> } } void AddState( <?php echo $className; ?> & o ) { // Do nothing } void Finalize() { SplitState & globalStates = constState.segments; if( multiIter != nullptr) delete multiIter; multiFragNo = 0; <?php if ($innerRes == 'fragment') { ?> frag_info fInfo = fragMap[multiFragNo]; multiIter = new Iterator(globalStates.Peek(fInfo.first), multiFragNo, fInfo.second); <?php } else { ?> multiIter = new Iterator(globalStates.Peek(multiFragNo), multiFragNo); <?php } ?> } bool GetNextResult(<?php echo typed_ref_args($output); ?> ) { bool gotResult = false; SplitState & globalStates = constState.segments; while( (multiFragNo < numFrags && multiIter != nullptr) && !gotResult ) { gotResult = multiIter->GetNextResult(<?php echo args($output); ?> ); if( !gotResult ) { multiFragNo++; delete multiIter; if( numFrags > multiFragNo ) { <?php if ($innerRes == 'fragment') { ?> frag_info fInfo = fragMap[multiFragNo]; multiIter = new Iterator(globalStates.Peek(fInfo.first), multiFragNo, fInfo.second); <?php } else { ?> multiIter = new Iterator(globalStates.Peek(multiFragNo), multiFragNo); <?php } ?> } else { multiIter = nullptr; } } } return gotResult; } int GetNumFragments(void) { <?php if ($innerRes == 'fragment') { ?> SplitState & globalStates = constState.segments; numFrags = 0; for (int i = 0; i < NUM_STATES; i++) { int curFrags = globalStates.Peek(i)->GetNumFragments(); for (int curFrag = 0; curFrag < curFrags; curFrag++) { fragMap[numFrags] = frag_info(i, curFrag); numFrags++; } } <?php } else { ?> numFrags = NUM_STATES; <?php } ?> return numFrags; } Iterator * Finalize( int fragment ) { SplitState & globalStates = constState.segments; <?php if ($innerRes == 'fragment') { ?> frag_info info = fragMap[fragment]; return new Iterator(globalStates.Peek(info.first), fragment, info.second); <?php } else { ?> return new Iterator(globalStates.Peek(fragment), fragment); <?php } ?> } bool GetNextResult( Iterator * it, <?php echo typed_ref_args($output); ?> ) { bool ret = it->GetNextResult(<?php echo args($output); ?> ); return ret; } <?php if ($iterable) { ?> bool ShouldIterate( ConstantState & modible ) { modible.pass++; return modible.pass < ConstantState::N_PASSES; } void PostFinalize() { constState.segments.Reset(); } <?php } // iterable ?> <?php if ($gla->is('finite container')) { ?> size_type size() { SplitState & globalStates = constState.segments; size_type s = 0; for( int i = 0; NUM_STATES > i; i++ ) { InnerGLA * ptr = globalStates.Peek(i); s += ptr->size(); } return s; } size_type size(int frag) { SplitState & globalStates = constState.segments; return globalStates.Peek(frag)->size(); } <?php } // if the gla is a container ?> }; typedef <?php echo $className; ?> ::Iterator <?php echo $className; ?> _Iterator; <?php return ['kind' => 'GLA', 'name' => $className, 'system_headers' => $system_headers, 'user_headers' => $user_headers, 'lib_headers' => $lib_headers, 'libraries' => $libraries, 'input' => $input, 'output' => $output, 'result_type' => $resType, 'generated_state' => $constState, 'required_states' => $gla->req_states(), 'chunk_boundary' => true, 'configurable' => $gla->configurable(), 'iterable' => $iterable, 'post_finalize' => $iterable, 'intermediates' => true]; }
function Multi_Hash(array $t_args, array $inputs, array $outputs) { // Class name randomly generated $className = generate_name('Hash'); // Processing of template arguments. $split = $t_args['split']; // Processing of inputs. $keys = array_slice($inputs, 0, $split); $vals = array_slice($inputs, $split); $sys_headers = ['map', 'tuple', 'unordered_map']; $user_headers = []; $lib_headers = ['HashFct.h']; $libraries = []; $properties = []; $extra = ['keys' => $keys, 'vals' => $vals]; $result_type = ['state']; ?> class <?php echo $className; ?> ; class <?php echo $className; ?> { public: // The standard hashing for Grokit is used, which returns a uint64_t. using Key = uint64_t; // The value type for the map that contains the various values passed through. using Tuple = std::tuple<<?php echo typed($vals); ?> >; // The map used, which must be a multimap. using Map = std::unordered_multimap<uint64_t, Tuple>; private: // The container that gathers the input. Map map; public: <?php echo $className; ?> () {} void AddItem(<?php echo const_typed_ref_args($inputs); ?> ) { auto key = ChainHash(<?php echo args($keys); ?> ); auto val = std::make_tuple(<?php echo args($vals); ?> ); map.insert(std::make_pair(key, val)); } void AddState(<?php echo $className; ?> & other) { map.insert(other.map.begin(), other.map.end()); } const Map& GetMap() const { return map; } static uint64_t ChainHash(<?php echo const_typed_ref_args($keys); ?> ) { uint64_t offset = 1; <?php foreach (array_keys($keys) as $name) { ?> offset = CongruentHash(Hash(<?php echo $name; ?> ), offset); <?php } ?> return offset; } }; <?php return ['kind' => 'GLA', 'name' => $className, 'system_headers' => $sys_headers, 'user_headers' => $user_headers, 'lib_headers' => $lib_headers, 'libraries' => $libraries, 'properties' => $properties, 'extra' => $extra, 'iterable' => false, 'input' => $inputs, 'output' => $outputs, 'result_type' => $result_type]; }
function OrderBy(array $t_args, array $inputs, array $outputs) { if (\count($inputs) == 0) { grokit_assert(array_key_exists('input', $t_args), 'No inputs given for OrderBy'); $inputs = $t_args['input']; foreach ($t_args['input'] as $name => &$type) { if (is_identifier($type)) { $type = lookupType(strval($type)); } grokit_assert(is_datatype($type), 'Invalid type given for input ' . $name); } } grokit_assert(array_key_exists('order', $t_args), 'No ordering attributes given for OrderBy'); $ordering = $t_args['order']; $ascOpts = ['ASC', 'ASCENDING', '+', '>']; $descOpts = ['DESC', 'DESCENDING', 'DES', 'DSC', '-', '<']; $ascending = []; foreach ($ordering as $name => $order) { grokit_assert(array_key_exists($name, $inputs), 'Ordering attribute ' . $name . ' not present in input'); if (in_array_icase($order, $ascOpts)) { $ascending[$name] = true; } else { if (in_array_icase($order, $descOpts)) { $ascending[$name] = false; } else { grokit_error("Unknown ordering " . $order . " given for attribute " . $name); } } } $rankAtt = get_default($t_args, 'rank', null); grokit_assert(is_null($rankAtt) || is_attribute($rankAtt), 'Rank argument should be null or an attribute'); grokit_assert(is_null($rankAtt) || array_key_exists($rankAtt->name(), $outputs), 'Rank attribute does not exist in outputs'); if (!is_null($rankAtt) && is_null($outputs[$rankAtt->name()])) { $outputs[$rankAtt->name()] = lookupType('base::BIGINT'); } $outputPassthroughAtts = []; foreach ($outputs as $name => $type) { if (is_null($rankAtt) || $rankAtt->name() != $name) { $outputPassthroughAtts[$name] = $type; } } $outToIn = []; $nInputs = \count($inputs); reset($inputs); reset($outputPassthroughAtts); for ($i = 0; $i < $nInputs; $i++) { $outName = key($outputPassthroughAtts); $inName = key($inputs); $outToIn[$outName] = $inName; // Unify types $outputs[$outName] = $inputs[$inName]; $outputPassthroughAtts[$outName] = $inputs[$inName]; next($inputs); next($outputPassthroughAtts); } $orderAtts = []; $extraAtts = []; foreach ($inputs as $name => $type) { if (array_key_exists($name, $ordering)) { $orderAtts[$name] = $type; } else { $extraAtts[$name] = $type; } } // Give 2^32 as the default, which should be effectively infinite $limitDefault = pow(2, 32); $limit = get_default($t_args, 'limit', $limitDefault); $limit = $limit == 0 ? $limitDefault : $limit; grokit_assert($limit > 0, 'The OrderBy limit must be a positive integer'); $className = generate_name('OrderBy'); $debug = get_default($t_args, 'debug', 0); ?> class <?php echo $className; ?> { struct Tuple { <?php foreach ($inputs as $name => $type) { ?> <?php echo $type; ?> <?php echo $name; ?> ; <?php } ?> Tuple( void ) = default; Tuple( const Tuple & other ) = default; Tuple( <?php echo array_template('const {val} & _{key}', ', ', $inputs); ?> ): <?php echo array_template('{key}(_{key})', ', ', $inputs); ?> { } Tuple & operator = (const Tuple & other ) = default; bool operator > ( const Tuple & other ) const { <?php foreach ($orderAtts as $name => $type) { $op1 = $ascending[$name] ? '<' : '>'; $op2 = !$ascending[$name] ? '<' : '>'; ?> if( <?php echo $name; ?> <?php echo $op1; ?> other.<?php echo $name; ?> ) return true; else if( <?php echo $name; ?> <?php echo $op2; ?> other.<?php echo $name; ?> ) return false; <?php } ?> return false; } bool operator < ( const Tuple& other ) const { return other > *this; } bool operator <= (const Tuple & other ) const { return ! (*this > other ); } bool operator >= (const Tuple & other ) const { return !( other > *this ); } <?php if ($debug > 0) { ?> std::string toString(void) const { std::ostringstream ss; ss << "( "; // > <?php $first = true; foreach ($inputs as $name => $type) { if ($first) { $first = false; } else { echo ' ss << ", ";' . PHP_EOL; } ?> ss << <?php echo $name; ?> ; // > <?php } // foreach input ?> ss << " )"; // > return ss.str(); } <?php } // debug > 0 ?> }; // struct Tuple typedef std::vector<Tuple> TupleVector; public: class Iterator { public: typedef TupleVector::const_iterator iter_type; private: iter_type begin; iter_type curr; iter_type end; public: Iterator(void) = default; Iterator( const iter_type & _begin, const iter_type & _end ) : begin(_begin), curr(_begin), end(_end) { } bool GetNextResult(<?php echo typed_ref_args($outputs); ?> ) { if( curr != end ) { <?php foreach ($outputPassthroughAtts as $name => $type) { ?> <?php echo $name; ?> = curr-><?php echo $outToIn[$name]; ?> ; <?php } if (!is_null($rankAtt)) { ?> <?php echo $rankAtt; ?> = (curr - begin) + 1; <?php } // if we need to output the rank ?> curr++; return true; } else { return false; } } }; private: uintmax_t __count; // number of tuples covered // K, as in Top-K static constexpr size_t K = <?php echo $limit; ?> ; TupleVector tuples; // Iterator for multi output type Iterator multiIterator; typedef std::greater<Tuple> TupleCompare; // Function to force sorting so that GetNext gets the tuples in order. void Sort(void) { TupleCompare comp; // If tuples doesn't contain at least K elements, it was never made into // a heap in the first place, so sort it normally. if( tuples.size() >= K ) { std::sort_heap(tuples.begin(), tuples.end(), comp); } else { std::sort(tuples.begin(), tuples.end(), comp); } } // Internal function to add a tuple to the heap void AddTupleInternal(Tuple & t ) { <?php if ($debug >= 1) { ?> { std::ostringstream ss; ss << "T ACK: " << t.toString() << std::endl; // > std::cerr << ss.str(); // > } <?php } ?> TupleCompare comp; if( tuples.size() >= K ) { <?php if ($debug >= 1) { ?> { std::ostringstream ss; ss << "T REP: " << tuples.front().toString() << std::endl; // > std::cerr << ss.str(); // > } <?php } ?> std::pop_heap(tuples.begin(), tuples.end(), comp); tuples.pop_back(); tuples.push_back(t); std::push_heap(tuples.begin(), tuples.end(), comp); } else { tuples.push_back(t); if( tuples.size() == K ) { std::make_heap(tuples.begin(), tuples.end(), comp); } } } public: <?php echo $className; ?> () : __count(0), tuples(), multiIterator() { } ~<?php echo $className; ?> () { } void AddItem(<?php echo const_typed_ref_args($inputs); ?> ) { __count++; Tuple t(<?php echo args($inputs); ?> ); <?php if ($debug >= 2) { ?> { std::ostringstream ss; ss << "T NEW: " << t.toString() << std::endl; // > std::cerr << ss.str(); // > } <?php } ?> if( tuples.size() == K && !(t > tuples.front()) ) return; AddTupleInternal(t); } void AddState( <?php echo $className; ?> & other ) { __count += other.__count; for( Tuple & el : other.tuples ) { if( tuples.size() < K /*>*/ || el > tuples.front() ) { AddTupleInternal(el); } } } void Finalize() { Sort(); Iterator::iter_type begin = tuples.cbegin(); Iterator::iter_type end = tuples.cend(); multiIterator = Iterator(begin, end); <?php if ($debug >= 1) { ?> std::ostringstream ss; ss << "[ "; //> bool first = true; for( auto el : tuples ) { if( first ) first = false; else ss << ", "; //>> ss << el.toString(); //>> } ss << " ]" << std::endl; // > std::cerr << ss.str(); //>> <?php } ?> } bool GetNextResult( <?php echo typed_ref_args($outputs); ?> ) { return multiIterator.GetNextResult(<?php echo args($outputs); ?> ); } }; <?php $system_headers = ['vector', 'algorithm', 'cinttypes']; if ($debug > 0) { $system_headers = array_merge($system_headers, ['iostream', 'sstream', 'string']); } return array('kind' => 'GLA', 'name' => $className, 'input' => $inputs, 'output' => $outputs, 'result_type' => 'multi', 'system_headers' => $system_headers); }