Add SSet implementation.
This commit is contained in:
		
							parent
							
								
									8eb4ec4274
								
							
						
					
					
						commit
						2592f98296
					
				| 
						 | 
				
			
			@ -4,10 +4,12 @@ AM_CPPFLAGS +=  -Wunused-variable -std=c++17 -D_XOPEN_SOURCE -O0 -g -I.
 | 
			
		|||
AM_CPPFLAGS +=  -fno-elide-constructors -Weffc++
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS :=		ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06 \
 | 
			
		||||
			list_bench
 | 
			
		||||
			list_bench uset_bench sset_bench
 | 
			
		||||
ch01ex01_SOURCES :=	ch01ex01.cc
 | 
			
		||||
ch01ex03_SOURCES :=	ch01ex03.cc
 | 
			
		||||
ch01ex04_SOURCES :=	ch01ex04.cc
 | 
			
		||||
ch01ex05_SOURCES :=	ch01ex05.cc
 | 
			
		||||
ch01ex06_SOURCES :=	ch01ex06.cc
 | 
			
		||||
list_bench_SOURCES :=	list_bench.cc
 | 
			
		||||
uset_bench_SOURCES :=	uset_bench.cc
 | 
			
		||||
sset_bench_SOURCES :=	sset_bench.cc
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,7 @@ benchmark(ods::List<int>& list, int ops)
 | 
			
		|||
 | 
			
		||||
			cout << "\tget " << j << endl;
 | 
			
		||||
			assert(list.get(j) != -1);
 | 
			
		||||
			break;
 | 
			
		||||
		// set
 | 
			
		||||
		case 1:
 | 
			
		||||
			if (list.size() == 0) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,92 @@
 | 
			
		|||
#ifndef __ODS_ODS_SIMPSSET__
 | 
			
		||||
#define __ODS_ODS_SIMPSSET__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <optional>
 | 
			
		||||
#include <ods/simplist.h>
 | 
			
		||||
#include <ods/sset.h>
 | 
			
		||||
 | 
			
		||||
namespace ods {
 | 
			
		||||
template<typename T>
 | 
			
		||||
class SimpSSet : public SSet<T> {
 | 
			
		||||
public:
 | 
			
		||||
	SimpSSet(void);
 | 
			
		||||
	~SimpSSet(void);
 | 
			
		||||
	std::size_t size(void);
 | 
			
		||||
	bool add(T);
 | 
			
		||||
	std::optional<T> remove(T);
 | 
			
		||||
	std::optional<T> find(T);
 | 
			
		||||
private:
 | 
			
		||||
	SimpList<T>	list;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
SimpSSet<T>::SimpSSet()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
SimpSSet<T>::~SimpSSet()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::size_t
 | 
			
		||||
SimpSSet<T>::size()
 | 
			
