示例#1
0
bool
Timer::add(Event* e, int id, int64_t cycle, void* param)
{
	const intptr_t key((intptr_t)e);
	auto ib = m_clients.find(key);

	if ( ib == m_clients.end() )
	{
		auto res = m_clients.insert(client_cont::value_type(key, event_cont()));
		if ( res.second == false )
		{
			PWLOGLIB("failed to insert timer event: e:%p id:%d cycle:%jd param:%p", e, id, intmax_t(cycle), param);
			return false;
		}

		event_cont& ec(res.first->second);

		// 이후 코드는 insert 성공 여부와 상관 없이 반복자가 무효하다.
		invalidateIterator();

		if ( false == ec.insert(event_cont::value_type(id, event_type(param, cycle, s_getNow()))).second )
		{
			PWLOGLIB("failed to insert timer event: e:%p id:%d cycle:%jd param:%p", e, id, intmax_t(cycle), param);
			m_clients.erase(ib);
			return false;
		}

		//PWTRACE("add new timer event: e:%p type:%s id:%d cycle:%jdms", e, typeid(*e).name(), id, cycle);
		return true;
	}

	auto& ec = ib->second;
	auto ib_event = ec.find(id);

	if ( ec.end() == ib_event )
	{
		if ( false == ec.insert(event_cont::value_type(id, event_type(param, cycle, s_getNow()))).second )
		{
			PWLOGLIB("failed to insert timer event: e:%p id:%d cycle:%jd param:%p", e, id, intmax_t(cycle), param);
			return false;
		}

		invalidateIterator();
		//PWTRACE("add new timer event: e:%p type:%s id:%d cycle:%jdms", e, typeid(*e).name(), id, cycle);
		return true;
	}

	// 반복자를 건들지 않았으므로 invalidateIterator를 호출하지 않는다.
	auto& et = ib_event->second;
	et.param = param;
	et.cycle = cycle;
	et.start = s_getNow();

	//PWTRACE("add new timer event: e:%p type:%s id:%d cycle:%jdms", e, typeid(*e).name(), id, cycle);
	return true;
}
示例#2
0
PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue)
{
    ASSERT(!value.isNull());
    
    // Implement copy-on-write semantics here.  We're guaranteed that the only refs of StorageMaps belong to Storage objects
    // so if more than one Storage object refs this map, copy it before mutating it.
    if (refCount() > 1) {
        RefPtr<StorageMap> newStorageMap = copy();
        newStorageMap->setItem(key, value, oldValue);
        return newStorageMap.release();
    }

    pair<HashMap<String, String>::iterator, bool> addResult = m_map.add(key, value);

    if (addResult.second) {
        // There was no "oldValue" so null it out.
        oldValue = String();
    } else {
        oldValue = addResult.first->second;
        addResult.first->second = value;
    }

    invalidateIterator();

    return 0;
}
示例#3
0
PassRefPtr<StorageMap> StorageMap::removeItem(const String& key, String& oldValue)
{
    // Implement copy-on-write semantics here.  We're guaranteed that the only refs of StorageMaps belong to Storage objects
    // so if more than one Storage object refs this map, copy it before mutating it.
    if (refCount() > 1) {
        RefPtr<StorageMap> newStorage = copy();
        newStorage->removeItem(key, oldValue);
        return newStorage.release();
    }

    oldValue = m_map.take(key);
    if (!oldValue.isNull())
        invalidateIterator();

    return 0;
}
示例#4
0
void
Timer::remove(Event* e, int id)
{
	const auto key(reinterpret_cast<intptr_t>(e));
	auto ib(m_clients.find(key));
	if ( ib == m_clients.end() ) return;

	auto& ec(ib->second);

	do {
		auto ib_event(ec.find(id));
		if ( ib_event == ec.end() ) return;

		ec.erase(ib_event);
		if ( ec.empty() ) m_clients.erase(ib);
	} while (false);

	invalidateIterator();
}
示例#5
0
PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue, bool& quotaException)
{
    ASSERT(!value.isNull());
    quotaException = false;

    // Implement copy-on-write semantics here.  We're guaranteed that the only refs of StorageMaps belong to Storage objects
    // so if more than one Storage object refs this map, copy it before mutating it.
    if (refCount() > 1) {
        RefPtr<StorageMap> newStorageMap = copy();
        newStorageMap->setItem(key, value, oldValue, quotaException);
        return newStorageMap.release();
    }

    // Quota tracking.  This is done in a couple of steps to keep the overflow tracking simple.
    unsigned newLength = m_currentLength;
    bool overflow = newLength + value.length() < newLength;
    newLength += value.length();

    oldValue = m_map.get(key);
    overflow |= newLength - oldValue.length() > newLength;
    newLength -= oldValue.length();

    unsigned adjustedKeyLength = oldValue.isNull() ? key.length() : 0;
    overflow |= newLength + adjustedKeyLength < newLength;
    newLength += adjustedKeyLength;

    ASSERT(!overflow);  // Overflow is bad...even if quotas are off.
    bool overQuota = newLength > m_quotaSize / sizeof(UChar);
    if (m_quotaSize != noQuota && (overflow || overQuota)) {
        quotaException = true;
        return 0;
    }
    m_currentLength = newLength;

    HashMap<String, String>::AddResult addResult = m_map.add(key, value);
    if (!addResult.isNewEntry)
        addResult.iterator->value = value;

    invalidateIterator();

    return 0;
}
bool MultiMap::Iterator::next()
{
	if (!valid())
		return false;

	while (m_ptrToNode != nullptr)
	{
		// check is cur->duplicate counter is greater than 0
		// if it is, check where this (next or prev) function last left off
		if (m_ptrToNode->duplicateTotal > 0)
		{
			if (m_ptrToNodeList->next != nullptr)
			{
				m_ptrToNodeList = m_ptrToNodeList->next;
				m_currentDuplicateValue = m_ptrToNodeList->value;
				return true;
			}
		}

		// Check non nullptr right child
		if (m_ptrToNode->right != nullptr)
		{
			m_ptrToNode = m_ptrToNode->right;
			// Now check for left children
			if (m_ptrToNode->left == nullptr)
			{
				m_ptrToNodeList = m_ptrToNode->val;
				m_currentDuplicateValue = m_ptrToNodeList->value;
				return true;
			}
			else
			{
				while (m_ptrToNode->left != nullptr)
					m_ptrToNode = m_ptrToNode->left;

				m_ptrToNodeList = m_ptrToNode->val;
				m_currentDuplicateValue = m_ptrToNodeList->value;
				return true;
			}
		}

		// If right child nullptr, check parent (loop up through parents)
		if (m_ptrToNode->right == nullptr)
		{
			std::string tempKey = m_ptrToNode->key;
			while (m_ptrToNode->parent != nullptr)
			{
				m_ptrToNode = m_ptrToNode->parent;
				if (m_ptrToNode->key > tempKey)
				{
					m_ptrToNodeList = m_ptrToNode->val;
					m_currentDuplicateValue = m_ptrToNodeList->value;
					return true;
				}
			}
			// Invalidates iterator to prevent undefined behavior
			invalidateIterator();
			return false;
		}
	}
	invalidateIterator();
	return false;
}
bool MultiMap::Iterator::prev()
{
	if (!valid())
		return false;

	while (m_ptrToNode != nullptr)
	{
		// First check for duplicate values beginning from current tail pointer
		if (m_ptrToNode->duplicateTotal > 0)
		{
			if (m_ptrToNodeList->prev != nullptr)
			{
				m_ptrToNodeList = m_ptrToNodeList->prev;
				m_currentDuplicateValue = m_ptrToNodeList->value;
				return true;
			}
		}

		// If left child is not nullptr go down that branch 
		// and check if that child has a right child
		if (m_ptrToNode->left != nullptr)
		{
			m_ptrToNode = m_ptrToNode->left;

			// If that child has a right child, loop down the right child branch
			// until we hit a nullptr
			if (m_ptrToNode->right != nullptr)
			{
				while (m_ptrToNode->right != nullptr)
					m_ptrToNode = m_ptrToNode->right;
				m_ptrToNodeList = m_ptrToNode->tail;
				m_currentDuplicateValue = m_ptrToNodeList->value;
				return true;
			}

			// Otherwise if right child is nullptr, we are at the right (prev) spot
			else
			{
				m_ptrToNodeList = m_ptrToNode->tail;
				m_currentDuplicateValue = m_ptrToNodeList->value;
				return true;
			}
		}

		// If left child IS a nullptr, loop through parents until we find
		// the first node that is less than the current key or until
		// we hit a parent nullptr (return false in this case)
		if (m_ptrToNode->left == nullptr)
		{
			std::string tempKey = m_ptrToNode->key;
			while (m_ptrToNode->parent != nullptr)
			{
				m_ptrToNode = m_ptrToNode->parent;
				if (m_ptrToNode->key < tempKey)
				{
					m_ptrToNodeList = m_ptrToNode->tail;
					m_currentDuplicateValue = m_ptrToNodeList->value;
					return true;
				}
			}
			invalidateIterator();
			return false;
		}
	}
	invalidateIterator();
	return false;
}