int CamelSuperStrategy::fetchServer(slb_request_t * req) {
		CHECK_POOL("BEFORE doFilter ",_rp);
		if (req == NULL || copyCall == NULL) {
			return -1;
		}
		if (_isDebug) {
			_chain_filter->debug(req->serverNum);
		}
		const int serverNum = req->serverNum;
		server_rank_t serverRank[serverNum];
		memset(serverRank, 0, sizeof (serverRank));		  /**< disable=false  */
		request_t request;
		memset(&request, 0, sizeof (request));
		request.serverRanks        = serverRank;
		request.mustSelectOneServer= true;
		request.needHealthyFilter  = true;

		// get from req
		request.key = req->key;
		request.nthRetry = req->nthRetry;
		snprintf(request.currentMachineRoom, sizeof(request.currentMachineRoom), "%s", req->currentMachineRoom);
		request.serverNum = serverNum;

		if (serverNum > static_cast<int>(MAX_SERVER_SIZE)) {
			UB_LOG_WARNING("too many server while fetchServer, get %d, suppert %d", serverNum, MAX_SERVER_SIZE);
			return -1;
		}
		for (int i = 0; i < serverNum; i++) {
			copyCall(req->svr[i], request.server + i);
		}
		int ret = _chain_filter->doFilter(&request);		  /**< 返回找到的serverID  */
		server_rank_t* serv = NULL;

		for (int i = 0; ret >= 0 && i < serverNum; i++)		  /**< 找到该serverID 的server_rank_t  */
		{
			server_rank_t& sr = serverRank[i];
			if (sr.serverId == (uint)ret)
			{
				serv = &sr;
				break;
			}
		}

		if (serv == NULL){
			ret = -1;
			UB_LOG_WARNING("SuperStrategy<fetchServer: failed ret[%d]", ret);
		}
		/*else{
			UB_LOG_DEBUG("SuperStrategy<fetchServer: server_id[%u] machine_room[%s] cross_room[%d] balance[%lu] \
					connect[%g] healthy_score[%g] healthy_select[%g] disabled[%d] use_backup[%d] backup_server[%u] \
					retry[%d]  key[%d]",
					serv->serverId, serv->machineRoom, serv->crossRoom, serv->balanceRank, serv->connectScore,
					serv->healthyScore, serv->healthySelectRate, serv->disabled, serv->useBackup, 
					serv->backupServerId, request.nthRetry, request.key);
		}*/


		CHECK_POOL("AFTER doFilter ",_rp);
		return ret;
	}
	int CamelSuperStrategy::setServerArg(void *xxServer, const slb_talk_returninfo_t *talk) {
		CHECK_POOL("BEFORE updateRequest",_rp);
		if (xxServer == NULL || talk == NULL || copyCall == NULL) {
			return -1;
		}

		slb_server_t server;
		copyCall(xxServer, &server);
		int ret = _chain_filter->updateRequestStatus(&server, talk);
		CHECK_POOL("AFTER updateRequest",_rp);
		return ret;
	}
	int CamelSuperStrategy::setServerArgAfterConn(void *xxServer, int errNo) {
		CHECK_POOL("BEFORE updateConnect",_rp);
		if (xxServer == NULL || copyCall == NULL) {
			return -1;
		}

		slb_server_t server;
		copyCall(xxServer, &server);		  /**< 将外部Server拷贝到server中  */
		int ret = _chain_filter->updateConnectStatus(&server, errNo);
		CHECK_POOL("AFTER updateConnect",_rp);
		return ret;
	}
void ResponseHeaderOverrides::setContentEncoding(const char* encoding)
{
	if (encoding == NULL || *encoding == 0)
		return;

	CHECK_POOL();
	content_encoding_ = pool_->dbuf_strdup(encoding);
}
void ResponseHeaderOverrides::setContentDisposition(const char* disposition)
{
	if (disposition == NULL || *disposition == 0)
		return;

	CHECK_POOL();
	content_disposition_ = pool_->dbuf_strdup(disposition);
}
void ResponseHeaderOverrides::setCacheControl(const char* control)
{
	if (control == NULL || *control == 0)
		return;

	CHECK_POOL();
	cache_control_ = pool_->dbuf_strdup(control);
}
void ResponseHeaderOverrides::setExpires(const char* expires)
{
	if (expires == NULL || *expires == 0)
		return;

	CHECK_POOL();
	expires_ = pool_->dbuf_strdup(expires);
}
void ResponseHeaderOverrides::setContentLangauge(const char* language)
{
	if (language == NULL || *language == 0)
		return;

	CHECK_POOL();
	content_language_ = pool_->dbuf_strdup(language);
}
void ResponseHeaderOverrides::setContentType(const char* type)
{
	if (type == NULL || *type == 0)
		return;

	CHECK_POOL();
	content_type_ = pool_->dbuf_strdup(type);
}
OPP_INLINE static SYNC_UWORD8_T*opp_alloc4_recycle(const SYNC_UWORD8_T slot_count, struct opp_pool*pool) {
	if(slot_count == 1) {
		/* traverse the pool link-list */
		for(;pool; pool = pool->next) {
			CHECK_POOL(pool);
			if(pool->recycled) {
				SYNC_ASSERT(!pool->recycled->refcount);
				const SYNC_UWORD8_T*ret = (SYNC_UWORD8_T*)pool->recycled;
				pool->recycled = pool->recycled->recycled;
				return ret;
			}
		}
	}
	return NULL;
}
OPP_INLINE static void opp_alloc4_init_object(struct opp_factory*obuff, const struct opp_pool*pool, SYNC_UWORD8_T*given, const SYNC_UWORD8_T obj_idx) {
	struct opp_object*obj = (struct opp_object*)given;
	struct opp_object_ext*ext = (struct opp_object_ext*)(obj+1);
#ifdef OPP_HAS_TOKEN
	if(obuff->property & OPPF_EXTENDED) {
		ext->token = obuff->token_offset + pool->idx*obuff->pool_size + obj_idx;
	}
#endif
	obj->obuff = obuff;
#ifdef FACTORY_OBJ_SIGN
	obj->signature = FACTORY_OBJ_SIGN;
#endif
	if(obuff->property & OPPF_EXTENDED) {
		ext->flag = OPPN_ALL;
		ext->hash = 0;
	}
	CHECK_POOL(pool);
}
C_CAPSULE_START

OPP_INLINE struct opp_pool*opp_factory_create_pool_donot_use(struct opp_factory*obuff, struct opp_pool*addpoint, void*nofreememory) {
	// allocate a block of memory
	struct opp_pool*pool = (struct opp_pool*)nofreememory;
	opp_factory_profiler_checkleak();
	if(!pool && !(pool = (struct opp_pool*)profiler_replace_malloc(obuff->memory_chunk_size))) {
		SYNC_LOG(SYNC_ERROR, "Out of memory\n");
		return NULL;
	}

	if(!obuff->pools) {
		obuff->pools = pool;
		pool->idx = 0;
		pool->next = NULL;
	} else {
		SYNC_ASSERT(addpoint);
		// insert the pool in appropriate place
		pool->next = addpoint->next;
		addpoint->next = pool;
		pool->idx = addpoint->idx+1;
	}
	if(pool->idx > 64) {
		opp_watchdog_report(WATCHDOG_ALERT, "pool->idx > 64");
	}

	obuff->pool_count++;
	opp_factory_profiler_checkleak();

	SYNC_UWORD8_T*ret = (SYNC_UWORD8_T*)(pool+1);
	/* clear bitstring */
	memset(ret, 0, obuff->bitstring_size);
	// setup pool
	pool->bitstring = (BITSTRING_TYPE*)ret;
#ifdef OPP_HAS_RECYCLING
	pool->recycled = NULL;
#endif
	pool->head = ret + (obuff->bitstring_size);
	pool->end = ret + obuff->memory_chunk_size - sizeof(struct opp_pool);
	pool->flags = nofreememory?0:OPP_POOL_FREEABLE;
	CHECK_POOL(pool);
	return pool;
}
/**
 * @brief allocates memory in object pool
 */
