// 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();
                    	}

                }
Esempio n. 2
0
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);
  }
}
Esempio n. 4
0
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;
  }
}