Exemple #1
0
	void CoroutineService::on_update(const int64_t now){
		Super::on_update(now);
		// wakeup sleeper
		if(m_sleeper_table->size() > 0){
			// prepare wake up list
			Int64Array* wake_list =0;
			HashIterator* it =static_cast< HashIterator* >(m_sleeper_table->iterator());
			while(it->next()){
				Int64* cr_id =static_cast< Int64* >(it->getKey());
				Int64* expire_time =static_cast< Int64* >(it->getValue());
				if(expire_time->getValue() > now){
					if(!wake_list){
						wake_list =SafeNew<Int64Array>();
					}
					wake_list->push_back(cr_id->getValue());
					it->remove();
				}
			}

			// wake up
			const int64_t n =wake_list ? wake_list->size() : 0;
			for(int64_t i=0; i<n; ++i){
				_resume_coroutine(wake_list->get(i), SafeNew<Error>(ErrorCode::TIMEOUT), 0);
			}
		}

		// update
		int64_t cr_new_id=0;
		m_cr_pool->go(_update, 0, cr_new_id);
	}
Exemple #2
0
 int Ardb::HashLen(Context& ctx, const Slice& key)
 {
     ValueObject meta;
     int err = GetMetaValue(ctx, key, HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (err == ERR_NOT_EXIST)
     {
         fill_int_reply(ctx.reply, 0);
     }
     else
     {
         if (meta.meta.Length() < 0)
         {
             HashIterator iter;
             meta.meta.len = 0;
             HashIter(ctx, meta, "", iter, true);
             while (iter.Valid())
             {
                 meta.meta.len++;
                 iter.Next();
             }
             SetKeyValue(ctx, meta);
         }
         fill_int_reply(ctx.reply, meta.meta.Length());
     }
     return 0;
 }
Exemple #3
0
	void CoroutinePool::finalize(){
		m_cleaning =true;

		// clean idle list
		for(int64_t i=0; i<m_idle_coroutine_list->size(); ++i){
			Coroutine* cr =static_cast< Coroutine* >(m_idle_coroutine_list->get(i));
			cr->resume(SafeNew<Error>(ErrorCode::COROUTINE_CLEAN), 0);
			ASSERT(cr->getStatus() == Coroutine::STATUS_DEAD);
		}
		CLEAN_POINTER(m_idle_coroutine_list);

		// clean active table
		Hash* active_cr_tb =m_active_coroutine_table;
		m_active_coroutine_table =0;
		HashIterator* it =static_cast< HashIterator* >(active_cr_tb->iterator());
		while(it->next()){
			Coroutine* cr =static_cast< Coroutine* >(it->getValue());
			cr->resume(SafeNew<Error>(ErrorCode::COROUTINE_CLEAN), 0);
			ASSERT(cr->getStatus() == Coroutine::STATUS_DEAD);
		}
		CLEAN_POINTER(active_cr_tb);

		// super
		Super::finalize();
	}
Exemple #4
0
	void Hash::forEach(void (*pfn)(Object*, Object*, void*), void* userdata){
		if(!pfn) return;
		HashIterator* it =dynamic_cast<HashIterator*>(iterator());
		while(it->next()){
			pfn(it->getKey(), it->getValue(), userdata);
		}
	}
Exemple #5
0
 int Ardb::HashGetAll(Context& ctx, const Slice& key, RedisReply& reply)
 {
     ValueObject meta;
     int err = GetMetaValue(ctx, key, HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     reply.type = REDIS_REPLY_ARRAY;
     if (0 != err)
     {
         return 0;
     }
     HashIterator iter;
     err = HashIter(ctx, meta, "", iter, true);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     reply.type = REDIS_REPLY_ARRAY;
     while (iter.Valid())
     {
         const Data* field = iter.Field();
         Data* value = iter.Value();
         RedisReply& r = reply.AddMember();
         fill_value_reply(r, *field);
         RedisReply& r1 = reply.AddMember();
         fill_value_reply(r1, *value);
         iter.Next();
     }
     return 0;
 }
Exemple #6
0
	Array* Actor::getAllComponent(){
		Array* ret =SafeNew<Array>();
		HashIterator* it =static_cast< HashIterator* >(m_component_manager->iterator());
		while(it->next()){
			ret->push_back(it->getValue());
		}
		return ret;
	}
Exemple #7
0
status_t
Directory::Rewind(void *cookie)
{
	HashIterator *iterator = (HashIterator *)cookie;
	iterator->Rewind();

	return B_OK;
}
Exemple #8
0
	Object * Hash::clone(){
		Hash* new_obj =core::SafeNew<Hash>();
		HashIterator* it =dynamic_cast<HashIterator*>(this->iterator());
		while(it->next()){
			new_obj->set(it->getKey(), it->getValue());
		}
		return new_obj;
	}
Exemple #9
0
	void Hash::removeIf(bool (*pfn)(Object*, Object*)){
		if(!pfn) return;
		HashIterator* it =dynamic_cast<HashIterator*>(iterator());
		while(it->next()){
			if(pfn(it->getKey(), it->getValue())){
				it->remove();
			}
		}
	}
Exemple #10
0
void CommandService::_optimize(const int64_t now) {
    if(m_queue_tb->size() > OPTIMIZE_THRESHOLD) {
        HashIterator* it =static_cast< HashIterator* >(m_queue_tb->iterator());
        while(it->next()) {
            Array* queue =static_cast< Array* >(it->getValue());
            if(queue->empty()) {
                it->remove();
            }
        }
        m_queue_tb->optimize(0);
    }
}
Exemple #11
0
status_t
Directory::GetNextEntry(void *cookie, char *name, size_t size)
{
	HashIterator *iterator = (HashIterator *)cookie;
	int32 block;

	NodeBlock *node = iterator->GetNext(block);
	if (node == NULL)
		return B_ENTRY_NOT_FOUND;

	return node->GetName(name, size);
}
Exemple #12
0
 int Ardb::HClear(Context& ctx, ValueObject& meta)
 {
     BatchWriteGuard guard(GetKeyValueEngine(), meta.meta.encoding != COLLECTION_ECODING_ZIPMAP);
     if (meta.meta.encoding != COLLECTION_ECODING_ZIPMAP)
     {
         HashIterator iter;
         HashIter(ctx, meta, "", iter, false);
         while (iter.Valid())
         {
             DelRaw(ctx, iter.CurrentRawKey());
             iter.Next();
         }
     }
     DelKeyValue(ctx, meta.key);
     return 0;
 }
Exemple #13
0
void CommandService::_process_timeout(const int64_t now) {
    /* clear timeout command */
    if(m_queue_tb->size()>0) {
        Int64Array* ls =0;
        HashIterator* it =static_cast< HashIterator* >(m_queue_tb->iterator());
        while(it->next()) {
            const int64_t who =static_cast< Int64* >(it->getKey())->getValue();
            Array* queue =static_cast< Array* >(it->getValue());
            while(Command* cmd =dynamic_cast< Command* >(queue->front())) {
                if(cmd->isTimeout(now)) {
                    if(cmd->isProcessing()) {
                        WARN("service %s(%lld) who %lld command %lld cancel", name(), (long long)m_id, (long long)cmd->getWho(), (long long)cmd->getCommand());
                    }
                    queue->pop_front();
                }
                else {
                    break;
                }
            }
            if(Command* cmd =dynamic_cast< Command* >(queue->front())) {
                if(cmd->isProcessing()) {
                    continue;
                }
                ASSERT(cmd->isInit());
                if(!ls) {
                    ls =SafeNew<Int64Array>();
                }
                ls->push_back(who);
            }
        }
        const int64_t n= ls ? ls->size() : 0;
        for(int64_t i=0; i<n; ++i) {
            _process_request(ls->get(i));
        }
    }
    /* clear timeout rpc */
    if(m_rpc_tb->size()>0) {
        Array* ls =0;
        HashIterator* it =static_cast< HashIterator* >(m_rpc_tb->iterator());
        while(it->next()) {
            RpcInfo* ri =static_cast< RpcInfo* >(it->getValue());
            if(now >= ri->getExpireTime()) {
                if(!ls) {
                    ls =SafeNew<Array>();
                }
                ls->push_back(ri);
                it->remove();
            }
        }
        const int64_t n =ls ? ls->size() : 0;
        for(int64_t i=0; i<n; ++i) {
            RpcInfo* ri =static_cast< RpcInfo* >(ls->get(i));
            WARN("service %s(%lld) rpc %lld cancel", name(), (long long)m_id, (long long)ri->getId());
            ri->timeout();
        }
    }
}
Exemple #14
0
status_t
Directory::Open(void **_cookie, int mode)
{
	_inherited::Open(_cookie, mode);

	HashIterator *iterator = new(nothrow) HashIterator(fVolume.Device(), fNode);
	if (iterator == NULL)
		return B_NO_MEMORY;

	if (iterator->InitCheck() != B_OK) {
		delete iterator;
		return B_NO_MEMORY;
	}

	*_cookie = (void *)iterator;
	return B_OK;
}
	Int64Array* ServiceManager::_get_need_unload_service_id(){
		std::lock_guard<LOCK_TYPE> guard(m_lock);
		if(m_unloading_service_tb->empty()){
			return 0;
		}
		const int64_t now =DateTime::Now();
		Int64Array* arr =SafeNew<Int64Array>();
		HashIterator* it =static_cast< HashIterator* >(m_unloading_service_tb->iterator());
		while(it->next()){
			const int64_t id_srv =static_cast< Int64* >(it->getKey())->getValue();
			const int64_t t =static_cast< Int64* >(it->getValue())->getValue();
			if(now >= t){
				arr->push_back(id_srv);
				it->remove();
			}
		}
		return arr;
	}
Exemple #16
0
 int Ardb::RenameHash(Context& ctx, DBID srcdb, const std::string& srckey, DBID dstdb, const std::string& dstkey)
 {
     Context tmpctx;
     tmpctx.currentDB = srcdb;
     ValueObject v;
     int err = GetMetaValue(tmpctx, srckey, HASH_META, v);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (0 != err)
     {
         fill_error_reply(ctx.reply, "no such key or some error");
         return 0;
     }
     if (v.meta.encoding == COLLECTION_ECODING_ZIPMAP)
     {
         DelKeyValue(tmpctx, v.key);
         v.key.encode_buf.Clear();
         v.key.db = dstdb;
         v.key.key = dstkey;
         v.meta.expireat = 0;
         SetKeyValue(ctx, v);
     }
     else
     {
         HashIterator iter;
         HashIter(ctx, v, "", iter, false);
         tmpctx.currentDB = dstdb;
         ValueObject dstmeta;
         dstmeta.key.type = KEY_META;
         dstmeta.key.key = dstkey;
         dstmeta.type = HASH_META;
         dstmeta.meta.encoding = COLLECTION_ECODING_ZIPMAP;
         BatchWriteGuard guard(GetKeyValueEngine());
         while (iter.Valid())
         {
             HashSet(tmpctx, dstmeta, *(iter.Field()), *(iter.Value()));
             iter.Next();
         }
         SetKeyValue(tmpctx, dstmeta);
         tmpctx.currentDB = srcdb;
         DeleteKey(tmpctx, srckey);
     }
     ctx.data_change = true;
     return 0;
 }
	void ServiceManager::unloadAllService(){
		OPH();
		// prepare service table
		Hash* srv_tb =0;
		{
			std::lock_guard<LOCK_TYPE> guard(m_lock);
			srv_tb =static_cast< Hash* >(m_service_tb->clone());
			m_service_tb->clear();
			m_route_tb->clear();
			m_unloading_service_tb->clear();
		}
		// unload
		HashIterator* it =static_cast< HashIterator* >(srv_tb->iterator());
		while(it->next()){
			Service* service =static_cast< Service* >(it->getValue());
			if(service){
				service->unload();
			}
		}
		srv_tb->clear();
	}
Exemple #18
0
 int Ardb::HVals(Context& ctx, RedisCommandFrame& cmd)
 {
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     ctx.reply.type = REDIS_REPLY_ARRAY;
     if (0 != err)
     {
         return 0;
     }
     HashIterator iter;
     err = HashIter(ctx, meta, "", iter, true);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     ctx.reply.type = REDIS_REPLY_ARRAY;
     while (iter.Valid())
     {
         Data* value = iter.Value();
         RedisReply& r = ctx.reply.AddMember();
         fill_value_reply(r, *value);
         iter.Next();
     }
     return 0;
 }
Exemple #19
0
 int Ardb::HKeys(Context& ctx, RedisCommandFrame& cmd)
 {
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     ctx.reply.type = REDIS_REPLY_ARRAY;
     if (0 != err)
     {
         return 0;
     }
     HashIterator iter;
     err = HashIter(ctx, meta, "", iter, true);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     ctx.reply.type = REDIS_REPLY_ARRAY;
     while (iter.Valid())
     {
         const Data* value = iter.Field();
         RedisReply& r = ctx.reply.AddMember();
         std::string tmp;
         fill_str_reply(r, value->GetDecodeString(tmp));
         iter.Next();
     }
     return 0;
 }
Exemple #20
0
	/** coroutine manager **/
	void CoroutinePool::update(const int64_t now){
		// process timeout
		if(m_active_coroutine_table && m_active_coroutine_table->size()>0){
			// prepare
			Int64Array* ls =0;
			HashIterator* it =static_cast< HashIterator* >(m_active_coroutine_table->iterator());
			while(it->next()){
				Coroutine* cr =static_cast< Coroutine* >(it->getValue());
				if(cr->isWaitingAndExpire(now)){
					if(!ls){
						ls =SafeNew<Int64Array>();
					}
					ls->push_back(cr->getId());
				}
			}
			// resume
			if(ls && ls->size()>0){
				const int64_t n =ls->size();
				for(int64_t i=0; i<n; ++i){
					resume(ls->get(i), SafeNew<Error>(ErrorCode::TIMEOUT), 0);
				}
			}
		}
	}
Exemple #21
0
	Iterator* Hash::iterator(){
		HashIterator* it =SafeNew<HashIterator>();
		it->bind(this);
		return it;
	}
Exemple #22
0
	Object* HashIterator::clone(){
		HashIterator* it =SafeNew<HashIterator>();
		it->bind(m_hash);
		return it;
	}
Exemple #23
0
	bool Url::_build(String* protocol, String* auth, String* host, String* path, String* query_string, Hash* query, String* fragment){
		// clean
		clean();

		// check
		if(path && path->size() && !path->hasPrefix("/")){
			return false;
		}

		// make url
		BinaryCoder<1024> coder;

		if(protocol && protocol->size()){
			ASSIGN_POINTER(m_protocol, protocol);
			coder.append(protocol);
			coder.append("://", 3);
		}
		if(auth && auth->size()){
			ASSIGN_POINTER(m_auth, auth);
			coder.append(auth);
			coder.append("@", 1);
		}
		if(host && host->size()){
			ASSIGN_POINTER(m_host, host);
			coder.append(host);
		}
		if(path && path->size()){
			ASSIGN_POINTER(m_path, path);
			coder.append(path);
		}
		if(query_string && query_string->size()){
			ASSIGN_POINTER(m_query_string, query_string);
			ASSIGN_POINTER(m_query, SafeNew<Hash>());
			if(!ParseQuery(m_query_string, m_query)){
				clean();
				return false;
			}
			coder.append("?", 1);
			coder.append(m_query_string);
		}
		else if(query && query->size()){
			ASSIGN_POINTER(m_query, query);
			// make query string
			BinaryCoder<1024> sub_coder;
			HashIterator* it =static_cast< HashIterator* >(query->iterator());
			while(it->next()){
				String* key =static_cast< String* >(it->getKey());
				String* val =static_cast< String* >(it->getValue());
				if(sub_coder.size() > 0){
					sub_coder.append("&", 1);
				}
				sub_coder.append(UrlEncode::Encode(key));
				sub_coder.append("=", 1);
				sub_coder.append(UrlEncode::Encode(val));
			}
			// set
			ASSERT(sub_coder.size());
			ASSIGN_POINTER(m_query_string, String::New(sub_coder.c_str(), sub_coder.size()));
			coder.append("?", 1);
			coder.append(m_query_string);
		}
		if(fragment && fragment->size()){
			ASSIGN_POINTER(m_fragment, fragment);
			coder.append("#", 1);
			coder.append(fragment);
		}
		ASSIGN_POINTER(m_url, String::New(coder.c_str(), coder.size()));
		return true;
	}
Exemple #24
0
	bool HttpRespond::flush(){
		// check
		if(m_requestor == 0){
			WARN("http flush failed, requestor is null");
			return false;
		}

		//// build data
		BinaryCoder<4096> coder;

		/// head line
		// version
		if(m_version){
			coder.append(m_version);
		}
		else{
			coder.append("HTTP/1.1");
		}
		coder.append(" ");
		// code
		coder.append(String::Format("%lld", (long long)m_code));
		coder.append(" ");
		// msg
		coder.append(_code_to_msg(m_code));
		coder.append("\r\n");

		/// header
	  	if(!m_header_tb->has("Content-Type")){
			coder.append("Content-Type: text/html\r\n");
		}
	  	if(!m_header_tb->has("Content-Length")){
			coder.append(String::Format("Content-Length: %lld\r\n", (long long)m_content->size()));
		}
		HashIterator* it =static_cast< HashIterator* >(m_header_tb->iterator());
		while(it->next()){
			if(String* name =dynamic_cast< String* >(it->getKey())){
				if(String* value =dynamic_cast< String* >(it->getValue())){
					coder.append(name);
					coder.append(": ");
					coder.append(value);
					coder.append("\r\n");
				}
			}
		}
		it =static_cast< HashIterator* >(m_cookie_tb->iterator());
		while(it->next()){
			if(dynamic_cast< String* >(it->getKey())){
				if(HttpCookie* cookie =dynamic_cast< HttpCookie* >(it->getValue())){
					if(String* str =cookie->build(false)){
						coder.append(str);
						coder.append("\r\n");
					}
				}
			}
		}
		coder.append("\r\n");

		/// content
		if(m_content->size() > 0){
			coder.append(m_content->c_str(), m_content->size());
		}

		//// send
		const bool ok =m_requestor->send(coder.c_str(), coder.size());

		//// clear
		CLEAN_POINTER(m_version);
		m_code =200;
		CLEAN_POINTER(m_msg);
		m_header_tb->clear();
		m_cookie_tb->clear();
		m_content->clear();

		//// post process
		if(!ok){
			close();
		}
		m_auto_flush =false;
		return ok;
	}
Exemple #25
0
    int Ardb::HScan(Context& ctx, RedisCommandFrame& cmd)
    {
        std::string pattern;
        uint32 limit = 10000; //return max 10000 keys one time
        if (cmd.GetArguments().size() > 2)
        {
            for (uint32 i = 2; i < cmd.GetArguments().size(); i++)
            {
                if (!strcasecmp(cmd.GetArguments()[i].c_str(), "count"))
                {
                    if (i + 1 >= cmd.GetArguments().size() || !string_touint32(cmd.GetArguments()[i + 1], limit))
                    {
                        fill_error_reply(ctx.reply, "value is not an integer or out of range");
                        return 0;
                    }
                    i++;
                }
                else if (!strcasecmp(cmd.GetArguments()[i].c_str(), "match"))
                {
                    if (i + 1 >= cmd.GetArguments().size())
                    {
                        fill_error_reply(ctx.reply, "'MATCH' need one args followed");
                        return 0;
                    }
                    pattern = cmd.GetArguments()[i + 1];
                    i++;
                }
                else
                {
                    fill_error_reply(ctx.reply, "Syntax error, try scan 0 ");
                    return 0;
                }
            }
        }
        ValueObject meta;
        int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
        CHECK_ARDB_RETURN_VALUE(ctx.reply, err);

        RedisReply& r1 = ctx.reply.AddMember();
        RedisReply& r2 = ctx.reply.AddMember();
        r2.type = REDIS_REPLY_ARRAY;
        if (0 != err)
        {
            fill_str_reply(r1, "0");
            return 0;
        }
        const std::string& cursor = cmd.GetArguments()[1];
        HashIterator iter;
        HashIter(ctx, meta, cursor == "0" ? "" : cursor, iter, true);
        while (iter.Valid())
        {
            const Data* field = iter.Field();
            std::string tmp;
            field->GetDecodeString(tmp);
            if ((pattern.empty() || fnmatch(pattern.c_str(), tmp.c_str(), 0) == 0))
            {
                RedisReply& rr1 = r2.AddMember();
                RedisReply& rr2 = r2.AddMember();
                fill_str_reply(rr1, tmp);
                fill_value_reply(rr2, *(iter.Value()));
            }
            if (r2.MemberSize() >= (limit * 2))
            {
                break;
            }
            iter.Next();
        }
        if (iter.Valid())
        {
            iter.Next();
            const Data* next_field = iter.Field();
            std::string tmp;
            fill_str_reply(r1, next_field->GetDecodeString(tmp));
        }
        else
        {
            fill_str_reply(r1, "0");
        }
        return 0;
    }