* merge in faster score searches (VRFS-2202)

This commit is contained in:
Seth Call 2014-09-30 10:51:23 -05:00
parent 6442674c91
commit 8889b8ce42
16 changed files with 494 additions and 185 deletions

View File

@ -212,4 +212,5 @@ fix_find_session_sorting_2216.sql
multiple_gateways.sql multiple_gateways.sql
fix_find_session_sorting_2216a.sql fix_find_session_sorting_2216a.sql
fix_find_session_sorting_2216b.sql fix_find_session_sorting_2216b.sql
fix_find_session_sorting_2216c.sql fix_find_session_sorting_2216c.sql
entabulate_current_network_scores.sql

View File

@ -0,0 +1,112 @@
DROP VIEW IF EXISTS current_scores;
DROP VIEW IF EXISTS current_network_scores;
DROP TABLE IF EXISTS current_network_scores;
-- this table is used to store a periodically computed summary of the scoring.
-- the raw scores are posted to the table scores and then processed somehow
-- and stored here.
CREATE TABLE current_network_scores (
alocidispid BIGINT NOT NULL,
blocidispid BIGINT NOT NULL,
score INTEGER NOT NULL,
limited BOOL NOT NULL,
score_dt TIMESTAMP NOT NULL
);
CREATE UNIQUE INDEX current_network_scores_a_b_ndx ON current_network_scores(alocidispid, blocidispid);
CREATE UNIQUE INDEX current_network_scores_b_a_ndx ON current_network_scores(blocidispid, alocidispid);
-- the update_current_network_scores function is used to compute a new score to insert into current_network_scores
-- given that a new row has been inserted into scores. a new value for the summary score is computed and stored.
-- aloc is the alocidispid for the new score, bloc is the blocidispid.
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;
END;
$$ LANGUAGE plpgsql;
CREATE VIEW current_scores AS
SELECT current_network_scores.*, a_users.id as a_userid, b_users.id as b_userid, (COALESCE(a_users.last_jam_audio_latency, 13) + COALESCE(b_users.last_jam_audio_latency, 13) + score) AS full_score, a_users.last_jam_audio_latency AS a_audio_latency, b_users.last_jam_audio_latency AS b_audio_latency
FROM current_network_scores
INNER JOIN users as a_users ON a_users.last_jam_locidispid = current_network_scores.alocidispid
INNER JOIN users as b_users ON b_users.last_jam_locidispid = current_network_scores.blocidispid
ORDER BY full_score ASC;
create index users_last_jam_locidispid_ndx on users (last_jam_locidispid);
CREATE OR REPLACE FUNCTION populate_current_network_scores() RETURNS VOID
STRICT VOLATILE AS $$
DECLARE
r RECORD;
BEGIN
FOR r IN SELECT DISTINCT alocidispid, blocidispid FROM scores WHERE alocidispid <= blocidispid ORDER BY alocidispid, blocidispid LOOP
PERFORM update_current_network_scores(r.alocidispid, r.blocidispid);
END LOOP;
END;
$$ LANGUAGE plpgsql;

View File

@ -224,14 +224,14 @@ SQL
SELECT DISTINCT SELECT DISTINCT
tmp_candidate_recipients.receiver_id, tmp_candidate_recipients.receiver_id,
tmp_candidate_recipients.session_id, tmp_candidate_recipients.session_id,
nondirected_scores.full_score AS latency current_scores.full_score AS latency
INTO TEMP TABLE tmp_matches INTO TEMP TABLE tmp_matches
FROM nondirected_scores FROM current_scores
INNER JOIN tmp_candidate_recipients ON INNER JOIN tmp_candidate_recipients ON
tmp_candidate_recipients.creator_id = nondirected_scores.a_userid AND tmp_candidate_recipients.creator_id = current_scores.a_userid AND
tmp_candidate_recipients.receiver_id = nondirected_scores.b_userid tmp_candidate_recipients.receiver_id = current_scores.b_userid
WHERE WHERE
nondirected_scores.full_score < #{max_score} current_scores.full_score < #{max_score}
GROUP BY GROUP BY
tmp_candidate_recipients.receiver_id, tmp_candidate_recipients.receiver_id,
tmp_candidate_recipients.session_id, tmp_candidate_recipients.session_id,

View File

@ -14,9 +14,12 @@ module JamRuby
def self.createx(alocidispid, anodeid, aaddr, blocidispid, bnodeid, baddr, score, score_dt = Time.now, score_data = nil, user_info = {}) def self.createx(alocidispid, anodeid, aaddr, blocidispid, bnodeid, baddr, score, score_dt = Time.now, score_data = nil, user_info = {})
score_dt = Time.new.utc if score_dt.nil? score_dt = Time.new.utc if score_dt.nil?
score = score.ceil score = score.ceil
raise "alocidispid must be positive" if alocidispid <= 0
raise "blocidispid must be positive" if blocidispid <= 0
raise "score must be positive" if score <= 0 raise "score must be positive" if score <= 0
ascore = Score.create(alocidispid: alocidispid, anodeid: anodeid, aaddr: aaddr, auserid: user_info[:auserid], alatencytestid: user_info[:alatencytestid], blocidispid: blocidispid, bnodeid: bnodeid, baddr: baddr, buserid: user_info[:buserid], blatencytestid: user_info[:blatencytestid], score: score, scorer: 0, score_dt: score_dt, scoring_data: score_data) ascore = Score.create(alocidispid: alocidispid, anodeid: anodeid, aaddr: aaddr, auserid: user_info[:auserid], alatencytestid: user_info[:alatencytestid], blocidispid: blocidispid, bnodeid: bnodeid, baddr: baddr, buserid: user_info[:buserid], blatencytestid: user_info[:blatencytestid], score: score, scorer: 0, score_dt: score_dt, scoring_data: score_data)
bscore = Score.create(alocidispid: blocidispid, anodeid: bnodeid, aaddr: baddr, auserid: user_info[:buserid], blatencytestid: user_info[:blatencytestid], blocidispid: alocidispid, bnodeid: anodeid, baddr: aaddr, buserid: user_info[:auserid], blatencytestid: user_info[:alatencytestid], score: score, scorer: 1, score_dt: score_dt) if alocidispid != blocidispid bscore = Score.create(alocidispid: blocidispid, anodeid: bnodeid, aaddr: baddr, auserid: user_info[:buserid], blatencytestid: user_info[:blatencytestid], blocidispid: alocidispid, bnodeid: anodeid, baddr: aaddr, buserid: user_info[:auserid], blatencytestid: user_info[:alatencytestid], score: score, scorer: 1, score_dt: score_dt) if alocidispid != blocidispid
Score.connection.execute("select update_current_network_scores(#{alocidispid}, #{blocidispid})")
return [ascore, bscore] return [ascore, bscore]
end end

View File

@ -228,15 +228,15 @@ module JamRuby
# the default of ANY setup above applies # the default of ANY setup above applies
end end
rel = rel.joins("LEFT JOIN nondirected_scores ON nondirected_scores.a_userid = users.id AND nondirected_scores.b_userid = '#{user.id}'") rel = rel.joins("LEFT JOIN current_scores ON current_scores.a_userid = users.id AND current_scores.b_userid = '#{user.id}'")
rel = rel.joins('LEFT JOIN regions ON regions.countrycode = users.country AND regions.region = users.state') rel = rel.joins('LEFT JOIN regions ON regions.countrycode = users.country AND regions.region = users.state')
rel = rel.where(['nondirected_scores.full_score > ?', score_min]) unless score_min.nil? rel = rel.where(['current_scores.full_score > ?', score_min]) unless score_min.nil?
rel = rel.where(['nondirected_scores.full_score <= ?', score_max]) unless score_max.nil? rel = rel.where(['current_scores.full_score <= ?', score_max]) unless score_max.nil?
rel = rel.select('nondirected_scores.full_score, nondirected_scores.score, regions.regionname') rel = rel.select('current_scores.full_score, current_scores.score, regions.regionname')
rel = rel.group('nondirected_scores.full_score, nondirected_scores.score, regions.regionname') rel = rel.group('current_scores.full_score, current_scores.score, regions.regionname')
end end
ordering = self.order_param(params) ordering = self.order_param(params)
@ -268,7 +268,7 @@ module JamRuby
end end
if !locidispid.nil? && !user.nil? if !locidispid.nil? && !user.nil?
rel = rel.order('nondirected_scores.full_score ASC NULLS LAST') rel = rel.order('current_scores.full_score ASC NULLS LAST')
end end
rel = rel.order('users.created_at DESC') rel = rel.order('users.created_at DESC')

View File

@ -53,6 +53,7 @@ describe EmailBatchNewMusician do
receiver1; receiver2 receiver1; receiver2
EmailBatchNewMusician.delete_all EmailBatchNewMusician.delete_all
JamRuby::Score.delete_all JamRuby::Score.delete_all
JamRuby::Score.connection.execute('delete from current_network_scores').check
JamRuby::Score.createx(1, 'a', 1, 1, 'a', 1, 10) JamRuby::Score.createx(1, 'a', 1, 1, 'a', 1, 10)
JamRuby::Score.createx(1, 'a', 1, 2, 'a', 2, Score::MAX_YELLOW_LATENCY + 1) JamRuby::Score.createx(1, 'a', 1, 2, 'a', 2, Score::MAX_YELLOW_LATENCY + 1)
end end
@ -161,6 +162,7 @@ describe EmailBatchNewMusician do
:created_at => ebatch0.created_at + 1.hour) :created_at => ebatch0.created_at + 1.hour)
end end
JamRuby::Score.delete_all JamRuby::Score.delete_all
JamRuby::Score.connection.execute('delete from current_network_scores').check
JamRuby::Score.createx(5, 'a', 5, 6, 'a', 6, 10) JamRuby::Score.createx(5, 'a', 5, 6, 'a', 6, 10)
JamRuby::Score.createx(5, 'a', 5, 7, 'a', 7, Score::MAX_YELLOW_LATENCY + 1) JamRuby::Score.createx(5, 'a', 5, 7, 'a', 7, Score::MAX_YELLOW_LATENCY + 1)
FactoryGirl.create(:user, :last_jam_locidispid => 8, :created_at => dd) FactoryGirl.create(:user, :last_jam_locidispid => 8, :created_at => dd)

View File

@ -73,6 +73,7 @@ describe EmailBatchScheduledSessions do
MusicianInstrument.delete_all MusicianInstrument.delete_all
RsvpSlot.delete_all RsvpSlot.delete_all
JamRuby::Score.delete_all JamRuby::Score.delete_all
JamRuby::Score.connection.execute('delete from current_network_scores').check
scheduled_batch.reset! scheduled_batch.reset!
@drums_rsvp_slot = FactoryGirl.create(:rsvp_slot, :instrument => drums, :music_session => session1) @drums_rsvp_slot = FactoryGirl.create(:rsvp_slot, :instrument => drums, :music_session => session1)

