function SelectionGenerate($wpName, $queries, $attMap) { //echo PHP_EOL . '/*' . PHP_EOL; //print_r($wpName); //print_r($queries); //print_r($attMap); //echo PHP_EOL . '*/' . PHP_EOL; ?> // module specific headers to allow separate compilation #include "GLAData.h" #include "Errors.h" //+{"kind":"WPF", "name":"Pre-Processing", "action":"start"} extern "C" int SelectionPreProcessWorkFunc_<?php echo $wpName; ?> (WorkDescription& workDescription, ExecEngineData& result) { SelectionPreProcessWD myWork; myWork.swap(workDescription); QueryExitContainer& queries = myWork.get_whichQueryExits(); QueryToGLASContMap & requiredStates = myWork.get_requiredStates(); QueryToGLAStateMap constStates; <?php cgDeclareQueryIDs($queries); ?> <?php foreach ($queries as $query => $info) { $gf = $info['gf']; if (!is_null($gf) && $gf->has_state()) { $state = $gf->state(); if ($state->configurable()) { $carg = $info['cargs']; echo ' // JSON Configuration for query ' . queryName($query) . PHP_EOL; $carg->init(); echo PHP_EOL; } // if gf const state is configurable } // if gf has state } //foreach query ?> FOREACH_TWL(iter, queries) { <?php foreach ($queries as $query => $val) { ?> if( iter.query == <?php echo queryName($query); ?> ) { <?php if ($val['gf'] !== null) { // This is a generalized filter $gf = $val['gf']; $given_states = $val['states']; if ($gf->has_state()) { $cstArgs = []; $state = $gf->state(); // If the state is configurable, give it the JSON carg if ($state->configurable()) { $carg = $query['cargs']; $cstArgs[] = $carg->name(); } // if gf state is configurable if (\count($given_states) > 0) { ?> FATALIF(!requiredStates.IsThere(<?php echo queryName($query); ?> ), "No required states received for query that declared required states"); GLAStateContainer& givenStates = requiredStates.Find(<?php echo queryName($query); ?> ); givenStates.MoveToStart(); GLAPtr reqTemp; <?php foreach ($givenStates as $gs) { $cstArgs[] = $gs->name(); ?> // Extract state from waypoint[<?php echo $gs->waypoint(); ?> ] <?php echo $gs->type(); ?> * <?php echo $gs->name(); ?> = nullptr; reqTemp.Swap(givenStates.Current()); FATALIF( reqTemp.get_glaType() != <?php echo $gs->type()->cHash(); ?> , "Got different type than expected for required state of type <?php echo $gs > type(); ?> "); <?php echo $gs->name(); ?> = (<?php echo $gs->type(); ?> *) reqTemp.get_glaPtr(); reqTemp.swap(givenStates.Current()); givenStates.Advance(); <?php } // foreach given state } // if we have given states $cstStr = \count($cstArgs) > 0 ? '(' . implode(', ', $cstArgs) . ')' : ''; ?> <?php echo $state; ?> * temp = new <?php echo $state; echo $cstStr; ?> ; GLAPtr newPtr( <?php echo $state->cHash(); ?> , (void *) temp ); QueryID qryID = <?php echo queryName($query); ?> ; constStates.Insert(qryID, newPtr); <?php } // if gf has state } // if( $val['gf'] !== null ) ?> } // if <?php echo queryName($query); ?> is current query <?php } // foreach query ?> } END_FOREACH; SelectionPreProcessRez myRez( constStates ); myRez.swap(result); return WP_PREPROCESSING; // for PreProcess } //+{"kind":"WPF", "name":"Pre-Processing", "action":"end"} //+{"kind":"WPF", "name":"Process Chunk", "action":"start"} extern "C" int SelectionProcessChunkWorkFunc_<?php echo $wpName; ?> (WorkDescription &workDescription, ExecEngineData &result) { // go to the work description and get the input chunk SelectionProcessChunkWD myWork; myWork.swap (workDescription); Chunk &input = myWork.get_chunkToProcess (); QueryToGLAStateMap& constStates = myWork.get_constStates(); PROFILING2_START; QueryIDSet queriesToRun = QueryExitsToQueries(myWork.get_whichQueryExits ()); <?php cgDeclareQueryIDs($queries); cgAccessColumns($attMap, 'input', $wpName); // Declare the constants needed by the filters and synth expressions. foreach ($queries as $query => $val) { ?> // Constants for query <?php echo queryName($query); ?> : <?php $filters = $val['filters']; $synths = $val['synths']; cgDeclareConstants($filters); cgDeclareConstants($synths); } // foreach query ?> // prepare bitstring iterator Column inBitCol; BStringIterator queries; input.SwapBitmap (queries); // creating storage for syhthesized attributes <?php foreach ($queries as $query => $val) { $synList = $val['synths']; foreach ($synList as $att => $syn) { ?> MMappedStorage <?php echo attStorage($att); ?> ; Column <?php echo attCol($att); ?> (<?php echo attStorage($att); ?> ); <?php echo attIteratorType($att); ?> colI_<?php echo $att; ?> (<?php echo attCol($att); ?> ); <?php echo attType($att); ?> <?php echo $att; ?> ; <?php } // foreach synthesized attribute } // foreach query ?> <?php foreach ($queries as $query => $val) { $givenStates = $val['states']; $gf = $val['gf']; $cargs = $val['cargs']; grokit_assert($gf !== null || count($givenStates) == 0, 'We were given states for query ' . $query . ' when we have no GF!'); if (!is_null($gf) && $gf->has_state()) { $state = $gf->state(); $stateName = 'cst_state_' . queryName($query); $constMod = $state->mutable() ? '' : 'const '; ?> // Extracting constant state for query <?php echo queryName($query); ?> FATALIF(!constStates.IsThere(<?php echo queryName($query); ?> ), "No constant state found for query <?php echo queryName($query); ?> ."); <?php echo $constMod; echo $state; ?> * <?php echo $stateName; ?> = nullptr; { GLAState& curState = constStates.Find(<?php echo queryName($query); ?> ); GLAPtr tmp; tmp.swap(curState); FATALIF( tmp.get_glaType() != <?php echo $state->cHash(); ?> , "Got different type than expected for constant state of type <?php echo $state; ?> "); <?php echo $stateName; ?> = (<?php echo $constMod; echo $state; ?> *) tmp.get_glaPtr(); tmp.swap(curState); } <?php } // if gf requires constant state if ($gf !== null) { $ctrArgs = []; if ($gf->configurable()) { echo ' // JSON initialiser for query ' . queryName($query) . PHP_EOL; $cargs->init(); echo PHP_EOL; $ctrArgs[] = $cargs->name(); } if ($gf->has_state()) { $ctrArgs[] = '*' . $stateName; } $ctrStr = \count($ctrArgs) > 0 ? '(' . implode(', ', $ctrArgs) . ')' : ''; ?> // Construct GF for query <?php echo queryName($query); ?> <?php echo $gf->value(); ?> <?php echo queryName($query); ?> _state<?php echo $ctrStr; ?> ; <?php } // if we have a GF } // foreach query ?> MMappedStorage bitStore; Column outBitCol(bitStore); BStringIterator outQueries (outBitCol, queriesToRun); #ifdef PER_QUERY_PROFILE <?php foreach ($queries as $query => $val) { ?> int64_t n_tuples_<?php echo queryName($query); ?> = 0; <?php } // foreach query ?> #endif // PER_QUERY_PROFILE int64_t numTuples = 0; while (!queries.AtEndOfColumn ()) { ++numTuples; QueryIDSet qry; qry = queries.GetCurrent(); qry.Intersect(queriesToRun); queries.Advance(); //selection code for all the predicates <?php cgAccessAttributes($attMap); foreach ($queries as $query => $val) { $gf = $val['gf']; $filters = $val['filters']; $synths = $val['synths']; $stateName = queryName($query) . '_state'; $filterVals = array_map(function ($expr) { return '(' . $expr . ')'; }, $filters); if ($gf === null) { // Simple set of expressions. if (\count($filterVals) > 0) { $selExpr = implode(' && ', $filterVals); } else { $selExpr = 'true'; } } else { // We have a GF $selExpr = "{$stateName}.Filter(" . implode(', ', $filterVals) . ")"; } ?> // do <?php echo queryName($query); ?> : <?php foreach ($synths as $att => $syn) { ?> <?php echo attType($att); ?> <?php echo $att; ?> ; <?php } // foreach synthesized attribute ?> if( qry.Overlaps(<?php echo queryName($query); ?> ) ) { #ifdef PER_QUERY_PROFILE ++numTuples_<?php echo queryName($query); ?> ; #endif // PER_QUERY_PROFILE <?php cgDeclarePreprocessing($filters, 2); ?> if( <?php echo $selExpr; ?> ) { // compute synthesized <?php cgDeclarePreprocessing($synths, 3); foreach ($synths as $att => $expr) { ?> <?php echo $att; ?> = <?php echo $expr; ?> ; <?php } //foreach synthesized attribute ?> } else { qry.Difference(<?php echo queryName($query); ?> ); } } <?php foreach ($synths as $att => $syn) { ?> colI_<?php echo $att; ?> .Insert(<?php echo $att; ?> ); colI_<?php echo $att; ?> .Advance(); <?php } // foreach synthesized attribute } // foreach query ?> outQueries.Insert(qry); outQueries.Advance(); <?php cgAdvanceAttributes($attMap); ?> } // while we still have tuples remaining // finally, if there were any results, put the data back in the chunk <?php cgPutbackColumns($attMap, 'input', $wpName); foreach ($queries as $query => $val) { $synths = $val['synths']; ?> if (<?php echo queryName($query); ?> .Overlaps(queriesToRun)) { <?php foreach ($synths as $att => $expr) { ?> colI_<?php echo $att; ?> .Done(<?php echo attCol($att); ?> ); input.SwapColumn(<?php echo attCol($att); ?> , <?php echo attSlot($att); ?> ); <?php } //foreach synthesized attribute ?> } // If <?php echo queryName($query); ?> overlaps queriesToRun <?php } // foreach query ?> // put in the output bitmap outQueries.Done (); input.SwapBitmap (outQueries); // Finish performance counters PROFILING2_END; PCounterList counterList; PCounter totalCnt("tpi", numTuples, "<?php echo $wpName; ?> "); counterList.Append(totalCnt); PCounter tplOutCnt("tpo", numTuples, "<?php echo $wpName; ?> "); counterList.Append(tplOutCnt); #ifdef PER_QUERY_PROFILE <?php foreach ($queries as $query => $val) { $filters = $val['filters']; ?> if( <?php echo queryName($query); ?> .Overlaps(queriesToRun)) { PCounter cnt("<?php echo queryName($query); ?> ", numTuples_<?php echo queryName($query); ?> , "<?php echo $wpName; ?> "); counterList.Append(cnt); } <?php } // foreach query ?> #endif // PER_QUERY_PROFILE PROFILING2_SET(counterList, "<?php echo $wpName; ?> "); ChunkContainer tempResult (input); tempResult.swap (result); return WP_PROCESS_CHUNK; // For Process Chunk } //+{"kind":"WPF", "name":"Process Chunk", "action":"end"} <?php }
function cgExtractColumnFragment($att, $chunk, $start, $end, $wpName) { ?> // extracting <?php echo $att; ?> : Column <?php echo attCol($att); ?> ; if (<?php echo attQrys($att); ?> .Overlaps(queriesToRun)){ <?php echo $chunk; ?> .SwapColumn(<?php echo attCol($att); ?> , <?php echo attSlot($att); ?> ); if (! <?php echo attCol($att); ?> .IsValid()){ FATAL("Error: Column <?php echo $att; ?> not found in <?php echo $wpName; ?> \n"); } } <?php echo attIteratorType($att); ?> <?php echo attData($att); ?> (<?php echo attCol($att); ?> /*, 8192*/, <?php echo $start; ?> , <?php echo $end; ?> ); <?php }