Ejemplo n.º 1
0
bool MutableArrayIter::advance() {
    ArrayData *data = m_var ? getData() : m_data;
    if (!data) return false;
    // If the foreach loop's array changed since the previous iteration,
    // we recover by creating a new strong iterator for the new array,
    // starting with at the position indicated by the new array's internal
    // pointer.
    if (m_fp.container != data) {
        // Free the current strong iterator if its valid
        if (m_fp.container != NULL) {
            m_fp.container->freeFullPos(m_fp);
        }
        assert(m_fp.container == NULL);
        // If needed, escalate the array to an array type that can support
        // foreach by reference
        escalateCheck();
        // Trigger COW if needed, copying over strong iterators
        data = cowCheck();
        // Create a new strong iterator for the new array
        data->newFullPos(m_fp);
    } else {
        // Trigger COW if needed, copying over strong iterators
        data = cowCheck();
    }
    assert(m_fp.container == data);
    if (!data->setFullPos(m_fp)) return false;
    CVarRef curr = data->currentRef();
    m_valp->assignRef(curr);
    if (m_key) m_key->assignVal(data->key());
    data->next();
    data->getFullPos(m_fp);
    return true;
}
Ejemplo n.º 2
0
bool MutableArrayIter::advance() {
  ArrayData *data = m_var ? getData() : m_data;
  if (!data) return false;
  // If the foreach loop's array changed since the previous iteration,
  // we recover by creating a new strong iterator for the new array,
  // starting with at the position indicated by the new array's internal
  // pointer.
  if (m_fp.container != data) {
    // Free the current strong iterator if its valid
    if (m_fp.container != NULL) {
      m_fp.container->freeFullPos(m_fp);
    }
    // Create a new strong iterator for the new array
    ASSERT(m_fp.container == NULL);
    data->newFullPos(m_fp);
  }
  ASSERT(m_fp.container == data);
  if (!data->setFullPos(m_fp)) return false;
  CVarRef curr = data->currentRef();
  curr.setContagious();
  m_val = curr;
  if (m_key) *m_key = data->key();
  data->next();
  data->getFullPos(m_fp);
  return true;
}
                // 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();
                    	}

                }
Ejemplo n.º 4
0
bool MutableArrayIter::advance() {
  ArrayData *data = getData();
  if (!data) return false;
  if (!data->setFullPos(m_pos)) return false;
  CVarRef curr = data->currentRef();
  curr.setContagious();
  m_val = curr;
  if (m_key) *m_key = data->key();
  data->next();
  data->getFullPos(m_pos);
  return true;
}