blob: 7e31f4997d7affffa11f4d5b5983c2016b7ee28d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define ROOT_NAME "testEntriesMap"
#include "fw_helper.hpp"
#ifdef WIN32
BEGIN_TEST(NotOnWindows)
{ LOG("Too many non-external symbols used too fix right now on windows."); }
END_TEST(NotOnWindows)
#else
//#define BUILD_CPPCACHE 1
#include <gfcpp/GeodeCppCache.hpp>
#include <LRUEntriesMap.hpp>
#include <LRUMapEntry.hpp>
#include <VersionTag.hpp>
#include <stdlib.h>
using namespace apache::geode::client;
using namespace std;
typedef std::vector<MapEntryImplPtr> VectorOfMapEntry;
CacheableStringPtr createCacheable(const char* value) {
CacheableStringPtr result = CacheableString::create(value);
ASSERT(result != NULLPTR, "expected result non-NULL");
return result;
}
BEGIN_TEST(PutAndGet)
{
CacheableStringPtr ccstr = createCacheable("100");
CacheablePtr ct = ccstr;
EntryFactory* entryFactory = EntryFactory::singleton;
EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
entries->open();
CacheableKeyPtr keyPtr = CacheableKey::create((char*)"foobar");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
MapEntryImplPtr me;
VersionTagPtr versionTag;
CacheablePtr oldValue;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
CacheablePtr myValuePtr;
entries->get(keyPtr, myValuePtr, me);
ASSERT(myValuePtr != NULLPTR, "expected non-NULL");
CacheableStringPtr strValue = dynCast<CacheableStringPtr>(myValuePtr);
ASSERT(ccstr->operator==(*strValue), "expected 100");
delete entries;
}
END_TEST(PutAndGet)
BEGIN_TEST(CheckMapEntryImplPtr)
{
char error[1000] ATTR_UNUSED;
MapEntryImplPtr mePtr;
ASSERT(mePtr == NULLPTR, "expected mePtr to be NULL");
CacheableKeyPtr keyPtr = CacheableKey::create(fwtest_Name);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
EntryFactory::singleton->newMapEntry(keyPtr, mePtr);
ASSERT(mePtr != NULLPTR, "expected to not be null.");
}
END_TEST(CheckMapEntryImplPtr)
BEGIN_TEST(RemoveTest)
{
CacheableStringPtr cst = createCacheable("200");
CacheablePtr ct = cst;
EntryFactory* entryFactory = EntryFactory::singleton;
EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
entries->open();
CacheableKeyPtr keyPtr = CacheableKey::create(fwtest_Name);
MapEntryImplPtr me;
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr oldValue;
VersionTagPtr versionTag;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
CacheablePtr myValuePtr;
(void)entries->remove(keyPtr, myValuePtr, me, -1, versionTag, false);
CacheableStringPtr resPtr = dynCast<CacheableStringPtr>(myValuePtr);
ASSERT(myValuePtr != NULLPTR, "expected to not be null.");
ASSERT(resPtr->operator==(*createCacheable("200")),
"CustomerType with m_foobar 200.");
(void)entries->remove(keyPtr, myValuePtr, me, -1, versionTag, false);
ASSERT(myValuePtr == NULLPTR,
"expected already removed, and null result should clear ptr.");
}
END_TEST(RemoveTest)
BEGIN_TEST(GetEntryTest)
{
CacheableStringPtr cst = createCacheable("200");
CacheablePtr ct = cst;
EntryFactory* entryFactory = EntryFactory::singleton;
EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
entries->open();
CacheableKeyPtr keyPtr;
MapEntryImplPtr me;
keyPtr = CacheableKey::create(fwtest_Name);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr oldValue;
VersionTagPtr versionTag;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
MapEntryImplPtr mePtr;
CacheablePtr ctPtr;
entries->getEntry(keyPtr, mePtr, ctPtr);
ASSERT(mePtr != NULLPTR, "should not be null.");
CacheableStringPtr valPtr = dynCast<CacheableStringPtr>(ctPtr);
ASSERT(valPtr->operator==(*cst),
"Entry should have a CustomerType Value of 200");
CacheableKeyPtr keyPtr1;
mePtr->getKey(keyPtr1);
ASSERT(keyPtr1->operator==(*keyPtr), "should have same key.");
}
END_TEST(GetEntryTest)
BEGIN_TEST(MapEntryImplPtrRCTest)
{
// Test Reference Counting and destruction for MapEntry.
CacheableKeyPtr keyPtr = CacheableKey::create("foobar");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
MapEntryImplPtr mePtr;
EntryFactory ef;
ef.newMapEntry(keyPtr, mePtr);
CacheablePtr ct = createCacheable("someval");
mePtr->setValue(ct);
}
END_TEST(MapEntryImplPtrRCTest)
BEGIN_TEST(VectorOfMapEntryTestA)
{
VectorOfMapEntry* meVec = new VectorOfMapEntry();
delete meVec;
}
END_TEST(VectorOfMapEntryTestA)
BEGIN_TEST(VectorOfMapEntryTestB)
{
VectorOfMapEntry* meVec = new VectorOfMapEntry();
meVec->resize(100);
meVec->clear();
meVec->resize(10);
MapEntryImplPtr mePtr;
for (int i = 0; i < 10; i++) {
meVec->push_back(mePtr);
}
for (int j = 0; j < 10; j++) {
meVec->pop_back();
}
delete meVec;
}
END_TEST(VectorOfMapEntryTestB)
BEGIN_TEST(EntriesTest)
{
EntryFactory* entryFactory = EntryFactory::singleton;
EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
entries->open();
char keyBuf[100];
char valBuf[100];
VersionTagPtr versionTag;
MapEntryImplPtr me;
for (int i = 0; i < 10; i++) {
sprintf(keyBuf, "key_%d", i);
sprintf(valBuf, "%d", i);
CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr v = createCacheable(valBuf);
CacheablePtr oldValue;
entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
}
VectorOfRegionEntry* entriesVec = new VectorOfRegionEntry();
entriesVec->resize(1);
entries->entries(*entriesVec);
// should be 10, but they are hashed so, we don't know what order they will
// come in...
int total = 0;
int expectedTotal = 0;
for (int k = 0; k < 10; k++) {
expectedTotal += k;
RegionEntryPtr rePtr = entriesVec->back();
CacheableStringPtr ctPtr;
CacheablePtr ccPtr;
ccPtr = rePtr->getValue();
ctPtr = dynCast<CacheableStringPtr>(ccPtr);
test::cout << "value is " << ctPtr->asChar() << test::endl;
int val = atoi(ctPtr->asChar());
test::cout << "atoi returned " << val << test::endl;
total += val;
entriesVec->pop_back();
}
entriesVec->clear();
entriesVec->resize(0);
delete entriesVec;
sprintf(keyBuf, "total = %d, expected = %d", total, expectedTotal);
ASSERT(total == expectedTotal, keyBuf);
delete entries;
}
END_TEST(EntriesTest)
BEGIN_TEST(ValuesTest)
{
EntryFactory* entryFactory = EntryFactory::singleton;
EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
entries->open();
char keyBuf[100];
char valBuf[100];
VersionTagPtr versionTag;
MapEntryImplPtr me;
for (int i = 0; i < 10; i++) {
sprintf(keyBuf, "key_%d", i);
sprintf(valBuf, "%d", i);
CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr v = createCacheable(valBuf);
CacheablePtr oldValue;
entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
}
VectorOfCacheable* valuesVec = new VectorOfCacheable();
valuesVec->resize(1);
entries->values(*valuesVec);
// should be 10, but they are hashed so, we don't know what order they will
// come in...
int total = 0;
int expectedTotal = 0;
for (int k = 0; k < 10; k++) {
expectedTotal += k;
CacheableStringPtr valuePtr =
dynCast<CacheableStringPtr>(valuesVec->back());
total += atoi(valuePtr->asChar());
valuesVec->pop_back();
}
delete valuesVec;
sprintf(keyBuf, "total = %d, expected = %d", total, expectedTotal);
ASSERT(total == expectedTotal, keyBuf);
delete entries;
}
END_TEST(ValuesTest)
BEGIN_TEST(KeysTest)
{
EntryFactory* entryFactory = EntryFactory::singleton;
EntriesMap* entries = new ConcurrentEntriesMap(entryFactory, false);
entries->open();
char keyBuf[100];
char valBuf[100];
VersionTagPtr versionTag;
MapEntryImplPtr me;
for (int i = 0; i < 10; i++) {
sprintf(keyBuf, "key_%d", i);
sprintf(valBuf, "%d", i);
CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr v = createCacheable(valBuf);
CacheablePtr oldValue;
entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
}
VectorOfCacheableKey keysVec;
// keysVec.resize( 1 );
entries->keys(keysVec);
// should be 10, but they are hashed so, we don't know what order they will
// come in...
int total = 0;
int expectedTotal = 0;
for (int k = 0; k < 10; k++) {
expectedTotal += k;
CacheableKeyPtr keyPtr = keysVec.back();
CacheablePtr cvPtr;
entries->get(keyPtr, cvPtr, me);
CacheableStringPtr valuePtr = dynCast<CacheableStringPtr>(cvPtr);
total += atoi(valuePtr->asChar());
keysVec.pop_back();
}
sprintf(keyBuf, "total = %d, expected = %d", total, expectedTotal);
ASSERT(total == expectedTotal, keyBuf);
delete entries;
}
END_TEST(KeysTest)
BEGIN_TEST(TestRehash)
{
EntryFactory* entryFactory = EntryFactory::singleton;
ConcurrentEntriesMap* entries =
new ConcurrentEntriesMap(entryFactory, false, NULL, 1);
entries->open(10);
ASSERT(entries->totalSegmentRehashes() == 0,
"should not have rehashed yet.");
char keyBuf[100];
char valBuf[100];
MapEntryImplPtr me;
for (uint32_t i = 0; i < 10000; i++) {
sprintf(keyBuf, "key_%d", i);
sprintf(valBuf, "%d", i);
CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr v = createCacheable(valBuf);
CacheablePtr oldValue;
VersionTagPtr versionTag;
entries->put(keyPtr, v, me, oldValue, -1, 0, versionTag);
}
// check rehash count...
ASSERT(entries->totalSegmentRehashes() > 0,
"should have rehashed several times.");
// VectorOfMapEntry result ;
// entries->entries( result );
// printf("entries->size()=%d\n", entries->size());
ASSERT(entries->size() == 10000, "should be 10k items");
for (uint32_t j = 0; j < 10000; j++) {
sprintf(keyBuf, "key_%d", j);
CacheableStringPtr valuePtr;
CacheableKeyPtr keyPtr = CacheableKey::create(keyBuf);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr cvPtr;
entries->get(keyPtr, cvPtr, me);
valuePtr = dynCast<CacheableStringPtr>(cvPtr);
if (valuePtr == NULLPTR) {
test::cout << "error finding key: " << keyBuf << test::endl;
FAIL("should have found value for all keys after rehash.");
}
}
}
END_TEST(TestRehash)
//---- LRU variants
BEGIN_TEST(LRUPutAndGet)
{
CacheableStringPtr cst = createCacheable("100");
CacheablePtr ct = cst;
MapEntryImplPtr me;
EntryFactory* entryFactory = LRUEntryFactory::singleton;
EntriesMap* entries = new LRUEntriesMap(
entryFactory, NULL, LRUAction::LOCAL_DESTROY, 20, false);
entries->open();
ASSERT(entries->size() == 0, "expected size 0.");
CacheableKeyPtr keyPtr = CacheableKey::create("foobar");
CacheablePtr oldValue;
VersionTagPtr versionTag;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 1, "expected size 1.");
CacheableStringPtr myValuePtr;
CacheablePtr cvPtr;
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
entries->get(keyPtr, cvPtr, me);
myValuePtr = dynCast<CacheableStringPtr>(cvPtr);
ASSERT(myValuePtr != NULLPTR, "expected non-NULL");
ASSERT(cst->operator==(*myValuePtr), "expected 100");
delete entries;
}
END_TEST(LRUPutAndGet)
BEGIN_TEST(CheckLRUMapEntryImplPtr)
{
char error[1000] ATTR_UNUSED;
MapEntryImplPtr mePtr;
ASSERT(mePtr == NULLPTR, "expected mePtr to be NULL");
CacheableKeyPtr keyPtr = CacheableKey::create(fwtest_Name);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
LRUEntryFactory::singleton->newMapEntry(keyPtr, mePtr);
ASSERT(mePtr != NULLPTR, "expected to not be null.");
LRUMapEntryPtr lmePtr = dynCast<LRUMapEntryPtr>(mePtr);
ASSERT(lmePtr != NULLPTR, "expected to cast successfully to LRUMapEntry.");
}
END_TEST(LRUCheckMapEntryImplPtr)
BEGIN_TEST(LRURemoveTest)
{
CacheableStringPtr cst = createCacheable("200");
CacheablePtr ct = cst;
EntryFactory* entryFactory = LRUEntryFactory::singleton;
EntriesMap* entries = new LRUEntriesMap(
entryFactory, NULL, LRUAction::LOCAL_DESTROY, 20, false);
entries->open();
ASSERT(entries->size() == 0, "expected size 0.");
CacheableKeyPtr keyPtr;
MapEntryImplPtr me;
keyPtr = CacheableKey::create(fwtest_Name);
CacheablePtr oldValue;
VersionTagPtr versionTag;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 1, "expected size 1.");
CacheableStringPtr myValuePtr;
CacheablePtr cvPtr;
(void)entries->remove(keyPtr, cvPtr, me, -1, versionTag, false);
myValuePtr = dynCast<CacheableStringPtr>(cvPtr);
ASSERT(entries->size() == 0, "expected size 0.");
ASSERT(cvPtr != NULLPTR, "expected to not be null.");
ASSERT(myValuePtr->operator==(*createCacheable("200")),
"CustomerType with m_foobar 200.");
(void)entries->remove(keyPtr, cvPtr, me, -1, versionTag, false);
ASSERT(cvPtr == NULLPTR,
"expected already removed, and null result should clear ptr.");
}
END_TEST(LRURemoveTest)
BEGIN_TEST(LRUGetEntryTest)
{
CacheableStringPtr cst = createCacheable("200");
CacheablePtr ct = cst;
EntryFactory* entryFactory = LRUEntryFactory::singleton;
EntriesMap* entries = new LRUEntriesMap(
entryFactory, NULL, LRUAction::LOCAL_DESTROY, 20, false);
entries->open();
CacheableKeyPtr keyPtr;
MapEntryImplPtr me;
keyPtr = CacheableKey::create(fwtest_Name);
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
CacheablePtr oldValue;
VersionTagPtr versionTag;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 1, "expected size 1.");
MapEntryImplPtr mePtr;
CacheablePtr cvPtr;
entries->getEntry(keyPtr, mePtr, cvPtr);
ASSERT(mePtr != NULLPTR, "should not be null.");
CacheableStringPtr ctPtr;
ctPtr = dynCast<CacheableStringPtr>(cvPtr);
ASSERT(ctPtr->operator==(*cst),
"Entry should have a CustomerType Value of 200");
CacheableKeyPtr keyPtr1;
mePtr->getKey(keyPtr1);
ASSERT(keyPtr1->operator==(*keyPtr), "should have same key.");
}
END_TEST(LRUGetEntryTest)
BEGIN_TEST(LRULimitEvictTest)
{
EntryFactory* entryFactory = LRUEntryFactory::singleton;
EntriesMap* entries = new LRUEntriesMap(entryFactory, NULL,
LRUAction::LOCAL_DESTROY, 5, false);
entries->open();
MapEntryImplPtr me;
CacheablePtr ct = createCacheable("somevalue");
CacheablePtr oldValue;
CacheableKeyPtr keyPtr = CacheableKey::create("1");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
VersionTagPtr versionTag;
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 1, "expected size 1.");
keyPtr = CacheableKey::create("2");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 2, "expected size 2.");
keyPtr = CacheableKey::create("3");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 3, "expected size 3.");
keyPtr = CacheableKey::create("4");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 4, "expected size 4.");
keyPtr = CacheableKey::create("5");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
ASSERT(entries->size() == 5, "expected size 5.");
LOG("Map is now at the limit.");
keyPtr = CacheableKey::create("6");
ASSERT(keyPtr != NULLPTR, "expected keyPtr non-NULL");
LOG("About to spill over.");
entries->put(keyPtr, ct, me, oldValue, -1, 0, versionTag);
LOG("Spilled over.");
ASSERT(entries->size() == 5, "expected size 5.");
LOG("Limit was preserved.");
}
END_TEST(LRULimitEvictTest)
#endif