Skip to content

Commit

Permalink
Working now, have all 4 operations for transient
Browse files Browse the repository at this point in the history
  • Loading branch information
Louis Jenkins committed Jan 7, 2021
1 parent 4d41c47 commit b5b03d2
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 181 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ LDFLAGS := $(WARNING_FLAGS) $(foreach d, $(LDIRS), -Xlinker -rpath -Xlinker $(d)

ifeq ($(BUILD),graph-rec)
# -ftree-vectorize crashes Mnemosyne
CFLAGS+=-DGRAPH_RECOVERY -ftree-vectorize -O3 -DNDEBUG
CXXFLAGS+=-DGRAPH_RECOVERY -ftree-vectorize -O3 -DNDEBUG
CFLAGS+=-DGRAPH_RECOVERY -ftree-vectorize -O0 #-DNDEBUG
CXXFLAGS+=-DGRAPH_RECOVERY -ftree-vectorize -O0 #-DNDEBUG
# we can add additional release customization here
# e.g. link against different libraries,
# define enviroment vars, etc.
Expand Down
39 changes: 3 additions & 36 deletions src/RGraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class RGraph : public Rideable{
*/
virtual bool add_edge(int src, int dest, int weight) = 0;

virtual bool add_vertex(int vid) = 0;

virtual bool has_edge(int v1, int v2) = 0;

/**
Expand All @@ -26,15 +28,6 @@ class RGraph : public Rideable{
* @return True if the edge exists
*/
virtual bool remove_edge(int src, int dest) = 0;

/**
* @brief Removes any edge from the selected vertex.
*
* @param src The integer id of the source node.
* @return true If an edge can be removed.
* @return false If an edge cannot be removed, i.e. non-allocated vertex
*/
virtual bool remove_any_edge(int src) = 0;

/**
* @brief Removes vertex from graph, along with the incoming and outgoing edges.
Expand All @@ -48,33 +41,7 @@ class RGraph : public Rideable{
* @return false Vertex was already removed from the map.
*/
virtual bool remove_vertex(int vid) = 0;

/**
* @brief Calls function fn on vertex of each outgoing edge
*
* Calls the function fn on the vertex of each outgoing edge. This is to implement something
* similar to a for-each loop, but in an implementation-defined way. Will run over all outgoing
* edges or until fn returns 'false' indicating no further processing is required. This acquires the
* lock on vid, and so users should be cautious of deadlock.
*
* @param vid Identifier of the vertex
* @param fn Predicate function that performs work on outgoing edge and returns whether or not to continue processing.
*/
virtual void for_each_outgoing(int vid, std::function<bool(int)> fn) = 0;

/**
* @brief Calls function fn on vertex of each outgoing edge
*
* Calls the function fn on the vertex of each outgoing edge. This is to implement something
* similar to a for-each loop, but in an implementation-defined way. Will run over all outgoing
* edges or until fn returns 'false' indicating no further processing is required. This acquires the
* lock on vid, and so users should be cautious of deadlock.
*
* @param vid Identifier of the vertex
* @param fn Predicate function that performs work on outgoing edge and returns whether or not to continue processing.
*/
virtual void for_each_incoming(int vid, std::function<bool(int)> fn) = 0;


/**
* @brief Obtains statistics including (|V|, |E|, average degree, vertex degrees, vertex degrees length)
*
Expand Down
4 changes: 2 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int main(int argc, char *argv[])
{
GlobalTestConfig gtc;
const size_t numVertices = 1024;
const size_t meanEdgesPerVertex = 20;
const size_t meanEdgesPerVertex = 128;
const size_t vertexLoad = 50;

/* queues */
Expand Down Expand Up @@ -144,7 +144,7 @@ int main(int argc, char *argv[])
#ifndef MNEMOSYNE
gtc.addTestOption(new RecoverVerifyTest<string,string>(), "RecoverVerifyTest");

gtc.addTestOption(new GraphTest(1000000,numVertices, meanEdgesPerVertex), "GraphTest:1m:i33r33l33:c1");
gtc.addTestOption(new GraphTest(1024,numVertices, meanEdgesPerVertex), "GraphTest:1m:i33r33l33:c1");
// gtc.addTestOption(new GraphRecoveryTest("graph_data/", "orkut-edge-list_", 28610, 5, true), "GraphRecoveryTest:Orkut:verify");
// gtc.addTestOption(new GraphRecoveryTest("graph_data/", "orkut-edge-list_", 28610, 5, false), "GraphRecoveryTest:Orkut:noverify");
gtc.addTestOption(new TGraphConstructionTest("graph_data/", "orkut-edge-list_", 28610, 5), "TGraphConstructionTest:Orkut");
Expand Down
193 changes: 90 additions & 103 deletions src/rideables/TGraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,11 @@ class TGraph : public RGraph{
// 'deleter' function to control whether or not it will try to delete the wrapped pointer below
// https://stackoverflow.com/a/17853770/4111188

template<class T>
struct maybe_deleter {
bool _delete;
explicit maybe_deleter(bool doIt = true) : _delete(doIt){}

void operator()(T *p) {
if (_delete) delete p;
}
};

template <class T>
using set_shared_ptr = std::shared_ptr<T>;

template <class T>
set_shared_ptr<T> make_find_ptr(T *raw) {
return set_shared_ptr<T>(raw, maybe_deleter<T>(false));
}

class Relation;
class Vertex {
public:
std::unordered_set<set_shared_ptr<Relation>> adjacency_list;
std::unordered_set<set_shared_ptr<Relation>> dest_list;
std::unordered_set<Relation*> adjacency_list;
std::unordered_set<Relation*> dest_list;
int id;
int lbl;
Vertex(int id, int lbl): id(id), lbl(lbl){}
Expand Down Expand Up @@ -93,6 +75,7 @@ class TGraph : public RGraph{

// Allocates data structures and pre-loads the graph
TGraph(GlobalTestConfig* gtc) {
srand(time(NULL));
this->idxToVertex = new Vertex*[numVertices];
this->vertexLocks = new std::atomic<bool>[numVertices];
this->vertexSeqs = new uint32_t[numVertices];
Expand All @@ -115,16 +98,17 @@ class TGraph : public RGraph{

// Fill to mean edges per vertex
for (int i = 0; i < numVertices; i++) {
for (int i = 0; i < meanEdgesPerVertex * 100 / vertexLoad; i++) {
if (idxToVertex[i] == nullptr) continue;
int j = verticesRNG(gen);
while (j == i) {
j = verticesRNG(gen);
if (idxToVertex[i] == nullptr) continue;
for (int j = 0; j < meanEdgesPerVertex * 100 / vertexLoad; j++) {
int k = verticesRNG(gen);
while (k == i) {
k = verticesRNG(gen);
}
if (idxToVertex[j] != nullptr) {
auto r = make_shared<Relation>(i,j,-1);
source(i).insert(r);
destination(j).insert(r);
if (idxToVertex[k] != nullptr) {
Relation *in = new Relation(i, k, -1);
Relation *out = new Relation(i, k, -1);
source(i).insert(in);
destination(k).insert(out);
}
}
}
Expand Down Expand Up @@ -185,26 +169,28 @@ class TGraph : public RGraph{
lock(dest);
}

if (idxToVertex[src] == nullptr) {
idxToVertex[src] = new Vertex(src, src);
}
if (idxToVertex[dest] == nullptr) {
idxToVertex[dest] = new Vertex(dest, dest);
}

Relation r(src,dest,weight);
auto& srcSet = source(src);
auto& destSet = destination(dest);

// Note: We do not create a vertex if one is not found
// also we do not add an edge even if it is found some of the time
// to enable even constant load factor
if (idxToVertex[src] == nullptr || idxToVertex[dest] == nullptr) {
goto exitEarly;
}
if (has_relation(srcSet, &r)) {
// Sanity check
assert(has_relation(destSet, &r));
goto exitEarly;
}

{
std::shared_ptr<Relation> rel = std::make_shared<Relation>(src, dest, weight);
srcSet.insert(rel);
destSet.insert(rel);
Relation *out = new Relation(src, dest, weight);
Relation *in = new Relation(src, dest, weight);
srcSet.insert(out);
destSet.insert(in);
inc_seq(src);
inc_seq(dest);
retval = true;
Expand Down Expand Up @@ -272,36 +258,49 @@ class TGraph : public RGraph{
return true;
}

bool remove_any_edge(int vid) {
lock(vid);
int src = -1;
int dest = -1;

if (idxToVertex[vid] != nullptr) {
// Check source first
auto search = source(vid).begin();
if (search == source(vid).end()) {
// Then destination
search = destination(vid).begin();
if (search == destination(vid).end()) {
goto failure;
}
bool add_vertex(int vid) {
std::mt19937_64 vertexGen;
std::uniform_int_distribution<> uniformVertex(0,numVertices);
bool retval = true;
// Randomly sample vertices...
std::vector<int> vec(meanEdgesPerVertex);
for (size_t i = 0; i < meanEdgesPerVertex; i++) {
int u = uniformVertex(vertexGen);
while (u == i) {
u = uniformVertex(vertexGen);
}
std::shared_ptr<Relation> r = *search;
src = r->src;
dest = r->dest;
vec.push_back(u);
}

failure:
unlock(vid);
if (src == -1 || dest == -1) {
return false;
vec.push_back(vid);
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());

for (int u : vec) {
lock(u);
}

if (idxToVertex[vid] == nullptr) {
idxToVertex[vid] = new Vertex(vid, vid);
for (int u : vec) {
if (idxToVertex[u] == nullptr) continue;
if (u == vid) continue;
Relation *in = new Relation(vid, u, -1);
Relation *out = new Relation(vid, u, -1);
source(vid).insert(in);
destination(u).insert(out);
}
} else {
return remove_edge(src, dest);
retval = false;
}

std::reverse(vec.begin(), vec.end());
for (int u : vec) {
if (idxToVertex[vid] != nullptr && idxToVertex[u] != nullptr) inc_seq(u);
unlock(u);
}
return retval;
}


bool remove_vertex(int vid) {
startOver:
{
Expand All @@ -328,6 +327,16 @@ class TGraph : public RGraph{
unlock(vid);
for (int _vid : vertices) {
lock(_vid);
if (!(idxToVertex[_vid] != nullptr || get_seq(vid) != seq)) {
for (auto r : source(vid)) {
if (r->dest == _vid)
std::cout << "(" << r->src << "," << r->dest << ")" << std::endl;
}
for (auto r : destination(vid)) {
if (r->src == _vid)
std::cout << "(" << r->src << "," << r->dest << ")" << std::endl;
}
}
}

// Has vertex been changed? Start over
Expand All @@ -344,25 +353,20 @@ class TGraph : public RGraph{
// vertices that relate to this vertex
for (int other : vertices) {
if (other == vid) continue;
std::vector<Relation*> toRemoveList;

Relation src(other, vid, -1);
Relation dst(vid, other, -1);
remove_relation(source(other), &src);
remove_relation(destination(other), &dst);

// Last relation, delete this vertex
if (source(other).size() == 0 && destination(other).size() == 0) {
destroy(other);
}
}
Relation src(vid, other, -1);
Relation dest(other, vid, -1);
remove_relation(source(other), &dest);
remove_relation(destination(other), &src);
}

// Step 4: Delete edges, clear set of src and dest edges, then delete the vertex itself
source(vid).clear();
destination(vid).clear();
std::vector<Relation*> toDelete(source(vid).size() + destination(vid).size());
for (auto r : source(vid)) toDelete.push_back(r);
for (auto r : destination(vid)) toDelete.push_back(r);
destroy(vid);
for (auto r : toDelete) delete r;

// Step 5: Release in reverse order
// Step 4: Release in reverse order
std::reverse(vertices.begin(), vertices.end());
for (int _vid : vertices) {
inc_seq(_vid);
Expand All @@ -372,26 +376,6 @@ class TGraph : public RGraph{
return true;
}

void for_each_outgoing(int vid, std::function<bool(int)> fn) {
lock(vid);
for (auto r : source(vid)) {
if (!fn(r->dest)) {
break;
}
}
unlock(vid);
}

void for_each_incoming(int vid, std::function<bool(int)> fn) {
lock(vid);
for (auto r : destination(vid)) {
if (!fn(r->src)) {
break;
}
}
unlock(vid);
}

private:
void lock(size_t idx) {
std::atomic<bool>& lck = vertexLocks[idx];
Expand Down Expand Up @@ -421,24 +405,27 @@ class TGraph : public RGraph{
}

// Incoming edges
std::unordered_set<set_shared_ptr<Relation>>& source(int idx) {
std::unordered_set<Relation*>& source(int idx) {
return idxToVertex[idx]->adjacency_list;

}

// Outgoing edges
std::unordered_set<set_shared_ptr<Relation>>& destination(int idx) {
std::unordered_set<Relation*>& destination(int idx) {
return idxToVertex[idx]->dest_list;
}

bool has_relation(std::unordered_set<set_shared_ptr<Relation>>& set, Relation *r) {
auto search = set.find(make_find_ptr(r));
bool has_relation(std::unordered_set<Relation*>& set, Relation *r) {
auto search = set.find(r);
return search != set.end();
}

void remove_relation(std::unordered_set<set_shared_ptr<Relation>>& set, Relation *r) {
auto search = set.find(make_find_ptr(r));
void remove_relation(std::unordered_set<Relation*>& set, Relation *r) {
auto search = set.find(r);
if (search != set.end()) {
Relation *tmp = *search;
set.erase(search);
delete tmp;
}
}
};
Expand Down
Loading

0 comments on commit b5b03d2

Please sign in to comment.