-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathNormalDynamicSlice.m
115 lines (105 loc) · 3.66 KB
/
NormalDynamicSlice.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
classdef NormalDynamicSlice < DynamicSlice
%% Constructor
methods
function this = NormalDynamicSlice(slice_data)
if nargin == 0
args = {};
else
args = {slice_data};
end
this@DynamicSlice(args{:});
end
end
%% Public Methods
methods
function op = getOptimizer(this, options)
if nargin == 1
this.op = NormalDynamicSliceOptimizer(this);
else
this.op = NormalDynamicSliceOptimizer(this, options);
end
op = this.op;
op.initializeState();
end
function finalize(this, prices)
finalize@DynamicSlice(this, prices);
end
function c = getLinkCapacity(this, isfinal)
if nargin == 1 || isfinal
c = this.Links.Capacity;
else
if this.Optimizer.invoke_method == 0
c = getLinkCapacity@NormalSlice(this, isfinal);
else
c = this.op.temp_vars.c;
end
end
end
function c = getNodeCapacity(this, isfinal) % isfinal=true by default
if nargin == 1 || isfinal
c = this.ServiceNodes.Capacity;
else
if this.Optimizer.invoke_method == 0
c = getNodeCapacity@NormalSlice(this, isfinal);
else
% since we do not reconfigure VNF capacity through fast slice reconfiguration,
% the sum of VNF capacity equals to the node capacity.
c = sum(reshape(this.op.temp_vars.v, ...
this.NumberServiceNodes,this.NumberVNFs),2);
end
end
end
end
methods (Access = protected)
function release_resource_description(this)
error('error: not implemented!');
%% Release Unused Resource Description
% Release unused resource description: datacenters, nodes, links;
% A link is unused when its capcity is zero and no (candidate paths of) flow uses
% it;
% A node is unused only when all adjecent links are unused; If a node is unused
% and it is co-located with a DC, the DC must also be unused.
% A datacenter is unused when its capcacity is zero, and the co-located node is
% unused.
this.save_state;
b_removed_dcs = this.ServiceNodes.Capacity <= eps;
b_removed_links = this.Links.Capacity <= eps;
%%
if ~isempty(this.op.I_flow_path)
for i = 1:this.NumberFlows
b_removed_links(this.op.I_flow_edge(i,:)) = false;
end
end % otherwise existing flows potentially use all edges.
b_removed_nodes = this.graph.Remove([], b_removed_links);
%% Update variables
% see also <OnRemoveFlow>.
% A node can be removed only when the co-located DC should be removed.
if ~isempty(intersect(this.ServiceNodes{~b_removed_dcs, 'VirtualNode'},...
find(b_removed_nodes)))
error('error: datacenter is still alive while the colocated node is removed.');
end
if ~isempty(intersect(this.ServiceNodes{b_removed_dcs, 'VirtualNode'},...
find(~b_removed_nodes)))
warning('datacenter to be removed before the co-located node.');
end
b_removed_dcs = b_removed_dcs & (b_removed_nodes(this.ServiceNodes.VirtualNode));
this.net_changes.NodeIndex = find(b_removed_nodes);
this.net_changes.DCIndex = find(b_removed_dcs);
this.net_changes.LinkIndex = find(b_removed_links);
this.op.identify_change([]);
this.op.I_edge_path(b_removed_links, :) = [];
this.op.Variables.z(this.changed_index.z) = [];
this.op.Variables.v(this.changed_index.v) = [];
% this.vnf_reconfig_cost(this.changed_index.v) = [];
%% Update resources
this.Links(b_removed_links,:) = [];
this.Nodes(b_removed_nodes,:) = [];
this.ServiceNodes(b_removed_dcs, :) = [];
dc_node_index = find(this.Nodes.ServiceNode~=0);
this.Nodes{dc_node_index, 'ServiceNode'} = 1:this.NumberServiceNodes;
this.ServiceNodes.VirtualNode = dc_node_index;
this.op.OnUpdateResources('release');
warning('Debug Required!');
end
end
end