Skip to content

Commit

Permalink
Merge pull request #354 from cndolo/nkbg-transpose
Browse files Browse the repository at this point in the history
Support for directed graphs in NetworkitBinaryGraph file format
  • Loading branch information
avdgrinten committed Jul 1, 2019
2 parents 986dc9a + 0227f70 commit 21950fa
Show file tree
Hide file tree
Showing 8 changed files with 327 additions and 118 deletions.
65 changes: 60 additions & 5 deletions include/networkit/graph/Graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ struct Edge {
inline bool operator==(const Edge &e1, const Edge &e2) {
return e1.u == e2.u && e1.v == e2.v;
}
struct Unsafe {};
static constexpr Unsafe unsafe {};
} // namespace NetworKit

namespace std {
Expand Down Expand Up @@ -679,16 +681,28 @@ class Graph final {
Graph &operator=(const Graph &other) = default;

/**
* Reserves memory in the node's edge containers.
* Reserves memory in the node's edge containers for undirected graphs.
*
* @param u the node memory should be reserved for
* @param u the node memory should be reserved for
* @param size the amount of memory to reserve
*
* This function is thread-safe if called from different
*
* This function is thread-safe if called from different
* threads on different nodes.
*/
void preallocateUndirected(node u, size_t size);

/**
* Reserves memory in the node's edge containers for directed graphs.
*
* @param u the node memory should be reserved for
* @param inSize the amount of memory to reserve for in edges
* @param outSize the amount of memory to reserve for out edges
*
* This function is thread-safe if called from different
* threads on different nodes.
*/
void preallocateDirected(node u, size_t outSize, size_t inSize);

/** EDGE IDS **/

/**
Expand Down Expand Up @@ -765,7 +779,14 @@ class Graph final {
*/
std::string getName() const { return name; }

/**
/**
* Set edge count of the graph to edges.
* @param edges the edge count of a graph
*/
void setEdgeCount(Unsafe, count edges) { m = edges; }

void setNumberOfSelfLoops(Unsafe, count loops) { storedNumberOfSelfLoops = loops; }
/**
* Returns a string representation of the graph.
* @return A string representation.
*/
Expand Down Expand Up @@ -974,6 +995,40 @@ class Graph final {
*/
void addEdge(node u, node v, edgeweight ew = defaultEdgeWeight);

/**
* Insert an edge between the nodes @a u and @a v. Unline the addEdge function, this function does not not add any information to v. If the graph is
* weighted you can optionally set a weight for this edge. The default
* weight is 1.0. Note: Multi-edges are not supported and will NOT be
* handled consistently by the graph data structure.
* @param u Endpoint of edge.
* @param v Endpoint of edge.
* @param weight Optional edge weight.
*/
void addPartialEdge(Unsafe, node u, node v, uint64_t index = 0, edgeweight ew = defaultEdgeWeight);

/**
* Insert an in edge between the nodes @a u and @a v in a directed graph. If the graph is
* weighted you can optionally set a weight for this edge. The default
* weight is 1.0. Note: Multi-edges are not supported and will NOT be
* handled consistently by the graph data structure.
* @param u Endpoint of edge.
* @param v Endpoint of edge.
* @param weight Optional edge weight.
*/
void addPartialInEdge(Unsafe, node u, node v, uint64_t index = 0, edgeweight ew = defaultEdgeWeight);

/**
* Insert an out edge between the nodes @a u and @a v in a directed graph. If the graph is
* weighted you can optionally set a weight for this edge. The default
* weight is 1.0. Note: Multi-edges are not supported and will NOT be
* handled consistently by the graph data structure.
* @param u Endpoint of edge.
* @param v Endpoint of edge.
* @param weight Optional edge weight.
*/
void addPartialOutEdge(Unsafe, node u, node v, uint64_t index = 0, edgeweight ew = defaultEdgeWeight);


/**
* Removes the undirected edge {@a u,@a v}.
* @param u Endpoint of edge.
Expand Down
16 changes: 7 additions & 9 deletions include/networkit/io/NetworkitBinaryGraph.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#ifndef NETWORKIT_BINARY_GRAPH_
#define NETWORKIT_BINARY_GRAPH_

namespace nkbg {
struct Header {
char magic[8];
uint64_t checksum;
uint64_t features;
uint64_t features;
uint64_t nodes;
uint64_t chunks;
uint64_t offsetBaseData;
Expand All @@ -20,13 +21,10 @@ enum WEIGHT_FORMAT {
FLOAT = 3
};

enum MASKS {
DIR_MASK = 0x1, // bit 0
WGHT_MASK = 0x6, // bit 1-2
WGHT_SHIFT = 0x1
};

constexpr auto DELETED_BIT = uint64_t(1) << 52;
constexpr auto SIZE_MASK = (uint64_t(1) << 52) - 1;
static constexpr uint8_t DELETED_BIT = 0x1; // bit 0
static constexpr uint64_t DIR_MASK = 0x1; // bit 0
static constexpr uint64_t WGHT_MASK = 0x6; //bit 1-2
static constexpr uint64_t WGHT_SHIFT = 0x1;

}
#endif
19 changes: 5 additions & 14 deletions include/networkit/io/NetworkitBinaryReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,8 @@
#ifndef NETWORKIT_BINARY_READER_H
#define NETWORKIT_BINARY_READER_H

#include <networkit/auxiliary/Log.hpp>
#include <networkit/graph/Graph.hpp>
#include <networkit/io/GraphReader.hpp>
#include <networkit/io/NetworkitBinaryGraph.hpp>
#include <networkit/io/MemoryMappedFile.hpp>
#include <tlx/math/ffs.hpp>

#include <vector>
#include <fstream>
#include <string.h>
#include <cstring>
#include <networkit/graph/Graph.hpp>

namespace NetworKit {

Expand All @@ -28,21 +19,21 @@ namespace NetworKit {

class NetworkitBinaryReader : public GraphReader {

public:
public:
NetworkitBinaryReader() {};

Graph read(const std::string& path) override;

private:
static size_t decode(const uint8_t* data, uint64_t& result);

static int64_t decodeZigzag(uint64_t value);

count nodes;
count chunks;
bool directed;
bool weighted;
};
};
} /* namespace */

#endif
18 changes: 6 additions & 12 deletions include/networkit/io/NetworkitBinaryWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@

#include <networkit/graph/Graph.hpp>
#include <networkit/io/GraphWriter.hpp>
#include <networkit/auxiliary/Enforce.hpp>
#include <networkit/io/NetworkitBinaryGraph.hpp>
#include <tlx/math/clz.hpp>

#include <fstream>
#include <cstring>

namespace NetworKit {

Expand All @@ -23,21 +17,21 @@ namespace NetworKit {
*
* Writes a graph in the custom Networkit format documented in cpp/io/NetworkitGraph.md
*/

class NetworkitBinaryWriter : public GraphWriter {

public:
NetworkitBinaryWriter(uint64_t chunks = 32);
void write(const Graph& G, const std::string& path);

void write(const Graph& G, const std::string& path) override;

private:
static size_t encode(uint64_t value, uint8_t* buffer);

static uint64_t encodeZigzag(int64_t value);

count nodes;
count chunks;
count chunks;
};
} /* namespace */
#endif
61 changes: 60 additions & 1 deletion networkit/cpp/graph/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ Graph::Graph(const Graph &G, bool weighted, bool directed)
}

void Graph::preallocateUndirected(node u, size_t size) {
assert(!directed);
assert(exists[u]);
outEdges[u].reserve(size);
if(weighted) {
outEdgeWeights[u].reserve(size);
Expand All @@ -179,6 +181,21 @@ void Graph::preallocateUndirected(node u, size_t size) {
}
}

void Graph::preallocateDirected(node u, size_t outSize, size_t inSize) {
assert(directed);
assert(exists[u]);
inEdges[u].reserve(inSize);
outEdges[u].reserve(outSize);

if(weighted) {
inEdgeWeights[u].reserve(inSize);
outEdgeWeights[u].reserve(outSize);
}
if(edgesIndexed) {
inEdgeIds[u].reserve(inSize);
outEdgeIds[u].reserve(outSize);
}
}
/** PRIVATE HELPERS **/

count Graph::getNextGraphId() {
Expand Down Expand Up @@ -675,7 +692,49 @@ void Graph::addEdge(node u, node v, edgeweight ew) {
if (u == v) { // count self loop
++storedNumberOfSelfLoops;
}
} // namespace NetworKit
}
void Graph::addPartialEdge(Unsafe, node u, node v, uint64_t index, edgeweight ew) {
assert(u < z);
assert(exists[u]);
assert(v < z);
assert(exists[v]);

outEdges[u].push_back(v);

// if edges indexed, give new id
if (edgesIndexed) {
outEdgeIds[u].push_back(index);
}
if (weighted) {
outEdgeWeights[u].push_back(ew);
}
}
void Graph::addPartialOutEdge(Unsafe, node u, node v, uint64_t index, edgeweight ew) {
assert(u < z);
assert(exists[u]);
assert(v < z);
assert(exists[v]);

outEdges[u].push_back(v);

if (weighted) {
outEdgeWeights[u].push_back(ew);
}
}
void Graph::addPartialInEdge(Unsafe, node u, node v, uint64_t index, edgeweight ew) {
assert(u < z);
assert(exists[u]);
assert(v < z);
assert(exists[v]);

inEdges[u].push_back(v);
if (edgesIndexed) {
inEdgeIds[u].push_back(index);
}
if (weighted) {
inEdgeWeights[u].push_back(ew);
}
}

template <typename T>
void erase(node u, index idx, std::vector<std::vector<T>> &vec) {
Expand Down
18 changes: 14 additions & 4 deletions networkit/cpp/io/NetworkitBinaryGraph.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct Header {
};
```
- magic: A constant value used to identify the file format version.
- The current version is '*nkbg000*' which supports unweighted, undirected graphs.
- The current version is '*nkbg001*' which supports unweighted, undirected and directed graphs.
- checksum: Currently not used
- features: Contains the graph information bitwise
- Bit 0 : directed or undirected
Expand All @@ -35,23 +35,33 @@ struct Header {
- chunks: The number of chunks the nodes have been divided in
- offsetBaseData: Offset of base data in the file
- offsetAdjLists: Offset of the adjacency lists in the file
- offsetTranspose: Currently unused
- offsetTranspose: Offset of the transposed adjaceny lists in the file
- offsetWeights: Offset of the weights in the file

All offsets are relative to the beginning of the file.
All offsets are relative to the beginning of the section.

Base data
------------
```
uint64_t sizeSum[nodes]: The sum of sizes of adjacency vertices with indices <= i
uint64_t nodeFlags[nodes]: Flags storing information about a node
uint64_t firstVertex[chunks-1]: The index of the first vertex of each chunk excluding the first chunk
```
Adjacency lists
-----------------
```
uint64_t nrOfEdges: the total number of edges in the block
uint64_t offset[chunks-1]: Offset of the file where the adjacency list of
the firstVertex of each chunk relative to data starts
varint data [...]: Varint encoded adjaceny lists
```
Transpose lists
-----------------
```
uint64_t nrOfEdges: the total number of edges in the block
uint64_t offset[chunks-1]: Offset of the file where the tranpose list of
the firstVertex of each chunk relative to data starts
varint data [...]: Varint encoded transpose lists
```
Weights
--------------------
Expand Down
Loading

0 comments on commit 21950fa

Please sign in to comment.