// The default operator called from parallel_for void operator() (const tbb::blocked_range<int64> &range) const { callerContext.EnteringOperator(); // Build arguments array Array args = Array::Create(); // Pass the range start and end as parameters args.append(range.begin()); args.append(range.end()); // If an input array is defined, copy it and pass as a parameter if(inputArrayOfVariant.size() > 0) { Array inputPHPArray = Array::Create(); for(size_t ai=0; ai<inputArrayOfVariant.size(); ai++) inputPHPArray.append(inputArrayOfVariant[ai]); Variant inputArrayArg(inputPHPArray.getArrayData()); args.append(inputArrayArg); } // Call user supplied callback with arguments // This is a PHP function of the form worker($begin, $end, $array), returning an array or nothing // If an array is returned, it is expected to have elements which will be comingled into the output // array in the elements defined by the input range. Variant vres = f_call_user_func_array(this->callback, args); callerContext.ExitingOperator(); // Call this straight after the callback completes // Return if no result to pass back if(vres.isNull() || !vres.isArray()) return; // Now we take the output array [0..N) and assign it into the overall output array at [begin..begin+N) // Extract output array from result variant const Array aOutputArray = vres.asCArrRef(); ArrayData *pdOutputArray = aOutputArray.getArrayData(); Variant v = pdOutputArray->reset(); // Check the output array is the same size or smaller than the range passed size_t outIdx = range.begin(); if(pdOutputArray->size() > (range.end()-range.begin())) { raise_warning("Callback function returned array larger than passed range size"); return; } // Copy each row while(!v.isBoolean() || v.toBoolean()) { // printf(" outIdx=%d, v=%s\n", (int)outIdx, v.toString().c_str()); ( *pOutputArrayOfVariant ) [outIdx++] = v; v = pdOutputArray->next(); } }
MutableArrayIter::MutableArrayIter(const Variant *var ,Variant *key, Variant &val) : m_var(var), m_key(key), m_val(val), m_pos() { ASSERT(m_var); ArrayData *data = getData(); if (data) { data->reset(); data->getFullPos(m_pos); } }
MutableArrayIter::MutableArrayIter(const Variant *var, Variant *key, Variant &val) : m_var(var), m_data(NULL), m_key(key), m_val(val), m_fp() { ASSERT(m_var); ArrayData *data = getData(); if (data) { data->reset(); data->newFullPos(m_fp); ASSERT(m_fp.container == data); } }
MutableArrayIter::MutableArrayIter(const Variant *var, Variant *key, Variant &val) : m_var(var), m_data(NULL), m_key(key), m_valp(&val), m_fp() { assert(m_var); escalateCheck(); ArrayData* data = cowCheck(); if (data) { data->reset(); data->newFullPos(m_fp); assert(m_fp.container == data); } }
bool GlobalArrayWrapper::setFullPos(const FullPos &fp) { if (fp.pos != ArrayData::invalid_index) { if (m_pos < m_globals->staticSize()) return true; ArrayData *data = m_globals->getArrayData(); if (data) { data->reset(); return true; } else { return false; } } else { return false; } }