View File

@ -99,6 +99,7 @@ describe 'Musician search' do
# user1 has scores other users in user1 location, and with user2, user3, user4 # user1 has scores other users in user1 location, and with user2, user3, user4
# user2 has scores with users in user3 and user4 location # user2 has scores with users in user3 and user4 location
# Score.delete_all # Score.delete_all
# Score.connection.execute('delete from current_network_scores').check
Score.createx(1, 'a', 1, 1, 'a', 1, 10) Score.createx(1, 'a', 1, 1, 'a', 1, 10)
Score.createx(1, 'a', 1, 2, 'b', 2, 20) Score.createx(1, 'a', 1, 2, 'b', 2, 20)
Score.createx(1, 'a', 1, 3, 'c', 3, 30) Score.createx(1, 'a', 1, 3, 'c', 3, 30)

View File

@ -2,38 +2,61 @@ require 'spec_helper'
describe Score do describe Score do
let(:user1) { FactoryGirl.create(:user, last_jam_locidispid: 1234) } LOCA = 1234
let(:user2) { FactoryGirl.create(:user, last_jam_locidispid: 2345) } ADDRA = 0x01020304
let(:score_with_user) { s1, s2 = Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo', { auserid: user1.id, buserid: user2.id }); s1 } NODEA = 'anodeid'
let(:score_with_user_reversed) { s1, s2 = Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo', { buserid: user1.id, auserid: user2.id }); s1 }
LOCB = 2345
ADDRB = 0x02030405
NODEB = 'bnodeid'
LOCC = 3456
ADDRC = 0x03040506
NODEC = 'cnodeid'
LOCD = 4567
ADDRD = 0x04050607
NODED = 'dnodeid'
LOCE = 5678
ADDRE = 0x05060708
NODEE = 'enodeid'
LOCF = 6789
ADDRF = 0x06070809
NODEF = 'fnodeid'
let(:user1) { FactoryGirl.create(:user, last_jam_locidispid: LOCA, last_jam_audio_latency: 13) }
let(:user2) { FactoryGirl.create(:user, last_jam_locidispid: LOCB, last_jam_audio_latency: 17) }
let(:score_with_user) { s1, s2 = Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil, 'foo', { auserid: user1.id, buserid: user2.id }); s1 }
let(:score_with_user_reversed) { s1, s2 = Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil, 'foo', { auserid: user2.id, buserid: user1.id }); s1 }
let(:latency_tester1) { FactoryGirl.create(:latency_tester) } let(:latency_tester1) { FactoryGirl.create(:latency_tester) }
let(:latency_tester2) { FactoryGirl.create(:latency_tester) } let(:latency_tester2) { FactoryGirl.create(:latency_tester) }
let(:score_with_latency_tester) { s1, s2 = Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo', { alatencytestid: latency_tester1.id, blatencytestid: latency_tester2.id}); s1 }
let(:score_with_latency_tester) { s1, s2 = Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil, 'foo', { alatencytestid: latency_tester1.id, blatencytestid: latency_tester2.id}); s1 }
describe "with default scores" do describe "with default scores" do
before do before do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil, 'foo')
Score.createx(1234, 'anodeid', 0x01020304, 3456, 'cnodeid', 0x03040506, 30, nil) Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 30, nil)
Score.createx(1234, 'anodeid', 0x01020304, 3456, 'cnodeid', 0x03040506, 40, Time.new.utc-3600) Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 40, Time.new.utc-3600, 'foo')
end end
it "count" do it "count" do
Score.count.should == 6 Score.count.should == 6
end end
it 'a to b' do it 'a to b' do
s = Score.where(alocidispid: 1234, blocidispid: 2345).limit(1).first s = Score.where(alocidispid: LOCA, blocidispid: LOCB).limit(1).first
s.should_not be_nil s.should_not be_nil
s.alocidispid.should == 1234 s.alocidispid.should == LOCA
s.anodeid.should eql('anodeid') s.anodeid.should eql(NODEA)
s.aaddr.should == 0x01020304 s.aaddr.should == ADDRA
s.blocidispid.should == 2345 s.blocidispid.should == LOCB
s.bnodeid.should eql('bnodeid') s.bnodeid.should eql(NODEB)
s.baddr.should == 0x02030405 s.baddr.should == ADDRB
s.score.should == 20 s.score.should == 20
s.scorer.should == 0 s.scorer.should == 0
s.score_dt.should_not be_nil s.score_dt.should_not be_nil
@ -41,14 +64,14 @@ describe Score do
end end
it 'b to a' do it 'b to a' do
s = Score.where(alocidispid: 2345, blocidispid: 1234).limit(1).first s = Score.where(alocidispid: LOCB, blocidispid: LOCA).limit(1).first
s.should_not be_nil s.should_not be_nil
s.alocidispid.should == 2345 s.alocidispid.should == LOCB
s.anodeid.should eql('bnodeid') s.anodeid.should eql(NODEB)
s.aaddr.should == 0x02030405 s.aaddr.should == ADDRB
s.blocidispid.should == 1234 s.blocidispid.should == LOCA
s.bnodeid.should eql('anodeid') s.bnodeid.should eql(NODEA)
s.baddr.should == 0x01020304 s.baddr.should == ADDRA
s.score.should == 20 s.score.should == 20
s.scorer.should == 1 s.scorer.should == 1
s.score_dt.should_not be_nil s.score_dt.should_not be_nil
@ -56,14 +79,14 @@ describe Score do
end end
it 'a to c' do it 'a to c' do
s = Score.where(alocidispid: 1234, blocidispid: 3456).limit(1).first s = Score.where(alocidispid: LOCA, blocidispid: LOCC).limit(1).first
s.should_not be_nil s.should_not be_nil
s.alocidispid.should == 1234 s.alocidispid.should == LOCA
s.anodeid.should eql('anodeid') s.anodeid.should eql(NODEA)
s.aaddr.should == 0x01020304 s.aaddr.should == ADDRA
s.blocidispid.should == 3456 s.blocidispid.should == LOCC
s.bnodeid.should eql('cnodeid') s.bnodeid.should eql(NODEC)
s.baddr.should == 0x03040506 s.baddr.should == ADDRC
s.score.should == 30 s.score.should == 30
s.scorer.should == 0 s.scorer.should == 0
s.score_dt.should_not be_nil s.score_dt.should_not be_nil
@ -71,14 +94,14 @@ describe Score do
end end
it 'c to a' do it 'c to a' do
s = Score.where(alocidispid: 3456, blocidispid: 1234).limit(1).first s = Score.where(alocidispid: LOCC, blocidispid: LOCA).limit(1).first
s.should_not be_nil s.should_not be_nil
s.alocidispid.should == 3456 s.alocidispid.should == LOCC
s.anodeid.should eql('cnodeid') s.anodeid.should eql(NODEC)
s.aaddr.should == 0x03040506 s.aaddr.should == ADDRC
s.blocidispid.should == 1234 s.blocidispid.should == LOCA
s.bnodeid.should eql('anodeid') s.bnodeid.should eql(NODEA)
s.baddr.should == 0x01020304 s.baddr.should == ADDRA
s.score.should == 30 s.score.should == 30
s.scorer.should == 1 s.scorer.should == 1
s.score_dt.should_not be_nil s.score_dt.should_not be_nil
@ -86,53 +109,53 @@ describe Score do
end end
it 'delete a to c' do it 'delete a to c' do
Score.deletex(1234, 3456) Score.deletex(LOCA, LOCC)
Score.count.should == 2 Score.count.should == 2
Score.where(alocidispid: 1234, blocidispid: 3456).limit(1).first.should be_nil Score.where(alocidispid: LOCA, blocidispid: LOCC).limit(1).first.should be_nil
Score.where(alocidispid: 3456, blocidispid: 1234).limit(1).first.should be_nil Score.where(alocidispid: LOCC, blocidispid: LOCA).limit(1).first.should be_nil
Score.where(alocidispid: 1234, blocidispid: 2345).limit(1).first.should_not be_nil Score.where(alocidispid: LOCA, blocidispid: LOCB).limit(1).first.should_not be_nil
Score.where(alocidispid: 2345, blocidispid: 1234).limit(1).first.should_not be_nil Score.where(alocidispid: LOCB, blocidispid: LOCA).limit(1).first.should_not be_nil
end end
it 'findx' do it 'findx' do
Score.findx(1234, 1234).should == -1 Score.findx(LOCA, LOCA).should == -1
Score.findx(1234, 2345).should == 20 Score.findx(LOCA, LOCB).should == 20
Score.findx(1234, 3456).should == 30 Score.findx(LOCA, LOCC).should == 30
Score.findx(2345, 1234).should == 20 Score.findx(LOCB, LOCA).should == 20
Score.findx(2345, 2345).should == -1 Score.findx(LOCB, LOCB).should == -1
Score.findx(2345, 3456).should == -1 Score.findx(LOCB, LOCC).should == -1
Score.findx(3456, 1234).should == 30 Score.findx(LOCC, LOCA).should == 30
Score.findx(3456, 2345).should == -1 Score.findx(LOCC, LOCB).should == -1
Score.findx(3456, 3456).should == -1 Score.findx(LOCC, LOCC).should == -1
end end
it "test shortcut for making scores from connections" do it "test shortcut for making scores from connections" do
user1 = FactoryGirl.create(:user) user1 = FactoryGirl.create(:user)
conn1 = FactoryGirl.create(:connection, user: user1, addr: 0x01020304, locidispid: 5) conn1 = FactoryGirl.create(:connection, user: user1, addr: ADDRD, locidispid: LOCD)
user2 = FactoryGirl.create(:user) user2 = FactoryGirl.create(:user)
conn2 = FactoryGirl.create(:connection, user: user2, addr: 0x11121314, locidispid: 6) conn2 = FactoryGirl.create(:connection, user: user2, addr: ADDRE, locidispid: LOCE)
user3 = FactoryGirl.create(:user) user3 = FactoryGirl.create(:user)
conn3 = FactoryGirl.create(:connection, user: user3, addr: 0x21222324, locidispid: 7) conn3 = FactoryGirl.create(:connection, user: user3, addr: ADDRF, locidispid: LOCF)
Score.findx(5, 6).should == -1 Score.findx(LOCD, LOCE).should == -1
Score.findx(6, 5).should == -1 Score.findx(LOCE, LOCD).should == -1
Score.findx(5, 7).should == -1 Score.findx(LOCD, LOCF).should == -1
Score.findx(7, 5).should == -1 Score.findx(LOCF, LOCD).should == -1
Score.findx(6, 7).should == -1 Score.findx(LOCE, LOCF).should == -1
Score.findx(7, 6).should == -1 Score.findx(LOCF, LOCE).should == -1
Score.score_conns(conn1, conn2, 12) Score.score_conns(conn1, conn2, 12)
Score.score_conns(conn1, conn3, 13) Score.score_conns(conn1, conn3, 13)
Score.score_conns(conn2, conn3, 23) Score.score_conns(conn2, conn3, 23)
Score.findx(5, 6).should == 12 Score.findx(LOCD, LOCE).should == 12
Score.findx(6, 5).should == 12 Score.findx(LOCE, LOCD).should == 12
Score.findx(5, 7).should == 13 Score.findx(LOCD, LOCF).should == 13
Score.findx(7, 5).should == 13 Score.findx(LOCF, LOCD).should == 13
Score.findx(6, 7).should == 23 Score.findx(LOCE, LOCF).should == 23
Score.findx(7, 6).should == 23 Score.findx(LOCF, LOCE).should == 23
end end
describe "createx" do describe "createx" do
@ -163,68 +186,119 @@ describe Score do
end end
it "works with one score" do it "works with one score" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
result = Score.connection.execute('SELECT * FROM current_network_scores') result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY alocidispid')
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
result[0]['alocidispid'].to_i.should == 1234 result[0]['alocidispid'].to_i.should == LOCA
result[0]['scorer'].to_i.should == 0 result[0]['blocidispid'].to_i.should == LOCB
result[1]['alocidispid'].to_i.should == 2345 result[0]['score'].to_i.should == 20
result[1]['scorer'].to_i.should == 1 result[1]['alocidispid'].to_i.should == LOCB
result[1]['blocidispid'].to_i.should == LOCA
result[1]['score'].to_i.should == 20
end end
it "works with two scores in same location" do it "works with two scores in same location" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 25, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
# average of older scores is 20, min = 16, max = 24
result = Score.connection.execute('SELECT * FROM current_network_scores') result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
result[0]['score'].to_i.should == 20 result[0]['score'].to_i.should == 24
result[1]['score'].to_i.should == 20 result[1]['score'].to_i.should == 24
end end
it "works with three scores in same location" do it "works with three scores in same location ascending" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 25, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 30, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
result = Score.connection.execute('SELECT * FROM current_network_scores') result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
result[0]['score'].to_i.should == 25 result[0]['score'].to_i.should == 26
result[1]['score'].to_i.should == 25 result[1]['score'].to_i.should == 26
end end
it "works with six scores in same location" do it "works with three scores in same location descending" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') # we'll make sure this is old, so it won't be in the set Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 25, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 30, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 31, nil, 'foo')# median # average of older scores is 27, min = 21, max = 32
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 32, nil, 'foo')
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 33, nil, 'foo')
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{1.days.ago}' WHERE score = 20").cmdtuples.should == 2
result = Score.connection.execute('SELECT * FROM current_network_scores') result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
result[0]['score'].to_i.should == 31 result[0]['score'].to_i.should == 21
result[1]['score'].to_i.should == 31 result[1]['score'].to_i.should == 21
end
# now push back score with 33 to the very back, which will shift the median up to 30 it "works with three scores in same location limited to max" do
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 33").check Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 90, nil)
# average of older scores is 22, min = 17, max = 26
result = Score.connection.execute('SELECT * FROM current_network_scores') result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
result[0]['score'].to_i.should == 30 result[0]['score'].to_i.should == 26
result[1]['score'].to_i.should == 30 result[1]['score'].to_i.should == 26
end
it "works with three scores in same location limited to min" do
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 90, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 25, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
# average of older scores is 57, min = 45, max = 68
result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check
result.ntuples.should == 2
result[0]['score'].to_i.should == 45
result[1]['score'].to_i.should == 45
end
it "works with more than 5 scores in same location" do
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 1, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 12, nil)
# this will be limited to 80% of the average of the older 5 scores
# (40+40+40+40+40)/5 = 40, min = 32, max = 48
result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check
result.ntuples.should == 2
result[0]['score'].to_i.should == 32
result[1]['score'].to_i.should == 32
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 12, nil) # this will be limited to 80% of the average of the latest 5 scores
# (40+40+40+40+12)/5 = 34, min = 27, max = 40
result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check
result.ntuples.should == 2
result[0]['score'].to_i.should == 27
result[1]['score'].to_i.should == 27
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 12, nil) # this will be limited to 80% of the average of the latest 5 scores
# (40+40+40+12+12)/5 = 28, min = 22, max = 33
result = Score.connection.execute('SELECT * FROM current_network_scores')
result.check
result.ntuples.should == 2
result[0]['score'].to_i.should == 22
result[1]['score'].to_i.should == 22
end end
it "works with one score each in different locations" do it "works with one score each in different locations" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 25, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score') result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
result.check result.check
@ -237,28 +311,31 @@ describe Score do
end end
it "works with multiple scores in different locations" do it "works with multiple scores in different locations" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 25, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 30, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 35, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 35, nil)
# average of older scores is 20 for A/B, 25 for A/C, max = 24 for A/B, 30 for A/C
result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score') result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
result.check result.check
result.ntuples.should == 4 result.ntuples.should == 4
result[0]['score'].to_i.should == 20 result[0]['score'].to_i.should == 24
result[1]['score'].to_i.should == 20 result[1]['score'].to_i.should == 24
result[2]['score'].to_i.should == 25 result[2]['score'].to_i.should == 30
result[3]['score'].to_i.should == 25 result[3]['score'].to_i.should == 30
end end
it "works with multiple scores in different locations" do it "works with multiple scores in different locations" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 25, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 30, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 35, nil, 'foo') # median Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 35, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 40, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 45, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 45, nil)
# average of A/B scores is (20+30)/2 = 25, so min = 20, max = 30
# average of A/C scores is (25+35)/2 = 30, so min = 24, max = 36
result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score') result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
result.check result.check
@ -266,106 +343,201 @@ describe Score do
result[0]['score'].to_i.should == 30 result[0]['score'].to_i.should == 30
result[1]['score'].to_i.should == 30 result[1]['score'].to_i.should == 30
result[2]['score'].to_i.should == 35 result[2]['score'].to_i.should == 36
result[3]['score'].to_i.should == 35 result[3]['score'].to_i.should == 36
end end
it "works with over 6 scores in different locations" do it "works with over 6 scores in different locations" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 10, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 25, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 15, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 30, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 35, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 25, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 40, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 30, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 45, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 35, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 45, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 40, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 50, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 45, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 55, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 50, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 60, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 55, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 65, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 60, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2346, 'bnodeid', 0x02030405, 70, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 65, nil)
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 70, nil)
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{1.days.ago}' WHERE score = 20 OR score = 25").cmdtuples.should == 4 Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 75, nil)
# average of A/B scores is (20+30+40+50+60)/5 = 40, so min = 32, max = 48
# average of A/C scores is (25+35+45+55+65)/5 = 45, so min = 36, max = 54
result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score') result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
result.check result.check
result.ntuples.should == 4 result.ntuples.should == 4
result[0]['score'].to_i.should == 45 result[0]['score'].to_i.should == 48 # 70, but limited to max (48)
result[1]['score'].to_i.should == 45 result[1]['score'].to_i.should == 48
result[2]['score'].to_i.should == 50 result[2]['score'].to_i.should == 54 # 75, but limited to max (54)
result[3]['score'].to_i.should == 50 result[3]['score'].to_i.should == 54
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 80, nil)
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 65 OR score = 70").cmdtuples.should == 4 Score.createx(LOCA, NODEA, ADDRA, LOCC, NODEC, ADDRC, 85, nil)
# average of A/B scores is (30+40+50+60+70)/5 = 50, so min = 40, max = 60
# average of A/C scores is (35+45+55+65+75)/5 = 55, so min = 44, max = 66
result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score') result = Score.connection.execute('SELECT * FROM current_network_scores ORDER BY score')
result.check result.check
result.ntuples.should == 4 result.ntuples.should == 4
result[0]['score'].to_i.should == 40 result[0]['score'].to_i.should == 60 # 80, but limited to max (60)
result[1]['score'].to_i.should == 40 result[1]['score'].to_i.should == 60
result[2]['score'].to_i.should == 45 result[2]['score'].to_i.should == 66 # 85, but limited to max (66)
result[3]['score'].to_i.should == 45 result[3]['score'].to_i.should == 66
end end
it "resolves user information with a score created for different users" do it "resolves user information with a score created for different users" do
#pending "i have no idea what this is attempting to demonstrate"
score_with_user.touch score_with_user.touch
score_with_user_reversed.touch score_with_user_reversed.touch
5.times do 5.times do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo', { auserid: user1.id, buserid: user2.id }) Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo', { buserid: user1.id, auserid: user2.id }) Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
end end
result = Score.connection.execute('SELECT * FROM current_network_scores where scorer = 0')
# in the end, since the two scores are so close to each other, the last one will trump
# (that is, A to B and B to A are both 22).
result = Score.connection.execute('SELECT * FROM current_network_scores') # where scorer = 0 removed
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
result = Score.connection.execute('SELECT * FROM current_scores where scorer = 0') result[0]['score'].to_i.should == 22
result[1]['score'].to_i.should == 22
result = Score.connection.execute('SELECT * FROM current_scores') # where scorer = 0 removed
result.check result.check
result.ntuples.should == 2 result.ntuples.should == 2
# create two new users, in the same locations as user1 and user2, but with lower audio gear latency. They should sort first # print "current_scores[0] #{result[0].to_s}\n"
user3 = FactoryGirl.create(:user, last_jam_locidispid: user1.last_jam_locidispid, last_jam_audio_latency: user1.last_jam_audio_latency - 1) # print "current_scores[1] #{result[0].to_s}\n"
user4 = FactoryGirl.create(:user, last_jam_locidispid: user2.last_jam_locidispid, last_jam_audio_latency: user2.last_jam_audio_latency - 1)
result = Score.connection.execute('SELECT * FROM current_scores where scorer = 0') if result[0]['a_userid'] == user1.id
compare_current_score(result[0], user1, user2, 22)
compare_current_score(result[1], user2, user1, 22)
else
compare_current_score(result[0], user2, user1, 22)
compare_current_score(result[1], user1, user2, 22)
end
# create two new users, in the same locations as user1 and user2, but with lower audio gear latency.
user3 = FactoryGirl.create(:user, last_jam_locidispid: user1.last_jam_locidispid, last_jam_audio_latency: 9)
user4 = FactoryGirl.create(:user, last_jam_locidispid: user2.last_jam_locidispid, last_jam_audio_latency: 15)
result = Score.connection.execute('SELECT * FROM current_scores') # where scorer = 0 removed
result.check result.check
result.ntuples.should == 8 result.ntuples.should == 8
# with this data: # with this data:
# user1 has a score with user2 and user4. # user1 has a score with user2 and user4.
# user3 has a score with user4 and user2 # user3 has a score with user2 and user4.
# so there are these combinations:
# user1, user2
# user1, user4
# user2, user1
# user2, user3
# user3, user2
# user3, user4
# user4, user1
# user4, user3
# each must be accounted for below:
result[0]['full_score'].to_i.should == user3.last_jam_audio_latency + user4.last_jam_audio_latency + 20 user_1_2 = false
result[1]['full_score'].to_i.should == user3.last_jam_audio_latency + user2.last_jam_audio_latency + 20 user_1_4 = false
result[2]['full_score'].to_i.should == user4.last_jam_audio_latency + user1.last_jam_audio_latency + 20 user_2_1 = false
result[3]['full_score'].to_i.should == user2.last_jam_audio_latency + user1.last_jam_audio_latency + 20 user_2_3 = false
result[4]['full_score'].to_i.should == user3.last_jam_audio_latency + user4.last_jam_audio_latency + 22 user_3_2 = false
result[5]['full_score'].to_i.should == user3.last_jam_audio_latency + user2.last_jam_audio_latency + 22 user_3_4 = false
result[6]['full_score'].to_i.should == user4.last_jam_audio_latency + user1.last_jam_audio_latency + 22 user_4_1 = false
result[7]['full_score'].to_i.should == user2.last_jam_audio_latency + user1.last_jam_audio_latency + 22 user_4_3 = false
for i in 0..7
if result[i]['a_userid'] == user1.id
if result[i]['b_userid'] == user2.id
compare_current_score(result[i], user1, user2, 22)
user_1_2 = true
else
# b_userid must be user4
compare_current_score(result[i], user1, user4, 22)
user_1_4 = true
end
elsif result[i]['a_userid'] == user2.id
if result[i]['b_userid'] == user1.id
compare_current_score(result[i], user2, user1, 22)
user_2_1 = true
else
# b_userid must be user3
compare_current_score(result[i], user2, user3, 22)
user_2_3 = true
end
elsif result[i]['a_userid'] == user3.id
if result[i]['b_userid'] == user2.id
compare_current_score(result[i], user3, user2, 22)
user_3_2 = true
else
# b_userid must be user4
compare_current_score(result[i], user3, user4, 22)
user_3_4 = true
end
else # a_userid must be user4
if result[i]['b_userid'] == user1.id
compare_current_score(result[i], user4, user1, 22)
user_4_1 = true
else
# b_userid must be user3
compare_current_score(result[i], user4, user3, 22)
user_4_3 = true
end
end
end
user_1_2.should be_true
user_1_4.should be_true
user_2_1.should be_true
user_2_3.should be_true
user_3_2.should be_true
user_3_4.should be_true
user_4_1.should be_true
user_4_3.should be_true
end end
end end
def compare_current_score(r, u1, u2, sc)
r['alocidispid'].to_i.should == u1.last_jam_locidispid
r['a_userid'].should == u1.id
r['a_audio_latency'].to_i.should == u1.last_jam_audio_latency
r['blocidispid'].to_i.should == u2.last_jam_locidispid
r['b_userid'].should == u2.id
r['b_audio_latency'].to_i.should == u2.last_jam_audio_latency
r['score'].to_i.should == sc
r['full_score'].to_i.should == (u1.last_jam_audio_latency + u2.last_jam_audio_latency + sc)
end
describe "discard_scores" do describe "discard_scores" do
it "works" do it "works" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.count.should == 2 Score.count.should == 2
Score.connection.execute("SELECT discard_scores()").check Score.connection.execute("SELECT discard_scores()").check
Score.count.should == 2 Score.count.should == 2
end end
it "discards over 5 items" do it "discards over 5 items" do
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 20, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
Score.count.should == 10 Score.count.should == 10
Score.connection.execute("SELECT discard_scores()").check Score.connection.execute("SELECT discard_scores()").check
Score.count.should == 10 Score.count.should == 10
Score.createx(1234, 'anodeid', 0x01020304, 2345, 'bnodeid', 0x02030405, 26, nil, 'foo') Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 26, nil)
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 26").cmdtuples.should == 2 Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 26").cmdtuples.should == 2
Score.connection.execute("SELECT discard_scores()").check Score.connection.execute("SELECT discard_scores()").check
Score.count.should == 10 Score.count.should == 10
@ -374,17 +546,17 @@ describe Score do
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 5 Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 5
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo') Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo') Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo') Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo') Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 22, nil, 'foo') Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
Score.count.should == 20 Score.count.should == 20
Score.connection.execute("SELECT discard_scores()").check Score.connection.execute("SELECT discard_scores()").check
Score.count.should == 20 Score.count.should == 20
Score.createx(2345, 'bnodeid', 0x02030405, 1234, 'anodeid', 0x01020304, 36, nil, 'foo') Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 36, nil)
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 36").cmdtuples.should == 2 Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 36").cmdtuples.should == 2
Score.connection.execute("SELECT discard_scores()").check Score.connection.execute("SELECT discard_scores()").check
Score.count.should == 20 Score.count.should == 20

View File

@ -17,6 +17,7 @@ describe ApiMusicSessionsController do
ActiveMusicSession.delete_all ActiveMusicSession.delete_all
MusicSession.delete_all MusicSession.delete_all
Score.delete_all Score.delete_all
Score.connection.execute('delete from current_network_scores').check
end end
describe "ams_index" do describe "ams_index" do
@ -41,6 +42,9 @@ describe ApiMusicSessionsController do
end end
it "someone else with no score with self" do it "someone else with no score with self" do
#pending "this test works by itself or only others in the same spec but fails when run with some other tests from other specs"
# create a session with someone else in it, but no score # create a session with someone else in it, but no score
ams = FactoryGirl.create(:active_music_session, creator: other) ams = FactoryGirl.create(:active_music_session, creator: other)
other_conn.join_the_session(ams.music_session, true, tracks, user, 10) other_conn.join_the_session(ams.music_session, true, tracks, user, 10)
@ -127,6 +131,9 @@ describe ApiMusicSessionsController do
end end
it "someone else with no score with self" do it "someone else with no score with self" do
#pending "this test works by itself or only others in the same spec but fails when run with some other tests from other specs"
# create a session with someone else in it, but no score # create a session with someone else in it, but no score
sms = FactoryGirl.create(:music_session, creator: other) sms = FactoryGirl.create(:music_session, creator: other)

View File

@ -46,6 +46,7 @@ describe ApiScoringController do
#User.delete_all #User.delete_all
#Connection.delete_all #Connection.delete_all
Score.delete_all Score.delete_all
Score.connection.execute('delete from current_network_scores').check
end end
describe 'work' do describe 'work' do

View File

@ -17,7 +17,10 @@ describe "Musician Search", :js => true, :type => :feature, :capybara_feature =>
User.delete_all User.delete_all
austin_user.touch austin_user.touch
dallas_user.touch dallas_user.touch
Score.delete_all Score.delete_all
Score.connection.execute('delete from current_network_scores').check
Score.createx(austin_geoip[:locidispid], 'a', 1, dallas_geoip[:locidispid], 'a', 1, 10) Score.createx(austin_geoip[:locidispid], 'a', 1, dallas_geoip[:locidispid], 'a', 1, 10)
fast_signin(austin_user, "/client#/musicians") fast_signin(austin_user, "/client#/musicians")

View File

@ -144,6 +144,7 @@ describe "Notification Highlighter", :js => true, :type => :feature, :capybara_f
# we should see the count go back down to 0. # we should see the count go back down to 0.
JamRuby::Score.delete_all JamRuby::Score.delete_all
JamRuby::Score.connection.execute('delete from current_network_scores').check
JamRuby::Score.createx(1, 'a', 1, 2, 'b', 2, 10) JamRuby::Score.createx(1, 'a', 1, 2, 'b', 2, 10)
in_client(user) do in_client(user) do

View File

@ -24,7 +24,7 @@ describe "Text Message", :js => true, :type => :feature, :capybara_feature => tr
it "on find musician in musician's tile" do it "on find musician in musician's tile" do
JamRuby::Score.delete_all JamRuby::Score.delete_all
JamRuby::Score.connection.execute('delete from current_network_scores').check
JamRuby::Score.createx(locidispid_from_ip('127.0.0.1'), 'a', ip_address_to_int('127.0.0.1'), JamRuby::Score.createx(locidispid_from_ip('127.0.0.1'), 'a', ip_address_to_int('127.0.0.1'),
locidispid_from_ip('10.0.0.1'), 'a', ip_address_to_int('10.0.0.1'), locidispid_from_ip('10.0.0.1'), 'a', ip_address_to_int('10.0.0.1'),
10) 10)

View File

@ -18,6 +18,7 @@ describe "Musician Search API", :type => :api do
User.delete_all User.delete_all
Connection.delete_all Connection.delete_all
Score.delete_all Score.delete_all
Score.connection.execute('delete from current_network_scores').check
@user = FactoryGirl.create(:user, last_jam_locidispid: 1) @user = FactoryGirl.create(:user, last_jam_locidispid: 1)
@conn = FactoryGirl.create(:connection, user_id: @user.id, locidispid: 1) @conn = FactoryGirl.create(:connection, user_id: @user.id, locidispid: 1)

View File

@ -282,6 +282,7 @@ def verify_find_session_score(score, parent_selector, current_user, target_user)
expected = expected_score_info(score, current_user, target_user) expected = expected_score_info(score, current_user, target_user)
Score.connection.execute('DELETE FROM scores').check Score.connection.execute('DELETE FROM scores').check
Score.connection.execute('DELETE FROM current_network_scores').check
if score if score
create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id}, create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id},
austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped
@ -300,6 +301,7 @@ def verify_find_musician_score(score, current_user, target_user)
expected = expected_score_info(score, current_user, target_user) expected = expected_score_info(score, current_user, target_user)
Score.connection.execute('DELETE FROM scores').check Score.connection.execute('DELETE FROM scores').check
Score.connection.execute('DELETE FROM current_network_scores').check
if score if score
create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id}, create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id},
austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped
@ -318,6 +320,7 @@ def verify_session_info_score(score, current_user, target_user)
expected = expected_score_info(score, current_user, target_user) expected = expected_score_info(score, current_user, target_user)
Score.connection.execute('DELETE FROM scores').check Score.connection.execute('DELETE FROM scores').check
Score.connection.execute('DELETE FROM current_network_scores').check
if score if score
create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id}, create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id},
austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped
@ -335,6 +338,7 @@ def verify_session_detail_score(score, current_user, target_user, target_path)
expected = expected_score_info(score, current_user, target_user) expected = expected_score_info(score, current_user, target_user)
Score.connection.execute('DELETE FROM scores').check Score.connection.execute('DELETE FROM scores').check
Score.connection.execute('DELETE FROM current_network_scores').check
if score if score
create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id}, create_score(austin, dallas, { auserid: current_user.id, buserid: target_user.id},
austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped austin[:jamisp].beginip, dallas[:jamisp].beginip, 'a_client_id', 'b_client_id', score=score) # creates scores with very recent created_at, so it should be skipped