예제 #1
0
ALWAYS_INLINE
typename std::enable_if<
  std::is_base_of<BaseMap, TMap>::value, Object>::type
BaseMap::php_differenceByKey(const Variant& it) {
  if (!it.isObject()) {
    SystemLib::throwInvalidArgumentExceptionObject(
               "Parameter it must be an instance of Iterable");
  }
  ObjectData* obj = it.getObjectData();
  TMap* target = BaseMap::Clone<TMap>(this);
  auto ret = Object::attach(target);
  if (obj->isCollection()) {
    if (isMapCollection(obj->collectionType())) {
      auto map = static_cast<BaseMap*>(obj);
      auto* eLimit = map->elmLimit();
      for (auto* e = map->firstElm(); e != eLimit; e = nextElm(e, eLimit)) {
        if (e->hasIntKey()) {
          target->remove((int64_t)e->ikey);
        } else {
          assert(e->hasStrKey());
          target->remove(e->skey);
        }
      }
      return ret;
    }
  }
  for (ArrayIter iter(obj); iter; ++iter) {
    Variant k = iter.first();
    if (k.isInteger()) {
      target->remove(k.toInt64());
    } else {
      assert(k.isString());
      target->remove(k.getStringData());
    }
  }
  return ret;
}
예제 #2
0
Object c_GenMapWaitHandle::ti_create(const Variant& dependencies) {
  ObjectData* obj;
  if (UNLIKELY(!dependencies.isObject() ||
      !(obj = dependencies.getObjectData())->isCollection() ||
      obj->collectionType() != CollectionType::Map)) {
    SystemLib::throwInvalidArgumentExceptionObject(
      "Expected dependencies to be an instance of Map");
  }
  assertx(obj->collectionType() == CollectionType::Map);
  auto deps = req::ptr<c_Map>::attach(c_Map::Clone(obj));
  auto ctx_idx = std::numeric_limits<context_idx_t>::max();
  for (ssize_t iter_pos = deps->iter_begin();
       deps->iter_valid(iter_pos);
       iter_pos = deps->iter_next(iter_pos)) {

    auto* current = tvAssertCell(deps->iter_value(iter_pos));
    auto const child = c_WaitHandle::fromCell(current);
    if (UNLIKELY(!child)) {
      SystemLib::throwInvalidArgumentExceptionObject(
        "Expected dependencies to be a map of WaitHandle instances");
    }

    if (!child->isFinished()) {
      ctx_idx = std::min(
        ctx_idx,
        static_cast<c_WaitableWaitHandle*>(child)->getContextIdx()
      );
    }
  }

  Object exception;
  for (ssize_t iter_pos = deps->iter_begin();
       deps->iter_valid(iter_pos);
       iter_pos = deps->iter_next(iter_pos)) {

    auto* current = tvAssertCell(deps->iter_value(iter_pos));
    assert(current->m_type == KindOfObject);
    assert(current->m_data.pobj->instanceof(c_WaitHandle::classof()));
    auto child = static_cast<c_WaitHandle*>(current->m_data.pobj);

    if (child->isSucceeded()) {
      auto k = deps->iter_key(iter_pos);
      auto result = child->getResult();
      deps->set(k.asCell(), &result);
    } else if (child->isFailed()) {
      putException(exception, child->getException());
    } else {
      assert(child->instanceof(c_WaitableWaitHandle::classof()));
      auto child_wh = static_cast<c_WaitableWaitHandle*>(child);

      auto my_wh = req::make<c_GenMapWaitHandle>();
      my_wh->initialize(exception, deps.get(), iter_pos, ctx_idx, child_wh);

      AsioSession* session = AsioSession::Get();
      if (UNLIKELY(session->hasOnGenMapCreate())) {
        session->onGenMapCreate(my_wh.get(), dependencies);
      }

      return Object(std::move(my_wh));
    }
  }

  if (exception.isNull()) {
    return Object::attach(c_StaticWaitHandle::CreateSucceeded(
      make_tv<KindOfObject>(deps.detach())));
  } else {
    return Object::attach(c_StaticWaitHandle::CreateFailed(exception.detach()));
  }
}