/**
* Copyright (C) 2014 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects for
* all of the code used other than as permitted herein. If you modify file(s)
* with this exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
#include
#include
#include "mongo/db/concurrency/fast_map_noalloc.h"
#include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
struct TestStruct {
void initNew(int newId, const std::string& newValue) {
id = newId;
value = newValue;
}
int id;
std::string value;
};
typedef class FastMapNoAlloc TestFastMapNoAlloc;
TEST(FastMapNoAlloc, Empty) {
TestFastMapNoAlloc map;
ASSERT(map.empty());
TestFastMapNoAlloc::Iterator it = map.begin();
ASSERT(it.finished());
}
TEST(FastMapNoAlloc, NotEmpty) {
TestFastMapNoAlloc map;
map.insert(ResourceId(RESOURCE_COLLECTION, 1))->initNew(101, "Item101");
map.insert(ResourceId(RESOURCE_COLLECTION, 2))->initNew(102, "Item102");
ASSERT(!map.empty());
TestFastMapNoAlloc::Iterator it = map.begin();
ASSERT(!it.finished());
ASSERT(!!it);
ASSERT(it->id == 101);
ASSERT(it->value == "Item101");
it.next();
ASSERT(!it.finished());
ASSERT(!!it);
ASSERT(it->id == 102);
ASSERT(it->value == "Item102");
// We are at the last element
it.next();
ASSERT(it.finished());
ASSERT(!it);
}
TEST(FastMapNoAlloc, FindNonExisting) {
TestFastMapNoAlloc map;
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 0)));
}
TEST(FastMapNoAlloc, FindAndRemove) {
TestFastMapNoAlloc map;
for (int i = 0; i < 6; i++) {
map.insert(ResourceId(RESOURCE_COLLECTION, i))->initNew(
i, "Item" + boost::lexical_cast(i));
}
for (int i = 0; i < 6; i++) {
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, i)).finished());
ASSERT_EQUALS(i, map.find(ResourceId(RESOURCE_COLLECTION, i))->id);
ASSERT_EQUALS("Item" + boost::lexical_cast(i),
map.find(ResourceId(RESOURCE_COLLECTION, i))->value);
}
// Remove a middle entry
map.find(ResourceId(RESOURCE_COLLECTION, 2)).remove();
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 2)));
// Remove entry after first
map.find(ResourceId(RESOURCE_COLLECTION, 1)).remove();
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 1)));
// Remove entry before last
map.find(ResourceId(RESOURCE_COLLECTION, 4)).remove();
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 4)));
// Remove first entry
map.find(ResourceId(RESOURCE_COLLECTION, 0)).remove();
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 0)));
// Remove last entry
map.find(ResourceId(RESOURCE_COLLECTION, 5)).remove();
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 5)));
// Remove final entry
map.find(ResourceId(RESOURCE_COLLECTION, 3)).remove();
ASSERT(!map.find(ResourceId(RESOURCE_COLLECTION, 3)));
}
TEST(FastMapNoAlloc, RemoveAll) {
TestFastMapNoAlloc map;
unordered_map checkMap;
for (int i = 1; i <= 6; i++) {
map.insert(ResourceId(RESOURCE_COLLECTION, i))->initNew(
i, "Item" + boost::lexical_cast(i));
checkMap[ResourceId(RESOURCE_COLLECTION, i)].initNew(
i, "Item" + boost::lexical_cast(i));
}
TestFastMapNoAlloc::Iterator it = map.begin();
while (!it.finished()) {
ASSERT_EQUALS(it->id, checkMap[it.key()].id);
ASSERT_EQUALS(
"Item" + boost::lexical_cast(it->id), checkMap[it.key()].value);
checkMap.erase(it.key());
it.remove();
}
ASSERT(map.empty());
ASSERT(checkMap.empty());
}
} // namespace mongo