* VRFS-2613 - optimizing hourly cleanup by moving it to the score report routine
This commit is contained in:
parent
96bc9487c4
commit
7352fa9b19
|
|
@ -1,11 +1,89 @@
|
||||||
DROP FUNCTION IF EXISTS discard_scores();
|
DROP FUNCTION IF EXISTS discard_scores();
|
||||||
|
|
||||||
CREATE FUNCTION discard_scores (INTEGER keep) RETURNS VOID AS $$
|
CREATE FUNCTION discard_scores (keep INTEGER) RETURNS VOID AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
DELETE FROM scores WHERE score_dt >
|
DELETE FROM scores WHERE score_dt <
|
||||||
(SELECT score_dt FROM scores s WHERE s.alocidispid = scores.alocidispid AND s.blocidispid = scores.blocidispid ORDER BY DESC score_dt LIMIT 1 OFFSET (keep * 2));
|
(SELECT score_dt FROM scores s WHERE s.alocidispid = scores.alocidispid AND s.blocidispid = scores.blocidispid ORDER BY score_dt DESC LIMIT 1 OFFSET (keep - 1));
|
||||||
|
|
||||||
RETURN;
|
RETURN;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION update_current_network_scores(aloc BIGINT, bloc BIGINT) RETURNS VOID
|
||||||
|
STRICT VOLATILE AS $$
|
||||||
|
DECLARE
|
||||||
|
newscore INTEGER;
|
||||||
|
newscore_dt TIMESTAMP;
|
||||||
|
newscore_limited BOOL;
|
||||||
|
sum INTEGER;
|
||||||
|
kount INTEGER;
|
||||||
|
r RECORD;
|
||||||
|
avgscore INTEGER;
|
||||||
|
maxscore INTEGER;
|
||||||
|
minscore INTEGER;
|
||||||
|
BEGIN
|
||||||
|
-- find the 6 most recent scores
|
||||||
|
-- (supposedly newscore is the first...)
|
||||||
|
-- hybrid scheme: compute the average of some recent scores, then limit newscore to be between 4/5 and 6/5 of the average
|
||||||
|
newscore := NULL;
|
||||||
|
newscore_dt := NULL;
|
||||||
|
newscore_limited := FALSE;
|
||||||
|
sum := 0;
|
||||||
|
kount := 0;
|
||||||
|
FOR r IN SELECT score, score_dt FROM scores WHERE alocidispid = aloc AND blocidispid = bloc ORDER BY score_dt DESC LIMIT 6 LOOP
|
||||||
|
IF newscore IS NULL THEN
|
||||||
|
newscore := r.score;
|
||||||
|
newscore_dt := r.score_dt;
|
||||||
|
ELSE
|
||||||
|
sum := sum + r.score;
|
||||||
|
kount := kount + 1;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
-- if no scores in query at all, then delete any current entry
|
||||||
|
IF newscore IS NULL THEN
|
||||||
|
DELETE FROM current_network_scores WHERE alocidispid = aloc AND blocidispid = bloc;
|
||||||
|
IF aloc != bloc THEN
|
||||||
|
DELETE FROM current_network_scores WHERE alocidispid = bloc AND blocidispid = aloc;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- if there are scores older than newscore, then use their average to limit the range of newscore
|
||||||
|
IF kount > 0 THEN
|
||||||
|
avgscore := sum / kount;
|
||||||
|
maxscore := avgscore*6/5;
|
||||||
|
minscore := avgscore*4/5;
|
||||||
|
-- the score newscore will be inserted as the current value in current_network_scores, but we will limit it
|
||||||
|
-- to be no greater than 120% of the average and no less than 80% of the average. this will dampen wild
|
||||||
|
-- swings in the scores.
|
||||||
|
IF newscore > maxscore THEN
|
||||||
|
newscore := maxscore;
|
||||||
|
newscore_limited := TRUE;
|
||||||
|
ELSEIF newscore < minscore THEN
|
||||||
|
newscore := minscore;
|
||||||
|
newscore_limited := TRUE;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
UPDATE current_network_scores SET score = newscore, limited = newscore_limited, score_dt = newscore_dt WHERE alocidispid = aloc AND blocidispid = bloc;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
INSERT INTO current_network_scores (alocidispid, blocidispid, score, limited, score_dt) VALUES (aloc, bloc, newscore, newscore_limited, newscore_dt);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF aloc != bloc THEN
|
||||||
|
UPDATE current_network_scores SET score = newscore, limited = newscore_limited, score_dt = newscore_dt WHERE alocidispid = bloc AND blocidispid = aloc;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
INSERT INTO current_network_scores (alocidispid, blocidispid, score, limited, score_dt) VALUES (bloc, aloc, newscore, newscore_limited, newscore_dt);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- keep the scores table clean, meaning only up to the most 5 recent scores per group & direction (scorer)
|
||||||
|
DELETE FROM scores WHERE alocidispid = aloc AND blocidispid = bloc AND scorer = 0 AND score_dt <
|
||||||
|
(SELECT score_dt FROM scores s WHERE s.alocidispid = aloc AND s.blocidispid = bloc AND s.scorer = 0 ORDER BY score_dt DESC LIMIT 1 OFFSET 4);
|
||||||
|
DELETE FROM scores WHERE alocidispid = bloc AND blocidispid = aloc AND scorer = 1 AND score_dt <
|
||||||
|
(SELECT score_dt FROM scores s WHERE s.alocidispid = bloc AND s.blocidispid = aloc AND s.scorer = 1 ORDER BY score_dt DESC LIMIT 1 OFFSET 4);
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
@ -527,24 +527,25 @@ describe Score do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "discards over 5 items" do
|
it "discards over 5 items" do
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 6.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 5.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 4.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 3.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 2.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
|
||||||
|
|
||||||
Score.count.should == 12
|
Score.count.should == 10
|
||||||
Score.connection.execute("SELECT discard_scores(5)").check
|
|
||||||
Score.count.should == 12
|
|
||||||
|
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 26, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 1.days.ago)
|
||||||
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 26").cmdtuples.should == 2
|
|
||||||
Score.connection.execute("SELECT discard_scores(5)").check
|
Score.count.should == 10
|
||||||
Score.count.should == 12
|
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 12
|
# make a score older than all the rest; it should get whacked
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 6
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 26, 7.days.ago)
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 6
|
|
||||||
|
Score.count.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 5
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 5
|
||||||
|
|
||||||
|
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
||||||
|
|
@ -554,18 +555,35 @@ describe Score do
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
||||||
|
|
||||||
Score.count.should == 24
|
Score.count.should == 20
|
||||||
Score.connection.execute("SELECT discard_scores(5)").check
|
|
||||||
Score.count.should == 24
|
|
||||||
|
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 36, nil)
|
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
|
||||||
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 36").cmdtuples.should == 2
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
Score.connection.execute("SELECT discard_scores(5)").check
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 10
|
||||||
Score.count.should == 24
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 10
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 12
|
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 22 AND scorer = 0").ntuples.should == 6
|
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 22 AND scorer = 1").ntuples.should == 6
|
|
||||||
|
|
||||||
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 36, 7.days.ago)
|
||||||
|
Score.count.should == 20
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 10
|
||||||
|
|
||||||
|
# let's create scores between a new location, and make sure they don't distrurb the data we have now
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
|
||||||
|
Score.count.should == 22
|
||||||
|
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
|
||||||
|
Score.count.should == 30
|
||||||
|
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 10").ntuples.should == 10
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue