/*This first function finds the most active prefix in the table*/
DROP FUNCTION IF EXISTS find_most_active_prefix();
/*These functions show how prefixes and ASes are related.*/
DROP FUNCTION IF EXISTS get_prefixes_per_as(INTEGER);
DROP FUNCTION IF EXISTS get_as_per_prefix(CIDR);
/*These functions take statistics over a peer's table, either at one point or a
range of times.*/
DROP FUNCTION IF EXISTS get_table_growth(INET,VARCHAR,TIMESTAMP,TIMESTAMP,INTERVAL);
DROP FUNCTION IF EXISTS get_table_at_time(INET,VARCHAR,TIMESTAMP);
DROP FUNCTION IF EXISTS get_unique_prefix_growth(INET,VARCHAR,TIMESTAMP,TIMESTAMP,INTERVAL);
DROP FUNCTION IF EXISTS get_unique_prefixes_at_time(INET,VARCHAR,TIMESTAMP);

/*Function that finds the prefix with the most timerange entries associated
with it.  It counts across all peers.*/
CREATE OR REPLACE FUNCTION find_most_active_prefix() RETURNS CIDR AS $$
DECLARE
  p CURSOR FOR SELECT * FROM prefixes;
  top_pref CIDR;
  top_count INTEGER = 0;
  curr_count INTEGER = 0;
BEGIN
  FOR prefix IN p LOOP
    EXECUTE 'SELECT COUNT(1) 
    FROM timeranges AS t, ppms AS p1, prefixes AS p2
    WHERE p2.pref = '''||prefix.pref||''' AND
        p2.dbid = p1.prefix_dbid AND
        t.ppm_dbid = p1.dbid' INTO curr_count;
    IF curr_count > top_count THEN
        top_count = curr_count;
        top_pref = prefix.pref;
    END IF;
  END LOOP;
  RETURN top_pref;
END;
$$ LANGUAGE plpgsql;

/*Function that returns all the prefixes announced by a given ASN.*/
CREATE OR REPLACE FUNCTION get_prefixes_per_as(INTEGER) RETURNS SETOF CIDR AS $$
BEGIN
	RETURN QUERY
	SELECT DISTINCT pref
	FROM prefixes AS p1,ppms AS p2,timeranges AS t
	WHERE origin_as = $1 AND
		t.ppm_dbid = p2.dbid AND
		p2.prefix_dbid = p1.dbid;
END;
$$	LANGUAGE plpgsql;

/*Function to retrieve all unique ASN's that announce a given prefix.*/
CREATE OR REPLACE FUNCTION get_as_per_prefix(CIDR) RETURNS SETOF INTEGER AS $$
BEGIN
	RETURN QUERY
	SELECT DISTINCT origin_as
	FROM prefixes AS p1,ppms AS p2,timeranges AS t
	WHERE pref = $1 AND
		t.ppm_dbid = p2.dbid AND
		p2.prefix_dbid = p1.dbid;
END;
$$	LANGUAGE plpgsql;

/*Function to iteratively get table-size numbers for a given peer.  Function
takes a peer's address and collector and starting and ending timestamps as well as an
interval step size, then gets all of the prefixes that were active in that peer's table 
during each interval in the entire timerange.*/
CREATE OR REPLACE FUNCTION get_table_growth(INET,VARCHAR,TIMESTAMP,TIMESTAMP,INTERVAL) RETURNS SETOF INTEGER AS $$
DECLARE
	i TIMESTAMP;
BEGIN
	i := $3;
	WHILE i <= $4 LOOP
		RETURN NEXT COUNT(1) FROM get_table_at_time($1,$2,i);
		i := i + $5;
	END LOOP;
END;
$$	LANGUAGE plpgsql;

/*Function to return how many unique prefixes a given peer has seen over some
timerange*/
CREATE OR REPLACE FUNCTION get_unique_prefix_growth(INET,VARCHAR,TIMESTAMP,TIMESTAMP,INTERVAL) RETURNS SETOF INTEGER AS $$
DECLARE
	i TIMESTAMP;
BEGIN
	i := $3;
	WHILE i <= $4 LOOP
		RETURN NEXT COUNT(1) FROM get_unique_prefixes_at_time($1,$2,i);
		i := i + $5;
	END LOOP;
END;
$$	LANGUAGE plpgsql;

/*Function to get the contents of a peer's routing table at a given point in time.
Function takes a peer's address and collector's name and a unix timestamp, then
returns all prefixes that were/are currently active for that peer at that time.*/
CREATE OR REPLACE FUNCTION get_table_at_time(INET,VARCHAR,TIMESTAMP) RETURNS SETOF CIDR AS $$
DECLARE
    peer_table VARCHAR;
BEGIN
    peer_table := generate_peer_table_name($1,$2);
    RETURN QUERY EXECUTE
    'SELECT DISTINCT pref
    FROM prefixes AS p1,ppms AS p2,peers AS p3,'||quote_ident(peer_table)||' AS t
    WHERE (p3.addr,p3.collector) = (''' || $1 || ''', ''' || $2 || ''') AND
    p2.peer_dbid = p3.dbid AND
    p2.prefix_dbid = p1.dbid AND
    t.ppm_dbid = p2.dbid AND
    t.start_time <= '''|| $3 ||''' AND
    (t.end_time > '''|| $3 ||''' OR t.end_time IS NULL)';
END;
$$ LANGUAGE plpgsql;

/*Function that returns all unique prefixes seen by a peer at a given point in time.
Function takes a peer's address and collector with a timestamp, then returns all 
prefixes seen by that peer at all (including any that may have been only seen in a
withdrawal message) at that time.*/
CREATE OR REPLACE FUNCTION get_unique_prefixes_at_time(INET,VARCHAR,TIMESTAMP) RETURNS SETOF CIDR AS $$
DECLARE
    peer_table VARCHAR;
BEGIN
    peer_table := generate_peer_table_name($1,$2);
    RETURN QUERY EXECUTE
    'SELECT DISTINCT pref
    FROM prefixes AS p1,ppms AS p2,peers AS p3,'||quote_ident(peer_table)||' AS t
    WHERE (p3.addr,p3.collector) = (''' || $1 || ''', ''' || $2 || ''') AND
    p2.peer_dbid = p3.dbid AND
    p2.prefix_dbid = p1.dbid AND
    t.ppm_dbid = p2.dbid AND
    t.start_time <= '''|| $3 ||''' ';
END;
$$	LANGUAGE plpgsql;


