Example #1
0
int Database::search(const vector<SearchCriterion>& searchCriteria,
	const vector<SortCriterion>& sortCriteria, vector<int>& results)
{
	results.clear();
	if (searchCriteria.empty()) // no search criteria
		return ERROR_RESULT;

	// Search
	//	The result of our query is the intersection of all search criteria. To do this, 
	//	for each search criteria, we plug our results into the unordered_set cur_query.
	//	For each subsequent search criteria, we replace prev_query with cur_query, clear
	//	cur_query, then check if each new value exists within prev_query: if it does, we 
	//	have an intersection, and we enter the value into cur_query.
	unordered_set<int> cur_query, prev_query;
	for (int i = 0; i < searchCriteria.size(); ++i)
	{
		if (searchCriteria[i].minValue == "" && searchCriteria[i].maxValue == "")
			return ERROR_RESULT; // lacks both min AND max values

		// Find fieldName within m_schema
		prev_query = cur_query;
		cur_query.clear();
		int j = 0;
		for (; j < m_schema.size(); ++j)
		{
			if (searchCriteria[i].fieldName == m_schema[j].name)
			{
				if (m_schema[j].index == it_none) // field name is non-indexed
					return ERROR_RESULT;

				// Find all rows between minValue and maxValue, inclusive.
				// If minValue or maxValue is empty, min and max iterators will be set to the
				// smallest and largest nodes, respectively.
				MultiMap::Iterator min = m_fieldIndex[j]->findEqualOrSuccessor(searchCriteria[i].minValue),
					max = m_fieldIndex[j]->findEqualOrPredecessor(searchCriteria[i].maxValue);
				for (; min.valid(); min.next())
				{
					bool add = true;
					if (i > 0) // only check the previous query if this is not our first
					{
						unordered_set<int>::const_iterator found = prev_query.find(min.getValue());
						if (found == prev_query.end()) // not found, so no intersection
							add = false;
					}
					if (add)
						cur_query.insert(min.getValue()); // inserts row # to current unordered_set
					if (min.getKey() == max.getKey() && min.getValue() == max.getValue())
						break;
				}
				break;
			}
		}
		if (j == m_schema.size()) // no fieldName match found
			return ERROR_RESULT;
	}
	
	// Sort
	for (auto it = cur_query.begin(); it != cur_query.end(); ++it)
		results.push_back(*it);
	if (!sortCriteria.empty())
		quicksort(results, 0, cur_query.size(), sortCriteria);

	return cur_query.size();
}
Example #2
0
int main()
{
	/*Database db;
	db.loadFromURL("http://cs.ucla.edu/classes/winter14/cs32/Projects/4/Data/census.csv");
*/
	MultiMap m;
	m.insert("D", 8);
	m.insert("B", 4);
	m.insert("F", 12);
	m.insert("A", 1);
	m.insert("C", 5);
	m.insert("E", 9);
	m.insert("G", 13);
	m.insert("A", 2);
	m.insert("C", 6);
	m.insert("E", 10);
	m.insert("G", 14);
	m.insert("A", 3);
	m.insert("C", 7);
	m.insert("E", 11);
	m.insert("G", 15);

	MultiMap::Iterator c(m.findEqual("D"));
	assert(c.valid());
	MultiMap::Iterator d;
	for (; c.valid(); c.prev())
		d = c;
	for (; d.valid(); d.next())
		cout << d.getKey() << " " << d.getValue() << endl;

	cout << endl;

	MultiMap::Iterator a(m.findEqual("D"));
	assert(a.valid());
	MultiMap::Iterator b;
	for (; a.valid(); a.next())
		b = a;
	for (; b.valid(); b.prev())
		cout << b.getKey() << " " << b.getValue() << endl;

	MultiMap::Iterator t;
	t = m.findEqual("A");
	if (t.valid())
	{
		cout << endl;
		cout << t.getKey() << " " << t.getValue() << endl;
		t.next();
		cout << t.getKey() << " " << t.getValue() << endl;
		t.next();
		cout << t.getKey() << " " << t.getValue() << endl;
	}
	t = m.findEqualOrSuccessor("Fz");
	if (t.valid())
	{
		cout << endl;
		cout << t.getKey() << " " << t.getValue() << endl;
		t.next();
		cout << t.getKey() << " " << t.getValue() << endl;
		t.next();
		cout << t.getKey() << " " << t.getValue() << endl;
	}
	t = m.findEqualOrPredecessor("E");
	t.next();
	MultiMap::Iterator after = t;
	t.next();
	MultiMap::Iterator afterafter = t;
	t.prev();
	t.prev();
	if (t.valid() && after.valid() && afterafter.valid())
	{
		cout << endl;
		cout << t.getKey() << " " << t.getValue() << endl;
		t.next();
		cout << t.getKey() << " " << t.getValue() << endl;
		t.next();
		cout << t.getKey() << " " << t.getValue() << endl;
	}

	Database database;

	Database::FieldDescriptor fd1, fd2, fd3;

	fd1.name = "username";
	fd1.index = Database::it_indexed;	//	username	is	an	indexed	field	

	fd2.name = "phonenum";
	fd2.index = Database::it_indexed;	//	phone	#	is	an	indexed	field	

	fd3.name = "age";
	fd3.index = Database::it_none;	//	age	is	NOT	an	indexed	field	

	std::vector<Database::FieldDescriptor>	schema;
	schema.push_back(fd1);
	schema.push_back(fd2);
	schema.push_back(fd3);

	database.specifySchema(schema);

	vector<string> row;
	string username = "******";
	string phonenum = "6265375521";
	string age = "17";
	row.push_back(username);
	row.push_back(phonenum);
	row.push_back(age);

	database.addRow(row);

	vector<string> row2;
	username = "******";
	phonenum = "5403317654";
	age = "20";
	row2.push_back(username);
	row2.push_back(phonenum);
	row2.push_back(age);

	database.addRow(row2);

	vector<string> row3;
	username = "******";
	phonenum = "6265375521";
	age = "25";
	row3.push_back(username);
	row3.push_back(phonenum);
	row3.push_back(age);

	database.addRow(row3);

	vector<int> results;
	vector<Database::SortCriterion> sortCrit;
	vector<Database::SearchCriterion> searchCrit;
	
	Database::SearchCriterion s1;
	s1.fieldName = "username";
	s1.minValue = "A";
	s1.maxValue = "C";

	Database::SearchCriterion s2;
	s2.fieldName = "phonenum";
	s2.minValue = "6000000000";
	s2.maxValue = "";

	searchCrit.push_back(s1);
	searchCrit.push_back(s2);


	database.search(searchCrit, sortCrit, results);

	cout << endl << "Passed all tests" << endl;
}