Commit 9286e781 authored by 神楽坂玲奈's avatar 神楽坂玲奈

what

parent dda8dbff
Pipeline #1793 failed with stages
...@@ -2,6 +2,8 @@ dgram = require 'dgram' ...@@ -2,6 +2,8 @@ dgram = require 'dgram'
assert = require 'assert' assert = require 'assert'
http = require 'http' http = require 'http'
Quality = require './quality'
server_port = 495 server_port = 495
timeout = 10 timeout = 10
...@@ -45,143 +47,86 @@ timeout_timer = null ...@@ -45,143 +47,86 @@ timeout_timer = null
socket = dgram.createSocket('udp4') socket = dgram.createSocket('udp4')
caculate_metric = (delay, jitter, reliability, cost)-> route_quality = (from, to, next_hop = servers[from].next_hop[to])->
assert(jitter >= 0) assert next_hop?
assert(0 <= reliability <= 1, "reliability: #{reliability}") assert from != next_hop
assert(cost >= 0) assert from != to
delay + (1 - reliability) * 6 + cost * 0.1
route_metric = (server_id, from, to, next_hop)->
#console.log "route_metric(#{server_id}, #{from}, #{to}, #{next_hop})"
# delay 由于涉及时差问题,对内、对外、补偿权重必须是一致的。 result = new Quality()
# 其他几个变量对内、对外权重可以不一致。
delay = 0 current = from
internal_reliability = 1
internal_jitter = 0
internal_cost = 0
external_reliability = 1
external_jitter = 0
external_cost = 0
current = server_id
next = next_hop next = next_hop
route = [current, next] route = [current, next]
# 正向路由
while true while true
if next == 0 # from server_id to region_id 型路由到达出口 quality = servers[next].quality[current]
assert(from != 0) return Quality.unreachable if !quality or quality.reliability <= 0 # 网络不通,视为黑洞
quality = gateways[current][to] result.concat(quality.delay, quality.jitter, quality.reliability, servers[current].outbound_cost + servers[next].inbound_cost)
return Number.POSITIVE_INFINITY if !quality or quality.reliability <= 0 # 网络不通,视为黑洞 return result if next == to # 到达
#console.log '-gateway-', current, to, quality
delay += quality.delay # 寻找下一跳
external_reliability *= Math.sqrt(quality.reliability) current = next
external_jitter += quality.jitter / 2 next = servers[current].next_hop[to]
external_cost += servers[current].outbound_cost assert next #to server_id 型路由,由于 server 两两相连,下一跳一定是存在的,最坏情况也是直达
internal_reliability *= Math.sqrt(quality.reliability) if next in route # 环路
internal_jitter += quality.jitter / 2 return Quality.unreachable
internal_cost += servers[current].inbound_cost
if current == from # 出口直达
return caculate_metric(delay, internal_jitter + external_jitter, internal_reliability * external_reliability, internal_cost + external_cost)
next = servers[current].routes[0][from]
route = [current, next]
while true # 计算返程路线
# 计算网络质量
quality = servers[next].quality[current]
return Number.POSITIVE_INFINITY if !quality or quality.reliability <= 0 # 网络不通,视为黑洞
#console.log '-2-', current, next, quality
delay += quality.delay
internal_jitter += quality.jitter
internal_reliability *= quality.reliability
internal_cost += servers[current].outbound_cost + servers[next].inbound_cost
# 寻找下一跳
if next == from # 往返路径结束
return caculate_metric(delay, internal_jitter + external_jitter, internal_reliability * external_reliability, internal_cost + external_cost)
else
current = next
next = servers[current].routes[0][from]
assert(next?) # 返程的目标是server,相当于 from all to server_id 型路由,由于 server 两两相连,下一跳一定是存在的,最坏情况也是直达
if next in route # 环路
return Number.POSITIVE_INFINITY
else
route.push next
else else
# 计算网络质量 route.push next
quality = servers[next].quality[current]
return Number.POSITIVE_INFINITY if !quality or quality.reliability <= 0 # 网络不通,视为黑洞 route_metric = (from, to, next_hop)->
#console.log '-3-', current, next, quality route_quality(from, to, next_hop).metric()
delay += quality.delay
gateway_metric = (from, to, gateway)->
if from == 0 # 对内 quality = gateways[gateway][to]
internal_reliability *= quality.reliability assert quality
internal_jitter += quality.jitter result = new Quality(quality.delay, quality.jitter, quality.reliability, servers[gateway].outbound_cost + servers[gateway].inbound_cost)
internal_cost += servers[current].outbound_cost + servers[next].inbound_cost if from != gateway
if next == to result.concat route_quality(from, gateway)
return caculate_metric(delay, internal_jitter + external_jitter, internal_reliability * external_reliability, internal_cost + external_cost) result.concat route_quality(gateway, from)
else result.metric()
external_reliability *= quality.reliability
external_jitter += quality.jitter update_route = (server, to)->
external_cost += servers[current].outbound_cost + servers[next].inbound_cost # 计算当前和最优路线
if to.name? # is region
# 寻找下一跳 type = 'gateway'
current = next current_route = server[type][to.id]
next = servers[current].routes[from][to] if current_route
if next? current_metric = gateway_metric(server.id, to.id, current_route)
if next in route # 环路 else
return Number.POSITIVE_INFINITY current_metric = Number.POSITIVE_INFINITY
else best_route = current_route
route.push next best_metric = current_metric
else for index, route_server of servers when route_server.id != current_route and gateways[route_server.id]? and gateways[route_server.id][to.id]
assert(from != 0) # from all to server_id 型路由,由于 server 两两相连,下一跳一定是存在的,最坏情况也是直达 metric = gateway_metric(server.id, to.id, route_server.id)
return Number.POSITIVE_INFINITY # 对于from server_id to region 型路由,如果下一跳不存在,意味着出口没有已知路线可达,是黑洞 if metric < best_metric
best_route = route_server.id
best_metric = metric
# 返程 (下行) 路由
#console.log '-2-', next
update_route = (server, from, to)->
current_next_hop = server.routes[from][to]
# 计算当前路线
if current_next_hop?
current_metric = route_metric(server.id, from, to, current_next_hop)
else else
assert(from != 0) # from all to server_id 型路由,由于 server 两两相连,下一跳一定是存在的,最坏情况也是直达 assert(to.inbound_cost?) # is server
current_metric = Number.POSITIVE_INFINITY # 对于from server_id to region 型路由,如果下一跳不存在,意味着出口没有已知路线可达,是黑洞 type = 'next_hop'
current_route = server[type][to.id]
# 计算更优路线 assert(current_route) # 对于 to server 型路由,下一跳一定是存在的
best_next_hop = current_next_hop current_metric = route_metric(server.id, to.id, current_route)
best_metric = current_metric best_route = current_route
best_metric = current_metric
for index, next_hop_server of servers when next_hop_server.id != current_next_hop and next_hop_server != server and next_hop_server.id != from for index, route_server of servers when route_server.id != current_route and route_server.id != server.id # 对于 to server型路由,下一跳是自己是没有意义的
#console.log parseInt(next_hop), server.id metric = route_metric(server.id, to.id, route_server.id)
#console.log next_hop,current_next_hop if metric < best_metric
metric = route_metric(server.id, from, to, next_hop_server.id) best_route = route_server.id
if metric < best_metric best_metric = metric
best_next_hop = next_hop_server.id
best_metric = metric # 决定是否变更
if from != 0
metric = route_metric(server.id, from, to, 0)
if metric < best_metric
best_next_hop = 0
best_metric = metric
now = new Date().getTime() / 1000 now = new Date().getTime() / 1000
if current_next_hop != best_next_hop and (current_metric is Number.POSITIVE_INFINITY or (current_metric - best_metric - 0.01) * (now - server.updated_at[from][to]) > 10) if current_route != best_route and (current_metric is Number.POSITIVE_INFINITY or (current_metric - best_metric - 0.01) * (now - server[type+'_updated_at'][to.id]) > 10)
console.log "update ##{sequence}: server#{server.id} from #{from} to #{to} next hop #{current_next_hop}(#{current_metric}) -> #{best_next_hop}(#{best_metric})" console.log server[type+'_updated_at'][to.id],server[type+'_updated_at'], to.id
server.routes[from][to] = best_next_hop console.log "update ##{sequence}: #{type} server #{server.id} to #{to.id}: #{current_route}(#{current_metric}) -> #{best_route}(#{best_metric}) age #{now - server[type+'_updated_at'][to.id]}"
server.updated_at[from][to] = now server[type][to.id] = best_route
server[type+'_updated_at'][to.id] = now
updating = setInterval -> updating = setInterval ->
send_route(server, from, to, best_next_hop) send_route server, to.id, best_route, type
, 1000 , 1000
send_route(server, from, to, best_next_hop) send_route server, to.id, best_route, type
timeout_timer = setTimeout -> timeout_timer = setTimeout ->
delete server.address delete server.address
delete server.port delete server.port
...@@ -192,38 +137,29 @@ update_route = (server, from, to)-> ...@@ -192,38 +137,29 @@ update_route = (server, from, to)->
return true return true
false false
send_route = (server, from, to, next_hop)->
message = {sequence: sequence, from: from, to: to, next_hop: next_hop} send_route = (server, to, route, type)->
if server == from message = {sequence: sequence, to: to}
gateway = server message[type] = route
while next_hop != 0
gateway = next_hop
next_hop = servers[gateway].routes[from][to]
message.gateway = gateway
message = JSON.stringify message message = JSON.stringify message
socket.send message, 0, message.length, server.port, server.address socket.send message, 0, message.length, server.port, server.address
reset_route = (server)-> reset_route = (server)->
now = new Date().getTime() / 1000 now = new Date().getTime() / 1000
server.quality = {} server.quality = {}
# 目标地址是 server 的 from all to server_id 型路由, routes[0][server_id], 对于直连目标节点的,next_hop = server_id server.next_hop = {}
# 目标地址是 region 的 from server_id to region_id 型路由, routes[server_id][region_id], 对于直连出口的,next_hop = 0 server.next_hop_updated_at = {}
server.routes = {} server.gateway = {}
server.updated_at = {} server.gateway_updated_at = {}
server.routes[0] = {}
server.updated_at[0] = {}
for i,s of servers for i,s of servers
server.routes[0][i] = parseInt(i) server.next_hop[s.id] = s.id
server.updated_at[0][i] = now server.next_hop_updated_at[s.id] = now
server.routes[i] = {} for region_id, region of regions when gateways[server.id]? and gateways[server.id][region_id]?
server.updated_at[i] = {} server.gateway[region_id] = server.id
for region_id, region of regions when gateways[server.id]? and gateways[server.id][region_id]? server.gateway_updated_at[region_id] = now
server.routes[i][region_id] = 0
server.updated_at[i][region_id] = now
socket.on 'message', (message, rinfo) -> socket.on 'message', (message, rinfo) ->
message = JSON.parse(message) message = JSON.parse(message)
#console.log message
server = servers[message.server_id] server = servers[message.server_id]
return unless server? return unless server?
...@@ -244,12 +180,11 @@ socket.on 'message', (message, rinfo) -> ...@@ -244,12 +180,11 @@ socket.on 'message', (message, rinfo) ->
sequence += 1 sequence += 1
if !updating? if !updating?
for server_id, server of servers when server.address? for i, server of servers when server.address?
for to of servers when to != server_id for j, to_server of servers when server.id != to_server.id
return if update_route(server, 0, parseInt(to)) return if update_route(server, to_server)
for from of servers for j, to_region of regions
for region in regions return if update_route(server, to_region)
return if update_route(server, parseInt(from), region.id)
for server_id, server of servers for server_id, server of servers
reset_route(server) reset_route(server)
......
// Generated by CoffeeScript 1.9.3 // Generated by CoffeeScript 1.9.3
(function() { (function() {
var assert, caculate_metric, dgram, gateways, http, regions, reset_route, route_metric, send_route, sequence, server, server_id, server_port, servers, socket, timeout, timeout_timer, update_route, updating, var Quality, assert, dgram, gateway_metric, gateways, http, regions, reset_route, route_metric, route_quality, send_route, sequence, server, server_id, server_port, servers, socket, timeout, timeout_timer, update_route, updating,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
dgram = require('dgram'); dgram = require('dgram');
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
http = require('http'); http = require('http');
Quality = require('./quality');
server_port = 495; server_port = 495;
timeout = 10; timeout = 10;
...@@ -124,138 +126,107 @@ ...@@ -124,138 +126,107 @@
socket = dgram.createSocket('udp4'); socket = dgram.createSocket('udp4');
caculate_metric = function(delay, jitter, reliability, cost) { route_quality = function(from, to, next_hop) {
assert(jitter >= 0); var current, next, quality, result, route;
assert((0 <= reliability && reliability <= 1), "reliability: " + reliability); if (next_hop == null) {
assert(cost >= 0); next_hop = servers[from].next_hop[to];
return delay + (1 - reliability) * 6 + cost * 0.1; }
}; assert(next_hop != null);
assert(from !== next_hop);
route_metric = function(server_id, from, to, next_hop) { assert(from !== to);
var current, delay, external_cost, external_jitter, external_reliability, internal_cost, internal_jitter, internal_reliability, next, quality, route; result = new Quality();
delay = 0; current = from;
internal_reliability = 1;
internal_jitter = 0;
internal_cost = 0;
external_reliability = 1;
external_jitter = 0;
external_cost = 0;
current = server_id;
next = next_hop; next = next_hop;
route = [current, next]; route = [current, next];
while (true) { while (true) {
if (next === 0) { quality = servers[next].quality[current];
assert(from !== 0); if (!quality || quality.reliability <= 0) {
quality = gateways[current][to]; return Quality.unreachable;
if (!quality || quality.reliability <= 0) { }
return Number.POSITIVE_INFINITY; result.concat(quality.delay, quality.jitter, quality.reliability, servers[current].outbound_cost + servers[next].inbound_cost);
} if (next === to) {
delay += quality.delay; return result;
external_reliability *= Math.sqrt(quality.reliability); }
external_jitter += quality.jitter / 2; current = next;
external_cost += servers[current].outbound_cost; next = servers[current].next_hop[to];
internal_reliability *= Math.sqrt(quality.reliability); assert(next);
internal_jitter += quality.jitter / 2; if (indexOf.call(route, next) >= 0) {
internal_cost += servers[current].inbound_cost; return Quality.unreachable;
if (current === from) {
return caculate_metric(delay, internal_jitter + external_jitter, internal_reliability * external_reliability, internal_cost + external_cost);
}
next = servers[current].routes[0][from];
route = [current, next];
while (true) {
quality = servers[next].quality[current];
if (!quality || quality.reliability <= 0) {
return Number.POSITIVE_INFINITY;
}
delay += quality.delay;
internal_jitter += quality.jitter;
internal_reliability *= quality.reliability;
internal_cost += servers[current].outbound_cost + servers[next].inbound_cost;
if (next === from) {
return caculate_metric(delay, internal_jitter + external_jitter, internal_reliability * external_reliability, internal_cost + external_cost);
} else {
current = next;
next = servers[current].routes[0][from];
assert(next != null);
if (indexOf.call(route, next) >= 0) {
return Number.POSITIVE_INFINITY;
} else {
route.push(next);
}
}
}
} else { } else {
quality = servers[next].quality[current]; route.push(next);
if (!quality || quality.reliability <= 0) {
return Number.POSITIVE_INFINITY;
}
delay += quality.delay;
if (from === 0) {
internal_reliability *= quality.reliability;
internal_jitter += quality.jitter;
internal_cost += servers[current].outbound_cost + servers[next].inbound_cost;
if (next === to) {
return caculate_metric(delay, internal_jitter + external_jitter, internal_reliability * external_reliability, internal_cost + external_cost);
}
} else {
external_reliability *= quality.reliability;
external_jitter += quality.jitter;
external_cost += servers[current].outbound_cost + servers[next].inbound_cost;
}
current = next;
next = servers[current].routes[from][to];
if (next != null) {
if (indexOf.call(route, next) >= 0) {
return Number.POSITIVE_INFINITY;
} else {
route.push(next);
}
} else {
assert(from !== 0);
return Number.POSITIVE_INFINITY;
}
} }
} }
}; };
update_route = function(server, from, to) { route_metric = function(from, to, next_hop) {
var best_metric, best_next_hop, current_metric, current_next_hop, index, metric, next_hop_server, now; return route_quality(from, to, next_hop).metric();
current_next_hop = server.routes[from][to]; };
if (current_next_hop != null) {
current_metric = route_metric(server.id, from, to, current_next_hop); gateway_metric = function(from, to, gateway) {
} else { var quality, result;
assert(from !== 0); quality = gateways[gateway][to];
current_metric = Number.POSITIVE_INFINITY; assert(quality);
result = new Quality(quality.delay, quality.jitter, quality.reliability, servers[gateway].outbound_cost + servers[gateway].inbound_cost);
if (from !== gateway) {
result.concat(route_quality(from, gateway));
result.concat(route_quality(gateway, from));
} }
best_next_hop = current_next_hop; return result.metric();
best_metric = current_metric; };
for (index in servers) {
next_hop_server = servers[index]; update_route = function(server, to) {
if (!(next_hop_server.id !== current_next_hop && next_hop_server !== server && next_hop_server.id !== from)) { var best_metric, best_route, current_metric, current_route, index, metric, now, route_server, type;
continue; if (to.name != null) {
type = 'gateway';
current_route = server[type][to.id];
if (current_route) {
current_metric = gateway_metric(server.id, to.id, current_route);
} else {
current_metric = Number.POSITIVE_INFINITY;
} }
metric = route_metric(server.id, from, to, next_hop_server.id); best_route = current_route;
if (metric < best_metric) { best_metric = current_metric;
best_next_hop = next_hop_server.id; for (index in servers) {
best_metric = metric; route_server = servers[index];
if (!(route_server.id !== current_route && (gateways[route_server.id] != null) && gateways[route_server.id][to.id])) {
continue;
}
metric = gateway_metric(server.id, to.id, route_server.id);
if (metric < best_metric) {
best_route = route_server.id;
best_metric = metric;
}
} }
} } else {
if (from !== 0) { assert(to.inbound_cost != null);
metric = route_metric(server.id, from, to, 0); type = 'next_hop';
if (metric < best_metric) { current_route = server[type][to.id];
best_next_hop = 0; assert(current_route);
best_metric = metric; current_metric = route_metric(server.id, to.id, current_route);
best_route = current_route;
best_metric = current_metric;
for (index in servers) {
route_server = servers[index];
if (!(route_server.id !== current_route && route_server.id !== server.id)) {
continue;
}
metric = route_metric(server.id, to.id, route_server.id);
if (metric < best_metric) {
best_route = route_server.id;
best_metric = metric;
}
} }
} }
now = new Date().getTime() / 1000; now = new Date().getTime() / 1000;
if (current_next_hop !== best_next_hop && (current_metric === Number.POSITIVE_INFINITY || (current_metric - best_metric - 0.01) * (now - server.updated_at[from][to]) > 10)) { if (current_route !== best_route && (current_metric === Number.POSITIVE_INFINITY || (current_metric - best_metric - 0.01) * (now - server[type + '_updated_at'][to.id]) > 10)) {
console.log("update #" + sequence + ": server" + server.id + " from " + from + " to " + to + " next hop " + current_next_hop + "(" + current_metric + ") -> " + best_next_hop + "(" + best_metric + ")"); console.log(server[type + '_updated_at'][to.id], server[type + '_updated_at'], to.id);
server.routes[from][to] = best_next_hop; console.log("update #" + sequence + ": " + type + " server " + server.id + " to " + to.id + ": " + current_route + "(" + current_metric + ") -> " + best_route + "(" + best_metric + ") age " + (now - server[type + '_updated_at'][to.id]));
server.updated_at[from][to] = now; server[type][to.id] = best_route;
server[type + '_updated_at'][to.id] = now;
updating = setInterval(function() { updating = setInterval(function() {
return send_route(server, from, to, best_next_hop); return send_route(server, to.id, best_route, type);
}, 1000); }, 1000);
send_route(server, from, to, best_next_hop); send_route(server, to.id, best_route, type);
timeout_timer = setTimeout(function() { timeout_timer = setTimeout(function() {
delete server.address; delete server.address;
delete server.port; delete server.port;
...@@ -268,22 +239,13 @@ ...@@ -268,22 +239,13 @@
return false; return false;
}; };
send_route = function(server, from, to, next_hop) { send_route = function(server, to, route, type) {
var gateway, message; var message;
message = { message = {
sequence: sequence, sequence: sequence,
from: from, to: to
to: to,
next_hop: next_hop
}; };
if (server === from) { message[type] = route;
gateway = server;
while (next_hop !== 0) {
gateway = next_hop;
next_hop = servers[gateway].routes[from][to];
}
message.gateway = gateway;
}
message = JSON.stringify(message); message = JSON.stringify(message);
return socket.send(message, 0, message.length, server.port, server.address); return socket.send(message, 0, message.length, server.port, server.address);
}; };
...@@ -292,36 +254,29 @@ ...@@ -292,36 +254,29 @@
var i, now, region, region_id, results, s; var i, now, region, region_id, results, s;
now = new Date().getTime() / 1000; now = new Date().getTime() / 1000;
server.quality = {}; server.quality = {};
server.routes = {}; server.next_hop = {};
server.updated_at = {}; server.next_hop_updated_at = {};
server.routes[0] = {}; server.gateway = {};
server.updated_at[0] = {}; server.gateway_updated_at = {};
results = [];
for (i in servers) { for (i in servers) {
s = servers[i]; s = servers[i];
server.routes[0][i] = parseInt(i); server.next_hop[s.id] = s.id;
server.updated_at[0][i] = now; server.next_hop_updated_at[s.id] = now;
server.routes[i] = {}; }
server.updated_at[i] = {}; results = [];
results.push((function() { for (region_id in regions) {
var results1; region = regions[region_id];
results1 = []; if (!((gateways[server.id] != null) && (gateways[server.id][region_id] != null))) {
for (region_id in regions) { continue;
region = regions[region_id]; }
if (!((gateways[server.id] != null) && (gateways[server.id][region_id] != null))) { server.gateway[region_id] = server.id;
continue; results.push(server.gateway_updated_at[region_id] = now);
}
server.routes[i][region_id] = 0;
results1.push(server.updated_at[i][region_id] = now);
}
return results1;
})());
} }
return results; return results;
}; };
socket.on('message', function(message, rinfo) { socket.on('message', function(message, rinfo) {
var from, j, len, region, server, server_id, to; var i, j, server, to_region, to_server;
message = JSON.parse(message); message = JSON.parse(message);
server = servers[message.server_id]; server = servers[message.server_id];
if (server == null) { if (server == null) {
...@@ -341,24 +296,23 @@ ...@@ -341,24 +296,23 @@
sequence += 1; sequence += 1;
} }
if (updating == null) { if (updating == null) {
for (server_id in servers) { for (i in servers) {
server = servers[server_id]; server = servers[i];
if (!(server.address != null)) { if (!(server.address != null)) {
continue; continue;
} }
for (to in servers) { for (j in servers) {
if (to !== server_id) { to_server = servers[j];
if (update_route(server, 0, parseInt(to))) { if (server.id !== to_server.id) {
if (update_route(server, to_server)) {
return; return;
} }
} }
} }
for (from in servers) { for (j in regions) {
for (j = 0, len = regions.length; j < len; j++) { to_region = regions[j];
region = regions[j]; if (update_route(server, to_region)) {
if (update_route(server, parseInt(from), region.id)) { return;
return;
}
} }
} }
} }
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"main.coffee" "main.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }
\ No newline at end of file
assert = require 'assert'
module.exports = class Quality
constructor: (@delay=0, @jitter=0, @reliability=1, @cost=0)->
@unreachable: new Quality(0,0,0,0)
concat: (delay, jitter, reliability, cost)->
if delay instanceof Quality
@concat(delay.delay, delay.jitter, delay.reliability, delay.cost)
else
@delay += delay
@jitter += jitter
@reliability *= reliability
@cost += cost
this
# 若 reliability = 0,metric 应为 +∞
# 对于两条路线,同时连接任何一个相同的(reliability > 0的)线路,大小关系不变
metric: ()->
assert(@jitter >= 0)
assert(0 <= @reliability <= 1)
assert(@cost >= 0)
if @reliability == 0
Number.POSITIVE_INFINITY
else
@delay + (1 - @reliability) * 6 + @cost * 0.1
// Generated by CoffeeScript 1.9.3
(function() {
var Quality, assert;
assert = require('assert');
module.exports = Quality = (function() {
function Quality(delay1, jitter1, reliability1, cost1) {
this.delay = delay1 != null ? delay1 : 0;
this.jitter = jitter1 != null ? jitter1 : 0;
this.reliability = reliability1 != null ? reliability1 : 1;
this.cost = cost1 != null ? cost1 : 0;
}
Quality.unreachable = new Quality(0, 0, 0, 0);
Quality.prototype.concat = function(delay, jitter, reliability, cost) {
if (delay instanceof Quality) {
this.concat(delay.delay, delay.jitter, delay.reliability, delay.cost);
} else {
this.delay += delay;
this.jitter += jitter;
this.reliability *= reliability;
this.cost += cost;
}
return this;
};
Quality.prototype.metric = function() {
var ref;
assert(this.jitter >= 0);
assert((0 <= (ref = this.reliability) && ref <= 1));
assert(this.cost >= 0);
if (this.reliability === 0) {
return Number.POSITIVE_INFINITY;
} else {
return this.delay + (1 - this.reliability) * 6 + this.cost * 0.1;
}
};
return Quality;
})();
}).call(this);
//# sourceMappingURL=quality.js.map
{
"version": 3,
"file": "quality.js",
"sourceRoot": "",
"sources": [
"quality.coffee"
],
"names": [],
"mappings": ";AAAA;AAAA,MAAA;;EAAA,MAAA,GAAS,OAAA,CAAQ,QAAR;;EAET,MAAM,CAAC,OAAP,GAAuB;IACR,iBAAC,MAAD,EAAW,OAAX,EAAsB,YAAtB,EAAsC,KAAtC;MAAC,IAAC,CAAA,yBAAD,SAAO;MAAG,IAAC,CAAA,2BAAD,UAAQ;MAAG,IAAC,CAAA,qCAAD,eAAa;MAAG,IAAC,CAAA,uBAAD,QAAM;IAA5C;;IAEb,OAAC,CAAA,WAAD,GAAkB,IAAA,OAAA,CAAQ,CAAR,EAAU,CAAV,EAAY,CAAZ,EAAc,CAAd;;sBAGlB,MAAA,GAAQ,SAAC,KAAD,EAAQ,MAAR,EAAgB,WAAhB,EAA6B,IAA7B;MACN,IAAG,KAAA,YAAiB,OAApB;QACE,IAAC,CAAA,MAAD,CAAQ,KAAK,CAAC,KAAd,EAAqB,KAAK,CAAC,MAA3B,EAAmC,KAAK,CAAC,WAAzC,EAAsD,KAAK,CAAC,IAA5D,EADF;OAAA,MAAA;QAGE,IAAC,CAAA,KAAD,IAAU;QACV,IAAC,CAAA,MAAD,IAAW;QACX,IAAC,CAAA,WAAD,IAAgB;QAChB,IAAC,CAAA,IAAD,IAAS,KANX;;aAOA;IARM;;sBAYR,MAAA,GAAQ,SAAA;AACN,UAAA;MAAA,MAAA,CAAO,IAAC,CAAA,MAAD,IAAW,CAAlB;MACA,MAAA,CAAO,CAAA,CAAA,WAAK,IAAC,CAAA,YAAN,OAAA,IAAqB,CAArB,CAAP;MACA,MAAA,CAAO,IAAC,CAAA,IAAD,IAAS,CAAhB;MACA,IAAG,IAAC,CAAA,WAAD,KAAgB,CAAnB;eACE,MAAM,CAAC,kBADT;OAAA,MAAA;eAGE,IAAC,CAAA,KAAD,GAAS,CAAC,CAAA,GAAI,IAAC,CAAA,WAAN,CAAA,GAAqB,CAA9B,GAAkC,IAAC,CAAA,IAAD,GAAQ,IAH5C;;IAJM;;;;;AApBV"
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment