示例#1
0
int main(int argc, char** argv) {
    ConfigurationBuilder nearCacheBuilder;
    nearCacheBuilder.protocolVersion(argc > 1 ? argv[1] : Configuration::PROTOCOL_VERSION_24);
    nearCacheBuilder.addServer().host(argc > 2 ? argv[2] : "127.0.0.1").port(argc > 3 ? atoi(argv[3]) : 11222);
    nearCacheBuilder.balancingStrategyProducer(nullptr);
    nearCacheBuilder.nearCache().mode(NearCacheMode::INVALIDATED).maxEntries(10);
    RemoteCacheManager nearCacheManager(nearCacheBuilder.build(), false);
    JBasicMarshaller<std::string> *km = new JBasicMarshaller<std::string>();
    JBasicMarshaller<std::string> *vm = new JBasicMarshaller<std::string>();
    try
    {
    nearCacheManager.start();
    RemoteCache<std::string, std::string> nearCache = nearCacheManager.getCache<std::string, std::string>(km,
            &Marshaller<std::string>::destroy,
            vm,
            &Marshaller<std::string>::destroy);
    nearCache.clear();
    // Read stats to do some checks on hits and miss counter
    std::map<std::string,std::string> statsBegin= nearCache.stats();
    auto hitsBegin = std::stoi(statsBegin["hits"]);
    auto missesBegin = std::stoi(statsBegin["misses"]);
    // Only the first get goes to the remote cache and miss the value
    // then all the gets are resolved nearly
    nearCache.get("key1");
    nearCache.put("key1", "value1");
    std::string *rest = nearCache.get("key1");
    std::cout << "Got result from near cache:" << ((rest) ? *rest : "null") << std::endl;
    delete rest;
    rest = nearCache.get("key1");
    delete rest;
    std::map<std::string,std::string> stats1= nearCache.stats();
    auto hits1 = std::stoi(stats1["hits"]);
    auto misses1 = std::stoi(stats1["misses"]);
    std::cout << "Remote misses is: " << misses1-missesBegin << "" << std::endl;
    std::cout << "Remote hits is: " << hits1-hitsBegin << "" << std::endl;
    for(int i=2; i <= 11; i++)
    {   // fill cache with 10 more entries (11 in total)
        nearCache.put("key"+std::to_string(i),std::to_string(i));
    }
    // now key1 one should not be near
    rest = nearCache.get("key1");  // remote get. Stored near (this delete key2 nearly)
    delete rest;
    rest = nearCache.get("key2");  // remote get. Stored near (this delete key3 nearly)
    delete rest;
    rest = nearCache.get("key1");  // near
    delete rest;
    std::map<std::string,std::string> statsEnd= nearCache.stats();
    auto hitsEnd = std::stoi(statsEnd["hits"]);
    auto missesEnd = std::stoi(statsEnd["misses"]);
    std::cout << "Remote misses is: " << missesEnd-missesBegin << "" << std::endl;
    std::cout << "Remote hits is: " << hitsEnd-hitsBegin << "" << std::endl;
    }
    catch (Exception &e) {
    }
    try
    {
        nearCacheManager.stop();
    }
    catch (Exception &e) {
    }
}
示例#2
0
int basicTest(RemoteCacheManager &cacheManager, RemoteCache<K,V> &cache) {

    std::cout << "HotRod C++ Library version " << cache.getVersion() << std::endl;
    std::cout << "Protocol " << cache.getProtocolVersion() << std::endl;

    std::string k1("key13");
    std::string k2("key14");
    std::string v1("boron");
    std::string v2("chlorine");

    cache.clear();

    // put
    cache.put(k1, v1);
    std::unique_ptr<std::string> rv(cache.get(k1));
    assert_not_null("get returned null!", __LINE__, rv);
    if (rv->compare(v1)) {
        std::cerr << "get/put fail for " << k1 << " got " << *rv << " expected " << v1 << std::endl;
        return 1;
    }

    cache.put(k2, v2);
    std::unique_ptr<std::string> rv2(cache.get(k2));
    assert_not_null("get returned null!", __LINE__, rv2);
    if (rv2->compare(v2)) {
        std::cerr << "get/put fail for " << k2 << " got " << *rv2 << " expected " << v2 << std::endl;
        return 1;
    }
 
    std::unique_ptr<std::string> badValue(cache.get(std::string("no such key in the cache")));
    if (badValue.get()) {
        std::cout << "non-existent key failure, got " << *badValue << std::endl;
        return 1;
    }

    std::cout << "PASS: simple get/put" << std::endl;

    {
      std::string k3("rolling");
      std::string v3("stones");
      std::string v4("beatles");

      // putIfAbsent
      cache.putIfAbsent(k3, v3);
      std::unique_ptr<std::string> rv3(cache.get(k3));
      assert_not_null("get returned null!", __LINE__, rv3);
      if (rv3->compare(v3)) {
          std::cerr << "putIfAbsent fail for " << k3 << " got " << *rv3 << " expected " << v3 << std::endl;
          return 1;
      }

      cache.putIfAbsent(k3, v4);
      std::unique_ptr<std::string> rv4(cache.get(k3));
      assert_not_null("get returned null!", __LINE__, rv4);
      if (rv4->compare(v3)) {
          std::cerr << "putIfAbsent fail for " << k3 << " got " << *rv4 << " expected " << v3 << std::endl;
          return 1;
      }

      std::cout << "PASS: simple putIfAbsent"  << std::endl;
    }
    {
      std::string k3("rolling");
      std::string v3("stones");
      std::string v4("beatles");

      // putIfAbsent
      cache.putIfAbsent(k3, v3);
      std::unique_ptr<std::string> rv3(cache.get(k3));
      assert_not_null("get returned null!", __LINE__, rv3);
      if (rv3->compare(v3)) {
          std::cerr << "putIfAbsent fail for " << k3 << " got " << *rv3 << " expected " << v3 << std::endl;
          return 1;
      }

      std::unique_ptr<std::string> rv4(cache.withFlags(FORCE_RETURN_VALUE).putIfAbsent(k3, v4));
      assert_not_null("get returned null!", __LINE__, rv4);
      if (rv4->compare(v3)) {
          std::cerr << "putIfAbsent fail for " << k3 << " got " << *rv4 << " expected " << v3 << std::endl;
          return 1;
      }

      std::cout << "PASS: simple putIfAbsent with force return value"  << std::endl;
    }

    std::string k3("rolling");
    std::string v3("stones");
    std::string v4("beatles");

    cache.put(k3, v3, 10, SECONDS);
    // getWithMetadata
    std::pair<std::shared_ptr<std::string>, MetadataValue> rv5 = cache.getWithMetadata(k3);
    if (!rv5.first.get() || rv5.second.lifespan != 10) {
        std::cerr << "getWithMetadata with mortal entry fail for " << k3 << " not found" << std::endl;
        return 1;
    }
    std::cout << "PASS: simple getWithMetadata with mortal entry"  << std::endl;

    cache.put(k3, v3);
    // getWithMetadata
    rv5 = cache.getWithMetadata(k3);
    if (!rv5.first.get()
        || rv5.second.lifespan >= 0 || rv5.second.created >= 0
        || rv5.second.maxIdle >= 0 || rv5.second.lastUsed >= 0) {
        std::cerr << "getWithMetadata with immortal entry fail for " << k3 << std::endl;
        return 1;
    }
    std::cout << "PASS: simple getWithMetadata with immortal entry"  << std::endl;

    // getWithVersion
    std::pair<std::shared_ptr<std::string>, VersionedValue> rv5a = cache.getWithVersion(k3);
    if (!rv5a.first.get()) {
        std::cerr << "getWithVersion fail for " << k3 << " not found" << std::endl;
        return 1;
    }

    std::cout << "PASS: simple getWithVersion"  << std::endl;

    // replaceWithVersion
    cache.replaceWithVersion(k3, v4, rv5.second.version);
    std::unique_ptr<std::string> rv6(cache.get(k3));
    assert_not_null("get returned null!", __LINE__, rv6);
    if (rv6->compare(v4)) {
        std::cerr << "replaceWithVersion fail for " << k3 << " got " << *rv6 << " expected " << v4 << std::endl;
        return 1;
    }

    cache.replaceWithVersion(k3, v3, rv5.second.version);
    std::unique_ptr<std::string> rv7(cache.get(k3));
    assert_not_null("get returned null!", __LINE__, rv7);
    if (rv7->compare(v4)) {
        std::cerr << "replaceWithVersion fail for " << k3 << " got " << *rv7 << " expected " << v4 << std::endl;
        return 1;
    }

    std::cout << "PASS: simple replaceWithVersion" << std::endl;

    // size
    uint64_t size = cache.size();
    if (size != 3) {
        std::cerr << "size fail got " << size << " expected 3 " << std::endl;
        return 1;
    }

    std::cout << "PASS: simple size" << std::endl;

    // stats
    const std::map<std::string,std::string>& stats = cache.stats();
    if (stats.empty()) {
        std::cerr << "stats fail with empty map" << std::endl;
        return 1;
    }

    std::cout << "  stats result is:" << std::endl;
    for(std::map<std::string,std::string>::const_iterator i=stats.begin(); i!=stats.end(); i++) {
        std::cout << "    key: " << i->first << ", value: " << i->second << std::endl;
    }

    std::cout << "PASS: simple stats" << std::endl;

    // clear
    cache.clear();
    uint64_t size2 = cache.size();
    if (size2 != 0) {
        std::cerr << "clear fail cache has size " << size2 << " expected 0 " << std::endl;
        return 1;
    }

    std::cout << "PASS: simple clear" << std::endl;

    std::string k4("real");
    std::string v5("madrid");
    std::string v6("barcelona");

    // put with FORCE_RETURN_VALUE flag
    std::unique_ptr<std::string> rv8(cache.withFlags(FORCE_RETURN_VALUE).put(k4,v5));
    if (rv8.get()) {
        std::cerr << "put with FORCE_RETURN_FLAG fail for " << k4 << " got " << *rv8 << " expected null pointer" << std::endl;
        return 1;
    }

    std::unique_ptr<std::string> rv9(cache.withFlags(FORCE_RETURN_VALUE).put(k4,v6));
    assert_not_null("get returned null!", __LINE__, rv9);
    if (rv9->compare(v5)) {
        std::cerr << "put with FORCE_RETURN_FLAG fail for " << k4 << " got " << *rv9 << " expected " << v5 << std::endl;
        return 1;
    }

    std::cout << "PASS: simple put with FORCE_RETURN_FLAG" << std::endl;

    // keySet
    std::set<std::shared_ptr<std::string> > keySet = cache.keySet();
    if (keySet.size()!=1) {
        std::cerr << "keySet fail got " << keySet.size() << " entries expected 1" << std::endl;
        return 1;
    }

    std::cout << "  keySet result is:" << std::endl;
    for(std::set<std::shared_ptr<std::string> >::const_iterator i=keySet.begin(); i!=keySet.end(); i++) {
        std::cout << "    key: " << *i->get() << std::endl;
    }

    std::cout << "PASS: simple keySet" << std::endl;

    // getBulk
    std::map<std::shared_ptr<std::string>,std::shared_ptr<std::string> > map = cache.getBulk();
    if (map.size()!=1) {
        std::cerr << "getBulk fail got" << map.size() << " entries expected 1" << std::endl;
        return 1;
    }

    std::cout << "  getBulk result is:" << std::endl;
    for(std::map<std::shared_ptr<std::string>,std::shared_ptr<std::string> >::const_iterator i=map.begin(); i!=map.end(); i++) {
        std::cout << "    key: " << *i->first.get() << ", value: " << *i->second.get() << std::endl;
    }

    std::cout << "PASS: simple getBulk" << std::endl;

    // replace
    cache.replace(k4,v5);
    std::unique_ptr<std::string> rv10(cache.get(k4));
    assert_not_null("get returned null!", __LINE__, rv10);
    if (rv10->compare(v5)) {
        std::cerr << "replace fail for " << k4 << " got " << *rv10 << " expected " << v5 << std::endl;
        return 1;
    }

    std::cout << "PASS: simple replace" << std::endl;
    try {
        RemoteCache<std::string, std::string> namedCache =
                cacheManager.getCache<std::string, std::string>("namedCache", false);
        std::unique_ptr<std::string> namedCacheV1(namedCache.get("k1"));
    }
    catch (...)
    {
        return 1;
    }
    std::cout << "PASS: get for namedCache" << std::endl;

    // get non-existing cache
        try {
            RemoteCache<std::string, std::string> non_existing =
                    cacheManager.getCache<std::string, std::string>("non-existing", false);
            std::cerr << "fail getCache for non-existing cache didn't throw exception" << std::endl;
            return 1;
        } catch (const HotRodClientException &ex) {
            std::cout << "PASS: get non-existing cache" << std::endl;
        } catch (const Exception &e) {
            std::cout << "is: " << typeid(e).name() << '\n';
            std::cerr << "fail unexpected exception: " << e.what() << std::endl;
            return 1;
        }

    // Async test
    std::string ak1("asyncK1");
    std::string av1("sun");

    std::string ak2("asyncK2");
    std::string av2("mercury");

    cache.clear();

/*    // Put ak1,av1 in async thread A
    std::future<std::string*> future_put= cache.putAsync(ak1,av1);
    // Get the value in this thread
    std::string* arv1= cache.get(ak1);
    if (future_put.wait_for(std::chrono::seconds(0))!=std::future_status::ready)
    {
    	// get happens before put completes, arv1 must be null
    	if (arv1)
    	{
    		std::cerr << "fail: expected null got value" << std::endl;
    		return 1;
    	}
    }
    // Now wait for put completion
    future_put.wait();

    // All is synch now
    std::string* arv11= cache.get(ak1);
    if (!arv11 || arv11->compare(av1))
    {
    	std::cout << "fail: expected " << av1 << "got " << (arv11 ? *arv11 : "null") << std::endl;
    	return 1;
    }

    // Read ak1 again, but in async way and test that the result is the same
    std::future<std::string*> future_ga= cache.getAsync(ak1);
    std::string* arv2= future_ga.get();
    if (!arv2 || arv2->compare(av1))
    {
    	std::cerr << "fail: expected " << av1 << " got " << (arv2 ? *arv2 : "null") << std::endl;
    	return 1;
    }
*/
    bool flag=false;
    // Now user pass a lambda func that will be executed in the async thread after the put completion
    std::future<std::string*> future_put1= cache.putAsync(ak2,av2,0,0,[&] (std::string *v){flag=true; return v;});
    {
    	// If the async put is not completed flag must be false
    	if (future_put1.wait_for(std::chrono::seconds(0))!=std::future_status::ready)
    	{
    		if (flag)
    		{
    			std::cerr << "fail: expected false got true" << std::endl;
    			return 1;
    		}
    	}
    }
    // Now wait for put completion
    future_put1.wait();
    {
    	// The user lambda must be executed so flag must be true
    	if (!flag)
    	{
    		std::cerr << "fail: expected true got false" << std::endl;
    		return 1;
    	}
    }
    // Same test for get
    flag=false;
    std::future<std::string*> future_get1= cache.getAsync(ak2,[&] (std::string *v){flag=true; return v;});

    if (future_get1.wait_for(std::chrono::seconds(0))!=std::future_status::ready)
    {
    	if (flag)
    	{
    		std::cerr << "fail: expected false got true" << std::endl;
    		return 1;
    	}
    }
    future_get1.wait();
    {
    	if (!flag)
    	{
    		std::cerr << "fail: expected true got false" << std::endl;
    		return 1;
    	}
    }
    std::string* arv3= future_get1.get();

    if (!arv3 || arv3->compare(av2))
    {
    	std::cerr << "fail: expected " << av2 << " got " << (arv3 ? *arv3 : "null") << std::endl;
    	return 1;
    }
    std::cout << "PASS: Async test" << std::endl;
    return 0;
}