void*opp_alloc4(struct opp_factory*obuff, SYNC_UWORD16_T size, SYNC_UWORD8_T doubleref, SYNC_UWORD8_T require_clean, void*init_data, ...) {
	SYNC_UWORD8_T*ret = NULL;
	SYNC_UWORD8_T slot_count = 1;
	SYNC_UWORD8_T require_init = 1;
	if(!require_clean)
		require_clean = obuff->property & OPPF_MEMORY_CLEAN;
	
	SYNC_ASSERT(obuff->sign == OPPF_INITIALIZED_INTERNAL);

	OPP_LOCK(obuff);
	do {
		/* get the number of slots we need */
		if(!(slot_count = opp_alloc4_count_slots(size, obuff->obj_size, obuff->pool_size))) {
			break;
		}
#ifdef OPP_HAS_RECYCLING
		if((ret = opp_alloc4_recycle(slot_count, obuff->pools))) {
			break;
		}
#endif
		/* find the space in some empty pool */
		struct opp_pool*pool = NULL,*addpoint = NULL;
		for(addpoint = NULL, pool = obuff->pools;pool;pool = pool->next) {
			if(!addpoint && (!pool->next || (pool->idx+1 != pool->next->idx))) {
				addpoint = pool;
			}
			CHECK_POOL(pool);
			/* find some space in the pool */
			SYNC_UWORD16_T obj_idx = 0;
			if((ret = opp_alloc4_find_space(pool, obuff->pool_size, slot_count, obuff->obj_size, &obj_idx))) {
				/* initialize the object */
				opp_alloc4_init_object(obuff, pool, ret, obj_idx);
				break;
			}
		}

		if(ret) {
#ifdef OPP_HAS_RECYCLING
			pool->recycled = NULL;
#endif
			break;
		}

		/* try to allocate new space */
		pool = opp_factory_create_pool_donot_use(obuff, addpoint, NULL);
		if(!pool) {
			ret = NULL;
			break;
		}
		ret = pool->head;
		opp_alloc4_init_object_bit_index((struct opp_object*)ret, 0, pool->bitstring, slot_count);
		opp_alloc4_init_object(obuff, pool, ret, 0);
	}while(0);

	va_list ap;
	va_start(ap, init_data);

	if(ret) {
		struct opp_object*obj = (struct opp_object*)ret;
		opp_alloc4_object_setup(obj, doubleref);
		ret = (SYNC_UWORD8_T*)(obj+1);
	}

	if(ret && !(obuff->property & OPPF_FAST_INITIALIZE) && obuff->callback) {
		ret = opp_alloc4_build(obuff, ret, doubleref, &require_clean, &require_init, init_data, slot_count, ap);
	}
#ifdef OPP_DEBUG
	if(obuff->pools && obuff->pools->bitstring) {
		BITSTRING_TYPE*bitstring;
		for(bitstring = obuff->pools->bitstring;((void*)bitstring) < ((void*)obuff->pools->head);bitstring+=BITFIELD_SIZE) {
			SYNC_ASSERT(!(*(bitstring) & *(bitstring+BITFIELD_PAIRED)));
		}
	}
#endif

	DO_AUTO_GC_CHECK(obuff);
	OPP_UNLOCK(obuff);
	if(ret) {
		ret = opp_alloc4_build(obuff, ret, doubleref, &require_clean, &require_init, init_data, slot_count, ap);
	}
	va_end(ap);
//	SYNC_ASSERT(ret);
	return ret;
}