		||||
{
 | 
			
		||||
	return this->list.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
bool
 | 
			
		||||
SimpSSet<T>::add(T value)
 | 
			
		||||
{
 | 
			
		||||
	for (std::size_t i = 0; i < this->list.size(); i++) {
 | 
			
		||||
		if (this->list.get(i) == value) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	for (std::size_t i = 0; i < this->list.size(); i++) {
 | 
			
		||||
		if (this->list.get(i) < value) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		this->list.add(i, value);
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::optional<T>
 | 
			
		||||
SimpSSet<T>::remove(T value)
 | 
			
		||||
{
 | 
			
		||||
	for (std::size_t i = 0; i < this->list.size(); i++) {
 | 
			
		||||
		if (this->list.get(i) == value) {
 | 
			
		||||
			auto removed = this->list.get(i);
 | 
			
		||||
			this->list.remove(i);
 | 
			
		||||
			return removed;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return std::nullopt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::optional<T>
 | 
			
		||||
SimpSSet<T>::find(T value)
 | 
			
		||||
{
 | 
			
		||||
	for (std::size_t i = 0; i < this->list.size(); i++) {
 | 
			
		||||
		if (this->list.get(i) == value) {
 | 
			
		||||
			return this->list.get(i);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return std::nullopt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // namespace ods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // __ODS_ODS_SIMPSSET__
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
#ifndef __ODS_ODS_SSET__
 | 
			
		||||
#define __ODS_ODS_SSET__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
namespace ods {
 | 
			
		||||
template<typename T>
 | 
			
		||||
class SSet {
 | 
			
		||||
public:
 | 
			
		||||
	virtual ~SSet(void) {};
 | 
			
		||||
	virtual std::size_t size(void) =0;
 | 
			
		||||
	virtual bool add(T) = 0;
 | 
			
		||||
	virtual std::optional<T> remove(T) = 0;
 | 
			
		||||
	virtual std::optional<T> find(T) = 0;
 | 
			
		||||
};
 | 
			
		||||
} // namespace ods
 | 
			
		||||
 | 
			
		||||
#endif // __ODS_ODS_SSET__
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
// list_bench runs benchmarks against List implementations.
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <ods/sset.h>
 | 
			
		||||
#include <ods/simpsset.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
static mt19937		rng;
 | 
			
		||||
static random_device	devrand;
 | 
			
		||||
 | 
			
		||||
// reseed picks a new seed for the RNG using the system random device.
 | 
			
		||||
static void
 | 
			
		||||
reseed()
 | 
			
		||||
{
 | 
			
		||||
	rng.seed(devrand());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
randint(int low, int high)
 | 
			
		||||
{
 | 
			
		||||
	uniform_int_distribution<int>	dist(low, high);
 | 
			
		||||
	return dist(rng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
benchmark(ods::SSet<int>& set, int ops)
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < ops; i++) {
 | 
			
		||||
		auto op = randint(0, 3);
 | 
			
		||||
		int val = randint(1, 100);
 | 
			
		||||
		
 | 
			
		||||
		switch (op) {
 | 
			
		||||
		// add
 | 
			
		||||
		case 0:
 | 
			
		||||
		case 1:
 | 
			
		||||
			cout << "\tadd " << val << endl;
 | 
			
		||||
			set.add(val);
 | 
			
		||||
			break;
 | 
			
		||||
		// remove
 | 
			
		||||
		case 2:
 | 
			
		||||
			set.remove(val);
 | 
			
		||||
			break;
 | 
			
		||||
		// find
 | 
			
		||||
		case 3:
 | 
			
		||||
			set.find(val);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
run(string label, ods::SSet<int>& list, int ops)
 | 
			
		||||
{
 | 
			
		||||
	std::chrono::steady_clock	clock;
 | 
			
		||||
	
 | 
			
		||||
	auto start = clock.now();
 | 
			
		||||
	benchmark(list, ops);
 | 
			
		||||
	auto stop = clock.now();
 | 
			
		||||
	
 | 
			
		||||
	std::chrono::duration<double> delta = stop - start;
 | 
			
		||||
	cerr << label << " @ " << ops << " ops: " << delta.count() << "s" << endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	int	ops = 1000;
 | 
			
		||||
	
 | 
			
		||||
	if (argc == 2) {
 | 
			
		||||
		ops = stoi(argv[1]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	reseed();
 | 
			
		||||
	
 | 
			
		||||
	ods::SimpSSet<int>	us;
 | 
			
		||||
	run("SimpSSet", us, ops);
 | 
			
		||||
	
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
// list_bench runs benchmarks against List implementations.
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <ods/uset.h>
 | 
			
		||||
#include <ods/simpuset.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
static mt19937		rng;
 | 
			
		||||
static random_device	devrand;
 | 
			
		||||
 | 
			
		||||
// reseed picks a new seed for the RNG using the system random device.
 | 
			
		||||
static void
 | 
			
		||||
reseed()
 | 
			
		||||
{
 | 
			
		||||
	rng.seed(devrand());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
randint(int low, int high)
 | 
			
		||||
{
 | 
			
		||||
	uniform_int_distribution<int>	dist(low, high);
 | 
			
		||||
	return dist(rng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
benchmark(ods::USet<int>& set, int ops)
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < ops; i++) {
 | 
			
		||||
		auto op = randint(0, 3);
 | 
			
		||||
		int val = randint(1, 100);
 | 
			
		||||
		
 | 
			
		||||
		switch (op) {
 | 
			
		||||
		// add
 | 
			
		||||
		case 0:
 | 
			
		||||
		case 1:
 | 
			
		||||
			cout << "\tadd " << val << endl;
 | 
			
		||||
			set.add(val);
 | 
			
		||||
			break;
 | 
			
		||||
		// remove
 | 
			
		||||
		case 2:
 | 
			
		||||
			set.remove(val);
 | 
			
		||||
			break;
 | 
			
		||||
		// find
 | 
			
		||||
		case 3:
 | 
			
		||||
			set.find(val);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
run(string label, ods::USet<int>& list, int ops)
 | 
			
		||||
{
 | 
			
		||||
	std::chrono::steady_clock	clock;
 | 
			
		||||
	
 | 
			
		||||
	auto start = clock.now();
 | 
			
		||||
	benchmark(list, ops);
 | 
			
		||||
	auto stop = clock.now();
 | 
			
		||||
	
 | 
			
		||||
	std::chrono::duration<double> delta = stop - start;
 | 
			
		||||
	cerr << label << " @ " << ops << " ops: " << delta.count() << "s" << endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	int	ops = 1000;
 | 
			
		||||
	
 | 
			
		||||
	if (argc == 2) {
 | 
			
		||||
		ops = stoi(argv[1]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	reseed();
 | 
			
		||||
	
 | 
			
		||||
	ods::SimpUSet<int>	us;
 | 
			
		||||
	run("SimpUSet", us, ops);
 | 
			
		||||
	
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue