arXiv is now an independent nonprofit! Learn more
License: arXiv.org perpetual non-exclusive license
arXiv:1809.01246v1 [cs.DS] 04 Sep 2018

Fast and Accurate Graph Stream Summarization

Xiangyang Gou, Lei Zou, Chenxingyu Zhao, Tong Yang Affiliation: Peking University, China
Abstract

A graph stream is a continuous sequence of data items, in which each item indicates an edge, including its two endpoints and edge weight. It forms a dynamic graph that changes with every item in the stream. Graph streams play important roles in cyber security, social networks, cloud troubleshooting systems and other fields. Due to the vast volume and high update speed of graph streams, traditional data structures for graph storage such as the adjacency matrix and the adjacency list are no longer sufficient. However, prior art of graph stream summarization, like CM sketches, gSketches, TCM and gMatrix, either supports limited kinds of queries or suffers from poor accuracy of query results. In this paper, we propose a novel Graph Stream Sketch (GSS for short) to summarize the graph streams, which has the linear space cost (O(|E|)O(|E|), E is the edge set of the graph) and the constant update time complexity (O(1)O(1)) and supports all kinds of queries over graph streams with the controllable errors. Both theoretical analysis and experiment results confirm the superiority of our solution with regard to the time/space complexity and query results’ precision compared with the state-of-the-art.

Index Terms: 
graph, data stream, sketch, approximate query

I Introduction

I-A Background and Motivations

In the era of big data, data streams propose some technique challenges for existing systems. Furthermore, the traditional data stream is modeled as a sequence of isolated items, and the connections between the items are rarely considered. However, in many data stream applications, the connections often play important roles in data analysis, such as finding malicious attacks in the network traffic data, mining news spreading paths among the social network. In these cases the data is organized as graph streams. A graph stream is an unbounded sequence of items, in which each item is a vector with at least three fields (denoted by (s,d,w)(\langle s,d\rangle,w)), where s,d\langle s,d\rangle represents an edge between nodes ss and dd, and ww is the edge weight. These data items together form a dynamic graph that changes continuously and we call it streaming graph for convenience. Below we discuss three examples to demonstrate the usefulness of streaming graph problems.

Use case 1: Network traffic. The network traffic can be seen as a large dynamic graph, where each edge indicates the communication between two IP addresses. With the arrival of packets in the network, the network traffic graph changes rapidly and constantly. In the network traffic graph, various kinds of queries are needed, like performing node queries to find malicious attackers, or subgraph queries to locate certain topology structures in the dynamic networks.

Use case 2: Social networks. In a social network, the interactions among the users can form a graph. The edges between different nodes may be weighted by the frequencies of interactions. In such a graph, queries like finding the potential friends of a user and tracking the spreading path of a piece of news are often needed.

Use case 3: Troubleshooting in data centers. Cloud systems may need to analyze communication log stream to perform real time troubleshooting. In this situation the graph stream is the sequence of communication log entries where each entry is a description of a communication from a source machine to a destination machine. In such a graph, we may perform traversal query to find out if massages created by a certain application on a source machine can reach a destination machine, or perform edge query to find the detailed information of a communication log.

These streaming graphs are very large and change fast. For example, in Twitter, there are about 100100 million user login data, with 500500 million tweets posted per day. For another example, in large ISP or data centers[1], there could be millions of packets every second in each link. The large volume and high dynamicity make it hard to store the graph streams efficiently with traditional data structures like adjacency lists or adjacency matrices. In the context of graph streams, there are two requirements for designing a new data structure : (1) the linear space cost (2) the constant update time. To meet these two requirements, we can either apply approximated query data structures for data streams, like the CM sketch[2], the CU sketch [3] and other sketches [4, 5], or use specialized graph summarization techniques such as gSketches [6], TCM [7] and gMatrix [8]. However, existing solutions either support limited query types or have poor query accuracy. For example, CM sketches and gSketches fail to answer queries involved with topology like reachability queries, successor queries and so on. Though TCM and gMatrix can support these queries, they have poor accuracy. More details about the related work are given in Section II. In this paper, we design a novel data structure–Graph Stream Sketch (GSS for short), which can support all kinds of queries over streaming graphs with controllable errors in query results. Both theoretical analysis and experiment results show that the accuracy of our method outperforms state-of-the-art by orders of magnitudes.

I-B Our Solution

In this paper we propose GSS, which is an approximate query data structure for graph streams with linear memory usage, high update speed, high accuracy and supports all kinds of graph queries and algorithms like [9, 10, 11]. GSS can also be used in exiting distributed graph systems [12, 13, 14, 15]

Like TCM, GSS uses a hash function H()H(\cdot) to compress the streaming graph GG into a smaller graph GhG_{h} which is named a graph sketch. Each node vv in GG is mapped into a hash value H(v)H(v). Nodes with the same hash value are combined into one node in GhG_{h}, and the edges connected to them are also aggregated. An example of the graph stream and the graph sketch can be referred in Fig.1 and Fig.2. The compression rate can be controlled by the size of the value range of H()H(\cdot), which we represent with MM. The higher the compression rate is, the lower the accuracy is, as more nodes and edges will be combined.

Different from TCM which uses an adjacency matrix to store the graph sketch GhG_{h}, GSS uses a novel data structure to store it. This data structure is specially designed for sparse graphs and can store a much bigger graph sketch with the same space. As the graph is sparse, the number of nodes is large, but each node is connected to few edges. Therefore, different from adjacency matrix which stores edges with the same source node / destination node in one row / column, we store edges with different source nodes / destination nodes in the one row / column, and distinguish them with fingerprints. Each edge in the graph sketch is mapped to a bucket in the matrix depending on its endpoints, and marked with a fingerprint pair. If the bucket it is mapped is already occupied by other edges, we store this edge in a buffer BB, which is composed of adjacency lists. With a m×mm\times m matrix we can represent a graph sketch with at most m×Fm\times F nodes in GSS, where FF is the size of the value range of the fingerprint (for example, a 16-bit fingerprint has F=65536F=65536). On the other hand, the adjacency matrix can only store a a graph sketch with at most mm nodes. With a much larger graph sketch, the accuracy is also much higher compared to TCM.

In GSS, the memory cost and update speed are greatly influenced by the size of the buffer BB. As the buffer takes additional memory, and update speed in an adjacency list is linear with its size. In order to restrict its size, we propose a technique called square hashing. In this technique each edge is mapped to multiple buckets, and stored in the first empty one among them. This enlarges the chance that an edge finds an empty bucket. Besides, a few nodes in a sparse graph may still have very high degrees. If one node emits a lot of edges, these edges have high probability to evict each other when stored in one row. To solve this problem, In square hashing edges with source node vv are no longer mapped to one row, but rr rows, sharing memory with other source nodes. The higher degree a node has, the more buckets it may take. It is similar in the view of columns and destination nodes. This helps to ease the congestion brought by the skewness in node degrees. Experiments show that after this modification the buffer only stores less than 0.01%0.01\% of the edges in the graph stream.

The key contributions of this paper are as follows:

  1. 1.

    We propose GSS, a novel data structure for graph stream summarization. It has small memory usage, high update speed, and supports almost all kinds of queries for graphs. Most important of all, it uses a combination of fingerprints and hash addresses to achieve very high accuracy.

  2. 2.

    We propose a technique called square hashing in the implementation of GSS. It helps to decrease the buffer size, improve update speed and reduce memory cost. It also eases the influence brought by the skewness in node degrees.

  3. 3.

    We define 33 graph query primitives and give details about how GSS supports them. Almost all algorithms for graphs can be implemented with these primitives.

  4. 4.

    We carry out theoretical analysis and extensive experiments to evaluate the performance of GSS, which show that when using 1/256 memory size of the state-of-the-art graph summarization algorithm, our algorithm still significantly outperforms it for most queries.

II Related Work

In this part we will give a brief introduction about the related works. The prior arts of graph stream summarization can be divided into two kinds. The first kind is composed of counter arrays and stores each data item in these arrays independently, ignoring the connections between them. They only support queries for edge weights, but do not support any queries involved with topology of the graph. This kind includes CM sketches[2], CU sketches[3], gSketches[6] and so on. The second kind supports all queries in the streaming graph, but suffers from poor accuracy. This kind includes TCM[7] and gMatrix[8]. Because of space limitation, in this section we only introduce the second kind which is more relevant to our work.

TCM [7] is the state-of -the-art of data structures for graph stream summarization. It is composed of an adjacency matrix that stores the compression of the streaming graph. It uses a hash function H()H(\cdot) to compress the streaming graph G=(V,E)G=(V,E) into a smaller graph sketch GhG_{h}. For each node vv in GG, TCM maps it to node H(v)H(v) in GhG_{h}. For each edge e=s,de=\overrightarrow{s,d} in GG, TCM maps it to edge H(s),H(d)\overrightarrow{H(s),H(d)} in GhG_{h}. The weight of an edge in GhG_{h} is an aggregation of the weights of all edges mapped to it. A hash table that stores the hash value and the original ID pairs can be built in this map procedure to retrieve the original node IDs for some queries. Then TCM uses an adjacency matrix to represent the graph sketch. If we represent the size of the value range of H()H(\cdot) with MM, we need to build an M×MM\times M adjacency matrix. Each bucket in the matrix contains a counter. The weight of edge H(s),H(d)\overrightarrow{H(s),H(d)} in the graph sketch is added to the counter in the bucket in row H(s)H(s), column H(d)H(d).

When the memory is sufficient, we can also build multiple sketches with different hash functions, and report the most accurate value in queries.

In order to satisfy the demand on memory usage, the size of the adjacency matrix, M×MM\times M has to be within O(|E|)O(|E|), which means M|V|M\ll|V| for a sparse streaming graph where |E||V|\frac{|E|}{|V|} is usually within 1010. This means the graph sketch GhG_{h} is usually much smaller than GG, a lot of nodes and edges will be aggregated. As a result, the accuracy of TCM is poor.

The gMatrix [8] is a variant of TCM. Its structure is similar to TCM. But it uses reversible hash functions to generate graph sketches. It also extends TCM to more queries like edge heavy hitters and so on. However, different from the accurate hash tables, the reversible hash function introduces additional errors in the reverse procedure. Therefore the accuracy of gMatrix is no better than TCM, sometimes even worse.

There are some graph algorithms for statistic graph compression [16, 17, 18] or specific queries in graph stream processing [19, 20, 21]. However, they are either not suitable for high dynamic graph streams or too limited in functions. We do not introduce them in detail due to space limit.

III Problem Definition

Definition 1

Graph Stream: A graph stream is an unbounded timing evolving sequence of items S={e1,e2,e3en}S=\{e_{1},e_{2},e_{3}......e_{n}\}, where each item ei=(s,d,t,w)e_{i}=(\overrightarrow{s,d};t;w) indicates a directed edge11 1 The approach in this paper can be easily extended to handle undirected graphs. from node ss to node dd, with wight ww. The timepoint tit_{i} is also referred as the timestamp of eie_{i}. Thus, the edge streaming sequence SS forms a dynamic directed graph G=(V,E)G=(V,E) that changes with the arrival of every item eie_{i}, where VV and EE denote the set of nodes and the set of edges in the graph, respectively. We call GG a streaming graph for convenience.

In a graph stream SS, an edge s,d\overrightarrow{s,d} may appear multiple times with different timestamps. The weight of such edge in the streaming graph GG is SUM of all edge weights sharing the same endpoints. The weight ww can be either positive or negative. An item with w<0w<0 means deleting a former data item.

Example 1

A sample graph stream SS and the corresponding streaming graph GG are both shown in Fig. 1. Each node has an ID that uniquely identifies itself. If an edge appears multiple times, its weights are added up as stated above.

In practice, GG is usually a large, sparse and high speed dynamic graph. The large volume and high dynamicity make it hard to store graph streams using traditional data structures such as adjacency lists and adjacency matrices. The large space cost of O(|V|2)O({|V|}^{2}) rules out the possibility of using the adjacency matrix to represent a large sparse graph. On the other hand, the adjacency list has O(|E|)O(|E|) memory cost, which is acceptable, but the time cost of inserting an edge is O(|V|)O(|V|), which is unacceptable due to the high speed of the graph stream.

The goal of our study is to design a linear space cost data structure with efficient query and update algorithms over high speed graph streams. To meet that goal, we allow some approximate query results but with small and controllable errors. However, traditional graph stream summarization approaches either cannot answer graph topology queries such as reachability queries (such as CM sketches [2] and gSketches [6]) or fail to provide accurate query results (such as TCM [7] and gMatrix [8]). Therefore, in this paper, we design a novel graph stream summarization strategy.

In order to give a definition of the graph stream summarization problem, First we define the graph sketch as follows:

Definition 2

Graph Sketch: a graph sketch of G=(V,E)G=(V,E) is a samller graph Gh=(Vh,Eh)G_{h}=(V_{h},E_{h}) where |Vh||V||V_{h}|\leqslant|V| and |Eh||E||E_{h}|\leqslant|E|. A map function H()H(\cdot) is used to map each node in VV to a node in VhV_{h}, and edge e=s,de=\overrightarrow{s,d} in EE is mapped to edge H(s),H(d)\overrightarrow{H(s),H(d)} in EhE_{h}. The weight of an edge in EhE_{h} is the SUM of the weights of all edges mapped to it.

Formally, we define our graph stream summarization problem as follows.

Fig. 1: A sample graph stream
Definition 3

Graph Stream Summarization: Given a streaming graph G=(V,E)G=(V,E), the graph stream summarization problem is to design a graph sketch Gh=(Vh,Eh)G_{h}=(V_{h},E_{h}), and the corresponding data structure DSDS to represent GhG_{h}, where the following conditions hold:

  1. 1.

    There is a function H()H(\cdot) that map nodes in VV to nodes in VhV_{h};

  2. 2.

    The space cost of DSDS is O(|E|)O(|E|);

  3. 3.

    DSDS changes with each new arriving data item in the streaming graph and the time complexity of updating DSDS should be O(1)O(1);

  4. 4.

    DSDS supports answering any query over the original streaming graph GG with small and controllable errors.

In the context of streaming graphs, GG changes with every data item in the graph stream SS, which is mapped to updating the graph sketch GhG_{h}, and conducted in data structure DSDS. For every new item (s,d,t,w)(\overrightarrow{s,d};t;w) in SS, we map edge s,d\overrightarrow{s,d} in GG to edge H(s),H(d)\overrightarrow{H(s),H(d)} in GhG_{h} with weight ww and then insert it into GhG_{h}. Similarly, queries over GG are also mapped to the same kind of queries over the graph sketch GhG_{h}. In order to support any kind of graph queries, we first define three graph query primitives as follows, since many kinds of graph queries can be answered using these primitives.

Definition 4

Graph Query Primitives: Given a graph G(V,E)G(V,E), the three graph query primitives are:

  • Edge Query: given an edge e=s,de=\overrightarrow{s,d}, return its weight w(e)w(e) if it exists in the graph and return 1-1 if not.

  • 11-hop Successor Query: given a node vv, return a set of nodes that are 1-hop reachable from vv, and return {1}\{-1\} if there is no such node;

  • 11-hop Precursor Query: given a node vv, return a set of nodes that can reach node vv in 1-hop, and return {1}\{-1\} if there is no such node.

With these primitives, we can re-construct the entire graph. We can find all the node IDs in the hash table. Then by carrying out 1-hop successor queries or 1-hop precursor queries for each node, we can find all the edges in the graph. The weight of the edges can be retrieved by the edge queries. As the graph is reconstructed, all kinds of queries and algorithms can be supported. In fact, in many situations, it is not necessary to re-construct the entire graph. We can just follow the specific algorithm and use the primitives to get the information when needed. Therefore, The data structure DSDS needs to support these 33 query primitives.

IV GSS: Basic Version

In this section, we describe a conceptually simple scheme to help illustrate intuition and benefit of our approach. The full approach, presented in Section V, is designed with more optimizations. As stated above, to produce a graph stream summarization, we first need to design a graph sketch Gh=(Vh,Eh)G_{h}=(V_{h},E_{h}) for the streaming graph GG. Initially, we use the same strategy as TCM to generate the graph sketch. We choose a hash function H()H(\cdot) with value range [0,M)[0,M), then GhG_{h} is generated as following:

  1. 1.

    Initialization: Initially, Vh=V_{h}=\varnothing, and Eh=E_{h}=\varnothing.

  2. 2.

    Edge Insertion: For each edge e=(s,d)e=(s,d) in EE with weight ww, we compute hash values H(s)H(s) and H(d)H(d). If either node with ID H(s)H(s) or H(d)H(d) is not in VhV_{h} yet, we insert it into VhV_{h}. Then we set H(e)=H(s),H(d)H(e)=\overrightarrow{H(s),H(d)}. If H(e)H(e) is not in EhE_{h}, we insert H(e)H(e) into EhE_{h} and set its weight w(H(e))=ww(H(e))=w. If H(e)H(e) is in EhE_{h} already, we add ww to the weight.

GhG_{h} is empty at the beginning and expands with every data item in the graph stream. We can store H(v),v\langle H(v),v\rangle pairs with hash tables to make this mapping procedure reversible. This needs O|V|O|V| additional memory, as |V||E||V|\leqslant|E|, the overall memory requirement is still within O(|E|)O(|E|).

Fig. 2: A sample map function
Example 2

A graph sketch GhG_{h} for the streaming graph GG in Figure 1 is shown in Figure 2. The value range of the hash function H()H(\cdot) is [0,32)[0,32). In the example, nodes cc and gg are mapped to the same node with ID 55 in GhG_{h}. In GhG_{h}, the weight of edge (2,5)(2,5) is 66, which is the summary of the weight of edge (a,c)(a,c) and edge (a,g)(a,g) in GG.

Refer to caption
(a) Edge Query
Refer to caption
(b) 1-hop Successor Query
Refer to caption
(c) 1-hop Precursor Query
Fig. 3: Influence of M on Accuracy

Obviously, the size of the value range of the map function H()H(\cdot), which we represent with MM, will significantly influence the accuracy of the summarization, especially in the 1-hop successor / precursor query primitives. In a uniform mapping with the hash function, each node in GG has the probability 1M\frac{1}{M} to collide with another, which means they are mapped to the same node in GhG_{h}. When there are |V||V| nodes, the probability that a node vv does not collide with any other nodes is (11M)|V|1e|V|1M{(1-\frac{1}{M})}^{|V|-1}\approx{e}^{\frac{|V|-1}{M}}. In the 1-hop successor / precursor queries, if vv collides with others, the query result about it will definitely have errors. Therefore we have to use a large MM to maximize this probability.

Figure 3 shows the theoretical results of the relationship between MM and the accuracy of the query primitives . The results are computed according to analysis in Section VI-B. (In the figure of the edge query, d1d_{1} and d2d_{2} means the in-degree of the source node and the out-degree of the destination node of the queried edge. In the figure of the 1-hop successor / precursor query, dind_{in} and doutd_{out} means the in-degree and the out-degree of the queried node, respectively). The figure shows that we have to use a large MM to achieve high accuracy in the query primitives, which is not possible in the prior works. According to Figure 3, only when M|V|>200\frac{M}{|V|}>200, the accuracy ratio is larger than 80%80\% in 1-hop successor / precursor queries. When M|V|1\frac{M}{|V|}\leq 1, the accuracy ratio falls down to nearly 00, which is totally unacceptable.

Both TCM and the gMatrix resort to an adjacency matrix to represent GhG_{h}. In this case, the matrix rank mm equals to MM, i.e, the value range of the map function. To keep the memory usage of the graph sketch within O(|E|)O(|E|) (Condition 2 in Definition 3), mm must be less than E\sqrt{E}, that means m=M<E|V|m=M<\sqrt{E}\ll|V| for a sparse streaming graph. According to our theoretical analysis22 2 The detailed analyses are given in Section VI-B in Figure 3, the query results’ accuracy is quite low in them. Our experiments in Section VII also confirm the theoretical analysis.

Fig. 4: A sample of the basic version of data structure

Considering the above limitations, we design a novel data structure for graph stream summarization, called GSS.

Definition 5

GSS: Given a streaming graph G=(V,E)G=(V,E), we have a hash function H()H(\cdot) with value range [0,M)[0,M) to map each node vv in graph GG to node H(v)H(v) in graph sketch GhG_{h}. Then we use the following data structure to represent the graph sketch GhG_{h}:

  1. 1.

    GSSGSS consists of a size m×mm\times m adjacency matrix XX and an adjacency list buffer BB for left-over edges.

  2. 2.

    For each node H(v)H(v) in sketch graph GhG_{h}, we define an address h(v)(0h(v)m)h(v)(0\leqslant h(v)\leqslant m) and a fingerprint f(v)(0f(v)F)f(v)(0\leqslant f(v)\leqslant F) where M=m×FM=m\times F and h(v)=H(v)Fh(v)=\lfloor\frac{H(v)}{F}\rfloor, f(v)=H(v)%Ff(v)=H(v)\%F.

  3. 3.

    Each edge H(s),H(d)\overrightarrow{H(s),H(d)} in the graph sketch GhG_{h} is mapped to a bucket in the row h(s)h(s), column h(d)h(d) of the matrix XX. We record [f(s),f(d),w][\langle f(s),f(d)\rangle,w] in the corresponding bucket of the matrix, where ww is the edge weight and f(s)f(s), f(d)f(d) are fingerprints of the two endpoints.

  4. 4.

    Adjacency list buffer BB records all left-over edges in GhG_{h}, whose expected positions in the matrix XX have been occupied by other previous inserted edges already.

When implementing a GSS for a graph stream, in order to satisfy the O(|E|)O(|E|) memory cost requirement, we usually set m=α×|E|m=\alpha\times\sqrt{|E|}, where α\alpha should be a constant approximate to 11. To achieve high accuracy, we set M|V|M\gg|V|. This can be achieved by setting large FF, in other words, using long fingerprints. When the memory is not sufficient, we can also set smaller MM with smaller mm and FF, but this will decrease the accuracy.

Example 3

The basic version of GSS to store GhG_{h} in Figure 2 is shown in Figure 4. Here we set F=8F=8. The nodes in the original streaming graph and their corresponding H(v)H(v), h(v)h(v) and f(v)f(v) are shown in the table. In this example, edge 2,10\overrightarrow{2,10} and edge 5,18\overrightarrow{5,18} in GhG_{h} are stored in the buffer because of collisions with other edges.

We discuss the insertion and primitive query operations over GSS as follows:

Edge Updating: When a new item (s,d,t,w)(s,d;t;w) comes in the graph stream SS, we map it to an edge H(s),H(d)\overrightarrow{H(s),H(d)} with weight ww in graph sketch GhG_{h}. Then we find the bucket in row h(s)h(s), column h(d)h(d). If the bucket is empty, we store the fingerprints pair f(s),f(d)\langle f(s),f(d)\rangle together with the edge weight ww in the bucket. If it is not empty, we compare the fingerprint pair of this edge with the fingerprint pair f(s),f(d)\langle f(s^{\prime}),f(d^{\prime})\rangle that is in the bucket already. If they are same, we add the weight ww to the existing one; otherwise, it means this bucket has been occupied by other edges, and we store edge H(s),H(d)\overrightarrow{H(s),H(d)} in the adjacency list in the buffer BB. We call this kind of edges as left-over edges.

Graph Query Primitives: The three primitives (defined in Definition 4) are all supported with our proposed data structure GSS.

Edge Query: Given an edge query e=s,de=\overrightarrow{s,d}, we work as follows. We check the bucket in row h(s)h(s), column h(d)h(d) in the matrix. Let f(s),f(d)\langle f(s^{\prime}),f(d^{\prime})\rangle be the fingerprint pair stored at the bucket. If f(s),f(d)\langle f(s^{\prime}),f(d^{\prime})\rangle equals to the the fingerprint pair f(s),f(d)\langle f(s),f(d)\rangle of edge s,d\overrightarrow{s,d}, we return the weight in the bucket. Otherwise we search the buffer BB for edge H(s),H(d)\overrightarrow{H(s),H(d)} using the adjacency list. If we cannot find it in the matrix XX or in the buffer BB, we return 1-1, i.e. reporting that the edge e=s,de=\overrightarrow{s,d} does not exists.

11-hop Successor Query: To find the 1-hop successors of node vv, we work as follows. First, we search all buckets in row h(v)h(v) of the matrix XX. If a bucket in row h(v)h(v) and column cc has a fingerprint pair f(v),f(vs)\langle f(v),f(v_{s})\rangle, we add node H(vs)=c×F+f(vs)H(v_{s})=c\times F+f(v_{s}) to the 1-hop successors set SSSS. After that, we also need to search the buffer area to find all edges with source node H(v)H(v), and add its destination node to the 1-hop successors set SS. We return 1-1 if we find no result, i.e., |SS|=0|SS|=0. Otherwise, for each H(s)H(s) in successors set SSSS, we obtain the original node IDs by accessing the hash table.

11-hop Precursor Query: To find the 1-hop precursors of node vv, we have the analogue operations with 11-hop Successor Query if we switch the columns and the rows in the matrix XX. The details are omitted due to space limit.

In GSS, we store edges with different source nodes in GhG_{h} in one row of the matrix, because the graph is sparse and each node is usually connected to very few edges. We can use fingerprints to distinguish them. For example, edge 15,28\overrightarrow{15,28} and edge 10,15\overrightarrow{10,15} are all stored in row 11, but they have different source node fingerprints, namely 22 and 77, thus we know exactly which nodes they are from. It is similar in columns. Fingerprints also help us to distinguish edges when they are mapped into the same bucket. This enables us to apply a map function with a much larger value range, and generate a much larger graph sketch with the same size of matrix as TCM. With a 4×44\times 4 matrix as in Figure 2, TCM can only support a map function with M=4M=4 , and the number of nodes in the graph sketch will be no more than 44, thus the accuracy will he much poorer.

V GSS: Augmented Algorithm

As we know, GSS has two parts: a size m×mm\times m matrix XX and an adjacency list buffer BB for left-over edges. Obviously, we only need O(1)O(1) time to insert an edge into XX, but the linear time O(|B|)O(|B|) if the edge must goto the buffer BB, where |B||B| represents the number of all left-over edges. Therefore |B||B| both influences the memory and time cost. In this section, we design several solutions to reduce the size of buffer BB.

V-A Square Hashing

In the basic version, an edge is pushed into buffer BB if and only if its mapped position in the matrix XX has been occupied. The most intuitive solution is to find another bucket for it. Then where to find an empty bucket? We further notice the skewness in node degrees. In the real-world graphs, node degrees usually follow the power law distribution. In other words, a few nodes have very high degrees, while most nodes have small degrees. Consider a node vv that has AA out-going edges in the graph sketch GhG_{h}. For a m×mm\times m adjacency matrix XX in GSS (see Definition 5), there are at least AmA-m edges that should be inserted into buffer BB, as these AA edges must be mapped to the same row (in XX) due to the same source vertex vv. These high degree nodes lead to crowed rows and result in most left-over edges in buffer BB. On the other hand, many other rows are uncrowded. We have the same observation for columns of matrix XX. Is it possible to make use of the unoccupied positions in uncrowded rows/columns? It is the motivation of our first technique, called square hashing.

For each node with ID H(v)=h(v),f(v)H(v)=\langle h(v),f(v)\rangle in GhG_{h}, we compute a sequence of hash addresses {hi(v)|1ir}(0hi(v)<m)\{h_{i}(v)|1\leqslant i\leqslant r\}(0\leqslant h_{i}(v)<m) for it. Edge H(s),H(d)\overrightarrow{H(s),H(d)} is stored in the first empty bucket among the r×rr\times r buckets with addresses

{(hi(s),hj(d))|(1ir,1jr)}\{(h_{i}(s),h_{j}(d))|(1\leqslant i\leqslant r,1\leqslant j\leqslant r)\}

where hi(s)h_{i}(s) is the row index and hj(d)h_{j}(d) is the column index. We call these buckets mapped buckets for convenience. Note that we consider row-first layout when selecting the first empty bucket.

Example 4

An example of square hashing is shown in Figure 5. The inserted edge is mapped to 99 buckets, and the first 2 with address (h1(s),h1(d))(h_{1}(s),h_{1}(d)) and (h1(s),h2(d))(h_{1}(s),h_{2}(d)) have been already occupied. Therefore the edge is inserted in the third mapped bucket. In the bucket, we store the weight, the fingerprint pair, together with an index pair 1,3\langle 1,3\rangle which indicates the position of this bucket in the mapped buckets sequence. We will talk about the use of index pair later.

Fig. 5: The square hashing

The following issue is how to generate a good hash address sequence {hi(v)|1ir}\{h_{i}(v)|1\leq i\leq r\} for a vertex vv. There are two requirements:

Independent: For two nodes v1v_{1} and v2v_{2}, we use PP to represent the probability that 1ir,hi(v1)=hi(v2)\forall 1\leq i\leq r,h_{i}(v_{1})=h_{i}(v_{2}). Then we have P=i=1rPr(hi(v1)=hi(v2))P=\prod_{i=1}^{r}Pr(h_{i}(v_{1})=h_{i}(v_{2})). In other words, the randomness of each address in the sequence will not be influenced by others. This requirement will help to maximize the chance that an edge finds an empty bucket among the r×rr\times r mapped buckets.

Reversible: Given a bucket in row RR and column CC and the content in it, we are able to recover the representation of the edge ee in the graph sketch GhG_{h}: H(s),H(d)\overrightarrow{H(s),H(d)}, where ee is the edge in that bucket. This property of indexing is needed in the 1-hop successor query and the 1-hop precursor query. As in these queries, we need to check the potential buckets to see if they contain edges connected to the queried node vv and retrieve the other end point in each qualified bucket.

To meet the above requirements, we propose to use linear congruence method[22] to generate a sequence of rr random values {qi(v)|1ir}\left\{q_{i}(v)|1\leqslant i\leqslant r\right\} with f(v)f(v) as seeds. We call this sequence the linear congruential (LR) sequence for convenience. The linear congruence method is as following: select a timer aa, small prime bb and a module pp, then

{q1(v)=(a×f(v)+b)%pqi(v)=(a×qi1(v)+b)%p,(2ir)\left\{\begin{aligned} q_{1}(v)&=(a\times f(v)+b)\%p\\ q_{i}(v)&=(a\times q_{i-1}(v)+b)\%p,(2\leqslant i\leqslant r)\\ \end{aligned}\right. (1)

By choosing aa, bb and pp carefully, we can make sure the cycle of the sequence we generate is much larger than rr, and there will be no repetitive numbers in the sequence [22]. Then we generate a sequence of hash addresses as following:

{hi(v)|hi(v)=(h(v)+qi(v))%m,1ir}\left\{h_{i}(v)|h_{i}(v)=(h(v)+q_{i}(v))\%m,1\leqslant i\leqslant r\right\} (2)

When storing edge H(s),H(d)\overrightarrow{H(s),H(d)} in the matrix, besides storing the pair of fingerprints and the edge weight, we also store an index pair (is,id)(i_{s},i_{d}), supposing that the bucket that contains this room has an address (his(s),hid(d))(h_{i_{s}}(s),h_{i_{d}}(d)). As the length of the sequence, rr, is small, the length of each index will be less than 44 bits. Therefore storing such a pair will cost little.

Note that the hash sequence {qi(v)|1ir}\left\{q_{i}(v)|1\leqslant i\leqslant r\right\} generated by the linear congruence method are both independent and reversible. The independence property has been proved in [8]. We show how to recover the original hash value H(v)H(v) based on the f(v)f(v), hi(v)h_{i}(v) and the index ii as follows. First, we compute the LR sequence {qi(v)}\{q_{i}(v)\} with f(v)f(v) following equation 4. Second we use the equation (h(v)+qi(v))%m=hi(v)(h(v)+q_{i}(v))\%m=h_{i}(v) to compute the original hash address h(v)h(v). As h(v)<mh(v)<m, the equation has unique solution. At last we use H(v)=h(v)×F+f(v)H(v)=h(v)\times F+f(v) to compute H(v)H(v). Given a bucket in the matrix, the fingerprint pair (f(s),f(d))(f(s),f(d)) and the index pair (is,id)(i_{s},i_{d}) are all stored in it, and we have his(s)=Rh_{i_{s}}(s)=R, hid(d)=Ch_{i_{d}}(d)=C, where RR and CC are the row index and the column index of the bucket in the matrix, respectively. Therefore we can retrieve both H(s)H(s) and H(d)H(d) as above.

Fig. 6: A sample of the modified version of data structure
Example 5

An example of the modified version is shown in Fig. 6. In the matrix we stored GhG_{h} in Fig. 2, which is a compressed graph of GG in Fig.1. In this example we set F=8F=8, m=4m=4, r=2r=2, and the equation in the linger congruence method is

{q1(v)=(5×f(v)+3)%8qi(v)=(5×qi1(v)+3)%8,(2ir)\left\{\begin{aligned} q_{1}(v)&=(5\times f(v)+3)\%8\\ q_{i}(v)&=(5\times q_{i-1}(v)+3)\%8,(2\leqslant i\leqslant r)\\ \end{aligned}\right. (3)

Compared to the basic version, in the modified version all edges are stored in the matrix, and the number of memory accesses we need to find an edge in the matrix is within 22=42^{2}=4. In fact in the example we only need one memory access to find most edges, and 22 for a few ones.

In the following, we illustrate the four basic operators in this data structure GSS.

Edge Updating: When a new item (s,d,t,w)(s,d,t;w) comes in the graph stream SS, we map it to edge H(s),H(d)\overrightarrow{H(s),H(d)} in the graph sketch GhG_{h} with weight ww. Then we compute two hash address sequences {hi(s)}\{h_{i}(s)\} and {hi(d)}\{h_{i}(d)\} and check the r2r^{2} mapped buckets with addresses {(hi(s),hj(d))|1ir,1jr}\{(h_{i}(s),h_{j}(d))|1\leqslant i\leqslant r,1\leqslant j\leqslant r\} one by one. For a bucket in row his(s)h_{i_{s}}(s) and column hid(d)h_{i_{d}}(d), if it is empty, we store the fingerprint pair (f(s),f(d))(f(s),f(d)) and the index pair (is,id)(i_{s},i_{d}) and weights ww in it, and end the procedure. If it is not empty, we check the fingerprint pair (f(s),f(d))(f(s^{\prime}),f(d^{\prime})) and the index pair (is,id)(i_{s}^{\prime},i_{d}^{\prime}) stored in the bucket. If the fingerprint pair and the index pair are all equal to the corresponding pairs of the new inserted edge H(s),H(d)\overrightarrow{H(s),H(d)}, we add ww to the weights in it, and end the procedure. Otherwise it means this bucket has been occupied by other edges and we consider other hash addresses following the hash sequence. If all r2r^{2} buckets have been occupied, we store edge H(s),H(d)\overrightarrow{H(s),H(d)} with weight ww in the buffer BB, like the basic version of GSS.

Graph Query Primitives: The three graph query primitives are supported in the modified data structure as follows:

Edge Query: When querying an edge e=s,de=\overrightarrow{s,d}, we map it to edge H(s),H(d)\overrightarrow{H(s),H(d)} in the graph sketch, and use the same square hashingmethod to find the r2r^{2} mapped buckets and check them one by one. Once we find a bucket in row his(s)h_{i_{s}}(s) and column hid(d)h_{i_{d}}(d) which contains the fingerprint pair (f(s),f(d))(f(s),f(d)) and the index pair (is,id)(i_{s},i_{d}), we return its weight as the result. If we find no results in the r2r^{2} buckets, we search the buffer for edge H(s),H(d)\overrightarrow{H(s),H(d)} and return its weights. If we still can not find it, we return 1-1.

1-hop Successor Query: to find the 1-hop successors of node vv, we map it to node H(v)H(v) in GhG_{h}. Then we compute its hash address sequence hi(v){h_{i}(v)} according to H(v)H(v), and check the rr rows with index hi(v),(1ir)h_{i}(v),(1\leqslant i\leqslant r). If a bucket in row his(v)h_{i_{s}}(v), column CC contains fingerprint pair ((f(v),f(x))CLOSE((f(v),f(x)) and index pair (is,id)(i_{s},i_{d}) where f(x)f(x) is any integer in range [0,F)[0,F) and idi_{d} is any integer in range [1,r][1,r], we use f(x)f(x), idi_{d} and CC to compute H(x)H(x) as stated above. Then we add H(x)H(x) to the 1-hop successor set SSSS. After searching the rr rows, we also need to check the buffer to see if there are any edges with source node H(v)H(v) and add their destination node to SSSS. We return 1-1 if we find no result, otherwise we obtain the original node IDs from SSSS by accessing the hash table H(v),v\langle H(v),v\rangle.

1-hop Precursor Query: to answer an 1-hop precursor query, we have the analogue operations with 11-hop Successor Query if we switch the columns and the rows in the matrix XX. The details are omitted due to space limit.

After applying square hashing, the edges with source node H(v)H(v) in GhG_{h} are on longer stored in a single row, but spread over rr rows with addresses hi(v)(1ir)h_{i}(v)(1\leqslant i\leqslant r). Similarly, edges with destination node H(v)H(v) are stored in the rr different columns. These rows or columns are shared by the edges with different source nodes or destination nodes. The higher degree a node has, the more buckets its edges may take. This eases the congestion brought by skewness in node degrees. Moreover, as each bucket has multiple mapped buckets, it has higher probability to find an empty one. Obviously, square hashing will reduce the number of left-over edges.

V-B Further Improvements

There are some other improvements which can be implemented to GSS.

V-B1 Mapped Buckets Sampling

In the modified version of GSS, each edge has r2r^{2} mapped buckets. We usually set rr to integers from 44 to 1616. When the skewness of node degrees is serious, rr can be larger. If we check all the r2r^{2} buckets when inserting an edge, it will be time consuming. To improve the updating speed, which is very important for graph stream summarization, we can use a sampling technique to decrease the time cost. Instead of check all the r2r^{2} buckets, we select kk buckets as a sample from the mapped buckets, we call these buckets candidate buckets for short. For each edge we only check these kk buckets in updating and query, and the operations are the same as above. The method to select these kk buckets for an edge ee is also a linear congruence method. We add the fingerprint of the source node and the destination node of ee to get a seed seed(e)seed(e), then we compute a kk length sequence as

{q1(e)=(a×seed(e)+b)%pqi(e)=(a×qi1(e)+b)%p,(2ik)\left\{\begin{aligned} q_{1}(e)&=(a\times seed(e)+b)\%p\\ q_{i}(e)&=(a\times q_{i-1}(e)+b)\%p,(2\leqslant i\leqslant k)\\ \end{aligned}\right. (4)

where aa, bb and pp are the same integers used above. We choose the kk buckets with address

{(hqi(e)r%r(s),h(qi(e)%r)(d))|1ik}\centering\left\{(h_{\left\lfloor\frac{q_{i}(e)}{r}\right\rfloor\%r}(s),h_{(q_{i}(e)\%r)}(d))|1\leqslant i\leqslant k\right\}\@add@centering (5)

{hi(s)}\{h_{i}(s)\} and {hi(d)}\{h_{i}(d)\} are the hash address sequence of the source node and the destination node, respectively.

V-B2 Multiple Rooms

When the memory is sufficient, we do not need to use multiple matrices to increase accuracy as TCM, as the accuracy is already very high. Instead, in order to further decrease the buffer size, we can separate each bucket in the matrix into ll segments, and each segments contains an edge, including the weight, the fingerprint pair and the index pair. We call each segment a room for convenience. When performing the basic operators, we use the same process as above the find the buckets we need to check, and search all the rooms in them to find qualified edges or empty rooms.

However, when the rooms in each bucket are stored separately, the speed will probably decrease, as we can not fetch the ll rooms in one memory access in most cases, and multiple memory accesses increase the time cost. As shown in Fig. 7, we separate the bucket into 33 area: the index area, the fingerprint area, and the weight area. Each area contains the corresponding parts of the ll rooms. When we check this bucket to find certain edges, we can first check all the index pairs. If we find a matched index pair, we check the corresponding fingerprint pair, and if the fingerprint pair is also matched, we fetch the corresponding weights. If we do not find any matched index pair, we can just move on and do not need to check the fingerprint pairs any more. As the index pairs are very small, usually no more than 11 byte, we can fetch all the index pairs in one memory access. This will omit a lot of unnecessary memory accesses.

Fig. 7: Bucket Separation

VI Analysis

VI-A Memory and Time Cost Analysis

As stated above, GSS has O(|E|)O(|E|) memory cost and constant update speed. The memory cost of GSS is O(|Eh|+|B|)O(|E_{h}|+|B|), to be precise, where |Eh||E_{h}| is the number of edges in the graph sketch GhG_{h} and |B||B| is the size of buffer. When we use hash table to store the original ID, additional O(|V|)O(|V|) memory is needed, but the overall memory cost is still O(|E|)O(|E|). The update time cost is O(k+|B||Eh||B|)O(k+\frac{|B|}{|E_{h}|}|B|), where kk is the number of sampled buckets and is a small constant. When an edge is stored in the matrix, we only need to check at most kk candidate buckets, which takes O(k)O(k) time. Each edge has probability |B||Eh|\frac{|B|}{|E_{h}|} to be stored in the buffer. When it is stored in the buffer, the update takes additional O(|B|)O(|B|) time, as the buffer is an adjacency list. In implementations the buffer stores 00 edges in most cases, which will be shown in section VI-D and VII-G. Therefore |B||Eh||B|\frac{|B|}{|E_{h}|}|B| is also a small constant. When it is necessary to store the ID of nodes in applications, one insertion to the hash table is needed, which also takes constant time. Overall, the update time cost is O(1)O(1).

The time cost of queries is based on the algorithms we use. We consider the time cost of the operators as an evaluation. The time cost of the edge query operator is the same as the update, and the time cost of the 1-hop successor query and 1-hop precursor query is O(rm+|B|)O(rm+|B|), where mm is the side length of the matrix and rr is the length of the hash address sequence.

VI-B Accuracy Analysis

In this part we evaluate the accuracy of GSS. Before we analyze the probability of errors, we first propose the following theorem:

Theorem 1

The storage of the graph sketch GhG_{h} in the data structure of GSS is accurate. Which means for any edge e1=H(s1),H(d1)e_{1}=\overrightarrow{H(s_{1}),H(d_{1})} and e2=H(s2),H(d2)e_{2}=\overrightarrow{H(s_{2}),H(d_{2})} in GhG_{h}, the weights of them will be added up if and only if H(s1)=H(s2),H(d1)=H(d2)H(s_{1})=H(s_{2}),H(d_{1})=H(d_{2}).

As the buffer is an adjacency list that stores edges in GhG_{h} accurately, we only need to check the matrix. If we want to prove the storage of the graph sketch is accurate, we need to prove that if such collision happens to e1e_{1} and e2e_{2}, we have e1=e2e_{1}=e_{2} in GhG_{h}, in other words, H(s1)=H(s2),H(d1)=H(d2)H(s_{1})=H(s_{2}),H(d_{1})=H(d_{2}) .We assume that the bucket contains the wights of e1e_{1} and e2e_{2} is in row RR and column CC in the matrix. Obviously e1e_{1} and e2e_{2} must have the same fingerprint pair, otherwise it will be easy for us to differentiate them. With the same fingerprints, these two edges will produce the same LR sequences {q(s)}\{q(s)\} and {q(d)}\{q(d)\}. Moreover, this bucket must have the same index pair for these two edges, and we represent this pair with (c1,c2)(c_{1},c_{2}). Then we have

{(h(s1)+qc1(s1))%m=R((h(s2)+qc1(s2)))%m=Rqc1(s1)=qc1(s2)\left\{\begin{aligned} &(h(s_{1})+q_{c_{1}}(s_{1}))\%m=R\\ &((h(s_{2})+q_{c_{1}}(s_{2})))\%m=R\\ &q_{c_{1}}(s_{1})=q_{c_{1}}(s_{2})\\ \end{aligned}\right. (6)

and

{(h(d1)+qc2(d1))%m=C((h(d2)+qc2(d2)))%m=Cqc2(d1)=qc2(d2)\left\{\begin{aligned} &(h(d_{1})+q_{c_{2}}(d_{1}))\%m=C\\ &((h(d_{2})+q_{c_{2}}(d_{2})))\%m=C\\ &q_{c_{2}}(d_{1})=q_{c_{2}}(d_{2})\\ \end{aligned}\right. (7)

With these equations, we can get that h(d1)=h(d2)h(d_{1})=h(d_{2}), h(s1)=h(s2)h(s_{1})=h(s_{2}) when 0h(s1),h(s2),h(d1),h(d2)<m0\leqslant h(s_{1}),h(s_{2}),h(d_{1}),h(d_{2})<m. With the same fingerprint pair and hash values, we have H(s1)=H(s2)H(s_{1})=H(s_{2}), H(d1)=H(d2)H(d_{1})=H(d_{2}). e1e_{1} and e2e_{2} are the same edge in GhG_{h}. Therefore the storage of GhG_{h} is accurate.

This theorem means we only need to consider the procedure of mapping GG to GhG_{h}, as all errors happen in this procedure. We use P^\hat{P} to represent the probability of the following event:

Definition 6

Edge Collision: An edge collision means that given an edge ee, there is at least one ee^{\prime} in GG and eee^{\prime}\neq e which satisfies H(e)=H(e)H(e)=H(e^{\prime}) in the compressed graph GhG_{h}.

We set P=1P^P=1-\hat{P}, and PP is the main component of the error rate of all the 33 graph query primitives.

In the edge query, PP is just the correct rate. In the 1-hop successor query for a node vv, the correct rate is P|V|d{P}^{|V|-d}, where |V||V| is the number of nodes in GG, and dd is the out-degree of the queried node. Because we will get a correct answer if and only if for each vv^{\prime} in GG which is not a 1-hop successor of vv, (v,v)(v,v^{\prime}) does not collide with any existing edges, and the probability of such an event is PP. It is the same in the 1-hop precursor query. Therefore we need to compute PP to evaluate the accuracy of GSS.

VI-C Collision Rate

Now we show the probability that an edge ee suffers from edge collision, P^\hat{P}. For e=s,de=\overrightarrow{s,d} in GG, we assume there are DD edges with source node ss or destination node dd in GG besides ee, and there are totally |E||E| edges in GG. We represent the size of the value range of the map function H()H(\cdot) with MM.

For an edge share no common endpoints with ee , it will collide with ee when both its source node and destination node collide with the corresponding node of ee. The probability that it collides with ee in map function H()H(\cdot) is:

p1=1M2p_{1}=\frac{1}{M^{2}} (8)

The probability that all the |E|D|E|-D edges have no collisions with ee is

Pr1=(1p1)|E|DPr_{1}={(1-p_{1})}^{|E|-D} (9)

For those DD edges connected to ee, as one of the two end points is the same, the probability that such an edge has a collision with ee is

p2=1Mp_{2}=\frac{1}{M} (10)

The probability that all the DD edges have no collisions with ee is

Pr2=(1p2)DPr_{2}={(1-p_{2})}^{D} (11)

Therefore the correct rate of ee, in other words, all the |E||E| edges do not have collisions with ee in mapping is

P\displaystyle P =Pr1×Pr2\displaystyle=Pr_{1}\times Pr_{2} (12)
=((1p1)|E|D)×((1p2)D)\displaystyle=({(1-p_{1})}^{|E|-D})\times({(1-p_{2})}^{D})
=ep1×(|E|D)×ep2×D\displaystyle=e^{-p_{1}\times(|E|-D)}\times e^{-p_{2}\times D}
=e|E|DM2×eDM\displaystyle=e^{-\frac{|E|-D}{M^{2}}}\times e^{-\frac{D}{M}}
=e|E|+(M1)×DM2\displaystyle=e^{-\frac{|E|+(M-1)\times D}{M^{2}}}

And P^=1P\hat{P}=1-P. In GSS we have M=m×FM=m\times F, where mm is the length of the matrix, and FF is the maximum size of the fingerprints. The above correct rate is usually very high in applications. For example, suppose that the fingerprints we use are 88-bit, in other words, F=256F=256, and when querying an edge ee, we have |E|=5×105|E|=5\times 10^{5},D=200D=200. We use a matrix with side length m=1000m=1000. Then the correct rate of this edge query is e0.00078=0.9992e^{-0.00078}=0.9992. On the other hand, in TCM the accuracy analysis is the same as GSS  but we have M=mM=m. This lead to the difference on accuracy with the same size of matrix. With the same matrix size, TCM only has a probability of 0.4970.497 to get a correct weight for ee.

VI-D Buffer Size Analysis

After all the improvements, the buffer in GSSis very small. The mathematical expression of the buffer size is very complicated and is influenced by many details of the graph. Therefore we give an expression of the probability that a new edge ee becomes a left-over edge, which means inserted into the buffer, as a measurement. Assuming that there are already NN different edges in the graph stream, and among them DD edges have common source node or common destination node with ee. The length of the matrix is mm, and each bucket in the matrix has ll rooms. For each node we compute a hash address sequence with length rr. For each edge we choose kk candidate buckets among the r2r^{2} mapped buckets. Then the probability that ee becomes a left-over edge is: For each candidate bucket of ee, as the NDN-D non-adjacent edges are randomly inserted into the matrix with area m2m^{2}, the probability that there are a1a_{1} non-adjacent edges inserted into it is:

p1(a1)\displaystyle p_{1}(a_{1}) =(NDa1)×(1m2)a1×(11m2)NDa1\displaystyle=\binom{N-D}{a_{1}}\times{(\frac{1}{m^{2}})}^{a_{1}}\times{(1-\frac{1}{m^{2}})}^{N-D-a_{1}} (13)
=(NDa1)×(1m2)a1×eNDa1m2\displaystyle=\binom{N-D}{a_{1}}\times{(\frac{1}{m^{2}})}^{a_{1}}\times{e}^{-\frac{N-D-a_{1}}{m^{2}}}

As the DD adjacent edges are randomly inserted in an area of r×mr\times m (rr rows or rr columns in the matrix), the probability that there are a2a_{2} adjacent edges inserted into this bucket is:

p2(a2)\displaystyle p_{2}(a_{2}) =(Da2)×(1r×m)a2×(11r×m)Da2\displaystyle=\binom{D}{a_{2}}\times{(\frac{1}{r\times m})}^{a_{2}}\times{(1-\frac{1}{r\times m})}^{D-a_{2}} (14)
=(Da2)×(1r×m)a2×eDa2r×m\displaystyle=\binom{D}{a_{2}}\times{(\frac{1}{r\times m})}^{a_{2}}\times{e}^{-\frac{D-a_{2}}{r\times m}}

The probability that there are already nn edges inserted into this bucket is:

p(n)\displaystyle p(n) =a=0np1(a)×p2(na)\displaystyle=\sum_{a=0}^{n}p_{1}(a)\times p_{2}(n-a) (15)

The probability that there are less than ll edges inserted into this bucket is:

Pr=n=0l1p(n)\displaystyle Pr=\sum_{n=0}^{l-1}p(n) (16)
=n=0l1a=0np1(a)×p2(na)\displaystyle=\sum_{n=0}^{l-1}\sum_{a=0}^{n}p_{1}(a)\times p_{2}(n-a)
=n=0l1a=0n(NDa)(Dna)(1m2)a(1rm)nae(NDam2+Dn+arm)\displaystyle=\sum_{n=0}^{l-1}\sum_{a=0}^{n}\binom{N\!-\!D}{a}\binom{D}{n\!-\!a}{(\frac{1}{m^{2}})}^{a}{(\frac{1}{rm})}^{n\!-\!a}{e}^{-(\frac{N\!-\!D\!-\!a}{m^{2}}+\frac{D\!-\!n\!+\!a}{rm})}

This is also the lower bound that the bucket is still available for ee. The probability that ee can not be inserted into the matrix is the probability that all the kk candidate buckets are not available, which is:

P=(1Pr)k\displaystyle P=(1-Pr)^{k} (17)

where

Pr=n=0l1a=0n(NDa)(Dna)(1m2)a(1rm)nae(NDam2+Dn+arm)\displaystyle Pr=\sum_{n=0}^{l-1}\sum_{a=0}^{n}\binom{N\!-\!D}{a}\binom{D}{n\!-\!a}{(\frac{1}{m^{2}})}^{a}{(\frac{1}{rm})}^{n\!-\!a}\!\!{e}^{-(\frac{N\!-\!D\!-\!a}{m^{2}}+\frac{D\!-\!n\!+\!a}{rm})} (18)

Notice that this is an upper bound as we ignore collisions in the map procedure from GG to GhG_{h}. This probability is rather small. For example if N=1×106N=1\times 10^{6}, D=104D=10^{4}, we still set the side length of the matrix to w=1000w=1000, and set r=8r=8, l=3l=3, k=8k=8, the upper bound probability of insertion failure is only 0.0020.002. Experiments show that when the size of matrix is nearly equal to the number of edges, there will be almost no edges inserted into the buffer.

VII Experimental Evaluation

In this section, we show our experimental studies of GSS. We compare GSS with TCM on the three graph query primitives: edge query , 1-hop successor query, 1-hop precursor query (VII-D) and two compound queries, node queries (VII-E) and reachability queries (VII-F). We also evaluate the size of buffer (VI-D)and update speed of GSS (VII-H). Then we further compare GSS with the state-of-the-art graph processing algorithms on triangle counting and subgraph matching VII-I.

All experiments are performed on a server with dual 6-core CPUs (Intel Xeon CPU E5-2620 @2.0 GHz, 24 threads) and 62 GB DRAM memory, running Ubuntu. All algorithms including GSS and TCM are implemented in C++.

VII-A Data Sets

We choose three real world data sets. Details of three data sets are described as follows:

1)email-EuAll 33 3 http://snap.stanford.edu/data/email-EuAll.html.This data set is communication network data generated using email data from a large European research institution for a period of 18 months. Each node in the directed graph corresponds to an email address. Each edge between node src and dst represents src sent at least one email to dst. The directed graph contains 265214 nodes and 420045 edges. We use the Zipfian distribution to add the weight to each edge and the edge weight represents the appearance times in the stream.

2)cit-HepPh44 4 http://snap.stanford.edu/data/email-EuAll.html.It is the Arxiv HEP-PH (high energy physics phenomenology) citation graph. If a paper src cites paper dst, the data set contains a directed edge from src to dst. The data set covers 34,546 papers as nodes with 421,578 edges. The edge weights are also added using Zipfian distribution.

3)web-NotreDame 55 5 http://konect.uni-koblenz.de/networks/lkml-reply.It is a web graph collected from the University of Notre Dame. Nodes represent web pages and directed edges represent hyperlinks between pages. The data set contains 325729 nodes and 1497134 edges. We use the Zipfian distribution to generate weights for the edges in the data set, and insert the edges into the data structure one by one to simulate the procedure of real-world incremental updating.

4)lkml-reply66 6 http://konect.uni-koblenz.de/networks/lkml-reply.It is a collection of communication records in the network of the Linux kernel mailing list. It contains 63399 email addresses (nodes) and 1096440 communication records(edges). Each edge is weighted by its frequency in the data set, and has a timestamp indicating the communication time. We feed the data items to the data structure according to their timestamps to simulate a graph stream.

5)Caida-networkflow 77 7 www.caida. org It is the “CAIDA Internet Anonymized Traces 2015 Dataset”. It contains 445440480 communication records (edges) concerning 2601005 different IP addresses (nodes). Each edge is weighted by its frequency in the data set, and has a timestamp indicating the communication time. We feed the data items to the data structure according to their timestamps to simulate a graph stream.

The function we use to cumulate the edge weights is addition. In this case, TCM and GSS only have over-estimations. The codes are open sourced88 8 https://github.com/Puppy95/Graph-Stream-Sketch

VII-B Metrics

In this part we give a definition of the metrics we use in experiments.

Average Relative Error (ARE): ARE measures the accuracy of the reported weights in edge queries and node queries. Given a query qq, the relative error is defined as

RE(q)=f(q)^f(q)1\displaystyle RE(q)=\frac{\hat{f(q)}}{f(q)}-1

where f(q)f(q) and f(q)^\hat{f(q)} are the real answer and the estimated value of qq. When giving a query set, the average relative error (AREARE) is measured by averaging the relative errors over all queries int it. A more accuracy data structure will have smaller AREARE.

Average Precision We use average precision as the evaluation metric in 1-hop successor queries, 1-hop precursor queries and graph pattern matching. Given such a query qq, we use SSSS to represent the accurate set of 1-hop successors / precursors of the queried node vv, and SS^\hat{SS} to represent the set we get by qq. As TCM and GSS、 have only false positives, which means SSSS^SS\subseteq\hat{SS}, we define the precision of qq as:

Precision(q)=|SS||SS^|\displaystyle Precision(q)=\frac{|SS|}{|\hat{SS}|}

Average precision of a query set is the average value of the precision of all queries in it. A more accuracy data structure will have higher Average Precision

True Negative Recall: It measures the accuracy of the reachability query. Because connectives of all edges are kept, there is no false negatives in TCM and GSS, which means if we can travel to dd from ss in the streaming graph, the query result of these data structures will be definitely yes. Therefore in experiments we use reachability query sets Q={q1,q2,,qk}Q=\{q_{1},q_{2},...,q_{k}\} where qiQ\forall q_{i}\in Q, source node ss and destination node dd in qiq_{i} are unreachable. True negative recall is defined as the number of queries reported as unreachable divided by the number of all queries in QQ.

Buffer Percentage: It measures buffer size of GSS. Buffer percentage is defined as the number of edges that the buffer contains divided by the total number of edges in the graph stream.

VII-C Experiments settings

In experiments, we implement two kinds of GSS with different fingerprint sizes: 12 bits and 16 bits, and vary the matrix size. We use fsize to represent the fingerprint size by short. We apply all improvements to GSS, and the parameters are as follows. Each bucket in the matrix contains l=2l=2 rooms. The length of the address sequences is r=16r=16, and the number of candidate buckets for each edge is k=16k=16 (r=8r=8,k=8k=8 for the small data set email-EuAlland cit-HepPh). As for TCMTCM, we apply 44 graph sketches to improve its accuracy, and allow it to use larger memory, because otherwise the gap between it and GSS will be so huge that we can hardly compare them in one figure. In edge query primitives, we allow TCM to use 88 times memory, and in other queries we implement it with 256256 times memory, as its accuracy is too poor in these queries (in web-NotreDame, we implement it with 1616 times memory because of the limitation of the memory of the server). This ratio is the memory used by all the 4 sketches in TCM divided by the memory used by GSS with 16 bit fingerprint. When the size of GSS varies, the size of matrix in TCM also varies correspondingly to keep the ratio unchanged.

VII-D Experiments on query primitives

(a) email-EuAll
(b) cit-HepPh
(c) web-NotreDame
(d) lkml-reply
(e) Caida-networkflow
Fig. 8: Average Relative Error of Edge Queries
(a) email-EuAll
(b) cit-HepPh
(c) web-NotreDame
(d) lkml-reply
(e) Caida-networkflow
Fig. 9: Average Precision of 1-hop Precursor Queries
(a) email-EuAll
(b) cit-HepPh
(c) web-NotreDame
(d) lkml-reply
(e) Caida-networkflow
Fig. 10: Average Precision of 1-hop Successor Queries

In this section, we evaluate the performance of GSS in the 3 basic graph query primitives: the edge query, the 1-hop precursor query and the 1-hop successor query. Figure 8, Figure 9, and Figure 10 show that ARE of edge queries and average precision of 1-hop precursor / successor queries for the data sets, respectively. To reduce random error introduced by the selection of the data sample, the edge query set contains all edges in the graph stream, and the 1-hop precursor / successor query set contains all nodes in the graph stream. The results tell us that GSS performs much better in supporting these query primitives than TCM, especially in the 1-hop precursor / successor query primitives. In both GSS and TCM, the ARE decreases, and the precision increases with the growth of the width of the matrix. This trend is not very significant in GSS as the accuracy is high and there are no errors in most experiments. Also, when the length of fingerprint becomes longer, the accuracy of GSS increases.

VII-E Experiments on Node Query

(a) email-EuAll
(b) cit-HepPh
(c) web-NotreDame
(d) lkml-reply
(e) Caida-networkflow
Fig. 11: Average Relative Error of Node Queries

In this section, we evaluate the performance of GSS in estimating the accuracy of node query. A node query for a node vv is to compute the summary of the weights of all edges with source node vv. For each dataset, node query set contains all nodes in the graph stream. Figure 11 shows the ARE of node queries in data sets email-EuAll, cit-HepPh and web-NotreDame, respectively. The figure shows that although we unfairly fix the ratio of memory used by TCM and GSS, GSS still can achieve better performance than TCM.

VII-F Experiments on Reachability Query

In this section, we evaluate the performance of GSS in supporting reachability queries. Each reachability query set QQ contains 100 unreachable pairs of nodes which are randomly generated from the graph.

(a) email-EuAll
(b) cit-HepPh
(c) email-EuAll
(d) cit-HepPh
(e) web-NotreDame
Fig. 12: True Negative Recall of Reachability Queries

Figure 12 shows the true negative recall of reachability query for the data sets email-EuAll, cit-HepPh and web-NotreDame, respectively. From the figures we can see that the accuracy of GSS is much higher than TCM even when TCM uses much larger memory. The gap varies with the size of the graph. Along with increasing the memory and the length of the fingerprint, GSS can achieve better performance. We can also see that the accuracy of TCM is so poor that it can barely support this query.

(a) web-NotreDame
(b) lkml-reply
(c) Caida-networkflow
Fig. 13: Buffer Percentage

VII-G Experiments on Buffer Size

Figure 13 shows the buffer percentage for the three larger data sets web-NotreDame,lkml-replyand Caida-networkflow. The four curves in the figure represent 1)GSS with 1 room in each bucket and no square hashing. 2) GSS with 2 rooms in each bucket and no square hashing. 3) GSS with 1 room in each bucket and square hashing. 4) GSS with 2 rooms in each bucket and square hashing. The x-label, ww, is the side length of the matrices for the schemes with 22 rooms in each bucket. When GSS has 1 room in each bucket, the width of the matrix is 20.52^{0.5} times larger to make the memory unchanged. The above results show that the decrement in buffer size brought by using square hashing and multiple rooms is significant, especially the square hashing. The results also show that the buffer percentage in the fully improved GSS (2 rooms each bucket, with square hashing) becomes 00 in most experiments when the matrix size is close to |E||E|. In this case, the overhead brought by the insertion failure in the matrix is nearly 0.

VII-H Experiment on update speed

In this section we evaluate the update speed of GSS. We compare the update speed of GSS, TCM and adjacency lists, the result is shown in Table I. The adjacency list is accelerated using a map that records the position of the list for each node. Because the update speed changes little with the matrix size, we only show the average speed here. The fingerprint size is 16-bit. TCM is still implemented with the same settings as above experiments. In each data set we insert all the edges into the data structure, repeat this procedure 100 times and calculate the average speed. The unit we use is Million Insertions per Second (Mips). From the figure we can see that the speed of GSS is similar to TCM, because though more memory accesses are needed, GSS computes less hash functions. Both of them are much higher than the adjacency list. We also show the speed of GSS without candidate bucket sampling. We can see that the speed without candidate sampling is lower than the full optimized one. The gap is not very large because most edges find empty bucket in few searches.

TABLE I: Update Speed (Mips)
Data Structure email-EuAll cit-HepPh web-NotreDame
GSS 2.28872.2887 2.610572.61057 2.409762.40976
GSS(no sampling) 2.12452.1245 2.491912.49191 2.320152.32015
TCM 2.104172.10417 2.54982.5498 2.074032.07403
Adjacency Lists 0.5785960.578596 0.33840.3384 0.521470.52147

VII-I Experiment on Other Compound Queries

We compare GSS with state-of-the-art graph processing algorithms in triangle counting and subgraph matching in this Section. We compare GSS with TRIEST [23] in triangle counting with the same memory. We use relative error between the reported results and the true value as evaluation metrics. TRIEST does not support multiple edges. Therefore we unique the edges in the dataset for it. The results are shown in Figure 14. The results show that they achieve similarly high accuracy with relative error less than 1%1\%. We compare GSS with SJ-tree[24] in subgraph matching. As SJ-tree is an accurate algorithm, we set GSS to 110\frac{1}{10} of its memory. We use VF2 algorithm when querying in GSS, other algorithms can also be used. We use web-NotreDame and search for subgraphs in windows of the data stream. The edges in the graph are labeled by the ports and the protocol. We carry out experiment on 55 window sizes, and for each window size, we randomly select 55 windows in the stream. In each window, we generate 44 kinds of subgraphs with 66, 99, 1212 and 1515 edges and 55 instances in each kind by random walk. We use the correct rate as evaluation metrics, which means the percentage of correct matches in the 100100 matches for each window size. Experimental results are shown in Figure 15. We can see that GSS has nearly 100%100\% correct rate. Both TRIEST an SJ-tree have throughput less than 2×1052\times 10^{5} edges per second, much lower than the update speed of GSS, and high update speed is important in high speed streams.

Fig. 14: Triangle count in cit-HepPh
Fig. 15: Subgraph matching in web-NotreDame

VIII Conclusion

Graph stream summarization is a problem rising in many fields. However, as far as we know, there are no prior work that can support all kinds of queries with high accuracy. In this paper, we propose graph stream summarization data structure Graph Stream Sketch (GSS). It has O(|E|)O(|E|) memory usage where |E||E| is the number of edges in the graph stream, and O(1)O(1) update speed. It supports almost queries based on graphs and has accuracy which is higher than state-of-the-art by magnitudes. Both mathematical analysis and experiment results confirm the superiority of our work.

References

  • [1] S. Guha and A. McGregor, “Graph synopses, sketches, and streams: A survey,” PVLDB, vol. 5, no. 12, pp. 2030–2031, 2012.
  • [2] G. Cormode and S. Muthukrishnan, “An improved data stream summary: The count-min sketch and its applications,” in Latin American Symposium on Theoretical Informatics, pp. 29–38, 2004.
  • [3] C. Estan and G. Varghese, “New directions in traffic measurement and accounting: Focusing on the elephants, ignoring the mice,” ACM Transactions on Computer Systems (TOCS), vol. 21, no. 3, pp. 270–313, 2003.
  • [4] P. Roy, A. Khan, and G. Alonso, “Augmented sketch: Faster and more accurate stream processing,” in SIGMOD, pp. 1449–1463, ACM, 2016.
  • [5] D. Thomas, R. Bordawekar, C. C. Aggarwal, and S. Y. Philip, “On efficient query processing of stream counts on the cell processor,” in ICDE, pp. 748–759, IEEE, 2009.
  • [6] P. Zhao, C. C. Aggarwal, and M. Wang, “gsketch: on query estimation in graph streams,” PVLDB, vol. 5, no. 3, pp. 193–204, 2011.
  • [7] N. Tang, Q. Chen, and P. Mitra, “Graph stream summarization: From big bang to big crunch,” in SIGMOD, pp. 1481–1496, 2016.
  • [8] A. Khan and C. Aggarwal, “Query-friendly compression of graph streams,” in IEEE/ACM International Conference on Advances in Social Networks Analysis and Mining, pp. 130–137, 2016.
  • [9] M. Elkin, “Streaming and fully dynamic centralized algorithms for constructing and maintaining sparse spanners,” in ICALP, pp. 716–727, Springer, 2007.
  • [10] V. Braverman, R. Ostrovsky, and D. Vilenchik, “How hard is counting triangles in the streaming model?,” in ICALP, pp. 244–254, Springer, 2013.
  • [11] J. Feigenbaum, S. Kannan, A. McGregor, S. Suri, and J. Zhang, “On graph problems in a semi-streaming model,” Theoretical Computer Science, vol. 348, no. 2-3, pp. 207–216, 2005.
  • [12] J. E. Gonzalez, R. S. Xin, A. Dave, D. Crankshaw, M. J. Franklin, and I. Stoica, “Graphx: Graph processing in a distributed dataflow framework.,” in OSDI, vol. 14, pp. 599–613, 2014.
  • [13] J. E. Gonzalez, Y. Low, H. Gu, D. Bickson, and C. Guestrin, “Powergraph: distributed graph-parallel computation on natural graphs.,” in OSDI, vol. 12, p. 2, 2012.
  • [14] G. Malewicz, M. H. Austern, A. J. Bik, J. C. Dehnert, I. Horn, N. Leiser, and G. Czajkowski, “Pregel: a system for large-scale graph processing,” in SIGMOD, pp. 135–146, ACM, 2010.
  • [15] Y. Low, D. Bickson, J. Gonzalez, C. Guestrin, A. Kyrola, and J. M. Hellerstein, “Distributed graphlab: a framework for machine learning and data mining in the cloud,” PVLDB, vol. 5, no. 8, pp. 716–727, 2012.
  • [16] S. Raghavan and H. Garcia-Molina, “Representing web graphs,” in ICDE, pp. 405–416, IEEE, 2003.
  • [17] W. Fan, J. Li, X. Wang, and Y. Wu, “Query preserving graph compression,” in SIGMOD, pp. 157–168, ACM, 2012.
  • [18] D. A. Spielman and N. Srivastava, “Graph sparsification by effective resistances,” SIAM Journal on Computing, vol. 40, no. 6, pp. 1913–1926, 2011.
  • [19] J. Gao, C. Zhou, J. Zhou, and J. X. Yu, “Continuous pattern detection over billion-edge graph using distributed framework,” in ICDE, pp. 556–567, IEEE, 2014.
  • [20] C. Wang and L. Chen, “Continuous subgraph pattern search over graph streams,” in ICDE, pp. 393–404, IEEE, 2009.
  • [21] C. Song, T. Ge, C. Chen, and J. Wang, “Event pattern matching over graph streams,” PVLDB, vol. 8, no. 4, pp. 413–424, 2014.
  • [22] P. L’Ecuyer, “Tables of linear congruential generators of different sizes and good lattice structure,” Mathematics of Computation, vol. 68, no. 225, pp. 249–260, 1999.
  • [23] L. D. Stefani, A. Epasto, M. Riondato, and E. Upfal, “Triest:counting local and global triangles in fully-dynamic streams with fixed memory size,” in ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, pp. 825–834, 2016.
  • [24] S. Choudhury, L. Holder, G. Chin, K. Agarwal, and J. Feo, “A selectivity based approach to continuous pattern detection in streaming graphs,” Computer Science, vol. 93, no. 8, pp. 939–945, 2015.