LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
cache_gamma.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2012-2026, QORE Lab, Imperial College London
3
* All rights reserved.
4
*/
5
#ifndef LINE_API_CACHE_GAMMA_H
6
#define LINE_API_CACHE_GAMMA_H
7
8
/**
9
* @file
10
* @ingroup api_cache
11
* Access factors of a multi-list cache whose lists form a general access GRAPH.
12
*
13
* Templated port of jar/src/main/java/jline/api/cache/Cache_gamma.java. MATLAB
14
* has no counterpart: it carries only cache_gamma_lp, the specialization to a
15
* tree ("linear path"), which recovers the path by walking the unique parent
16
* relation and rejects a node with two parents.
17
*
18
* Here the structure is only required to be reachable. The path is the
19
* BREADTH-FIRST shortest path in the access graph of item i, so a node with
20
* several parents is admissible and the first shortest path found in node order
21
* is the one taken. Along that path,
22
*
23
* gamma(i,j) = (sum_v lambda(v,i,0)) prod_{edges (a,b)} sum_v lambda(v,i,a) R{v,i}(a,b)
24
*
25
* THREE DIVERGENCES FROM cache_gamma_lp, all faithful to the JAR and all of
26
* them changing the number, so a caller must not treat the two as substitutes:
27
* - THE DESTINATION IS NODE j, NOT NODE j+1. cache_gamma_lp walks to node l+1
28
* for column l, node 0 being the miss list; this walks to node j. Column 0
29
* therefore has the trivial one-node path and carries NO edge factor at all,
30
* where the tree version carries the miss-to-first-list edge.
31
* - the leading factor is the aggregate miss-node request rate sum_v
32
* lambda(v,i,0), whereas the tree version starts the product at one;
33
* - each edge factor reads lambda(v,i,a) at the SOURCE node a alone, whereas
34
* the tree version sums lambda(v,i,t) over every t <= a.
35
* The first of these is hard to read as anything but an off-by-one against the
36
* shared meaning of gamma. It is reproduced rather than corrected because this
37
* routine exists only in the JAR -- MATLAB has no cache_gamma to arbitrate, and
38
* no solver in any codebase calls it (only a JUnit import does), so "fixing" it
39
* would leave the C++ disagreeing with the sole reference that defines it. Use
40
* cache_gamma_lp for the access factors a cache solver consumes.
41
*
42
* An unreachable node gives gamma(i,j) = 0, which unlike the tree version is a
43
* REACHABLE branch here: the BFS genuinely returns no path.
44
*
45
* THE GRAPH IS READ FROM USER 0 ONLY. The JAR takes R.get(0).get(i) for the
46
* adjacency and then sums the per-user rates along that one path, so a model
47
* whose users route an item differently is analysed on the first user's graph.
48
* Reproduced rather than corrected, since changing it would silently move the
49
* answer for every such model.
50
*
51
* Arithmetic: EXACT-CAPABLE. Sums and products only; the BFS is pure integer
52
* bookkeeping and tests adjacency against zero, which is exact in any T.
53
*/
54
55
#include <cstddef>
56
#include <deque>
57
#include <vector>
58
59
#include "
line/num/number.h
"
60
#include "
line/util/error.h
"
61
#include "
line/util/matrix.h
"
62
63
namespace
line
{
64
namespace
cache
{
65
66
/** Return value of cache_gamma, mirroring the JAR's Ret.cacheGamma. */
67
template
<
class
T>
68
struct
CacheGammaGraphResult
{
69
Matrix<T>
gamma
;
///< (n x h) access factors
70
std::size_t
u
;
///< number of user streams
71
std::size_t
n
;
///< number of items
72
std::size_t
h
;
///< number of lists
73
};
74
75
namespace
detail {
76
77
/**
78
* Breadth-first shortest path from source to destination over the nonzero
79
* entries of an adjacency matrix; empty when the destination is unreachable.
80
*/
81
template
<
class
T>
82
std::vector<std::size_t> cache_bfs_path(
const
Matrix<T>
& adjacency, std::size_t source,
83
std::size_t destination) {
84
const
std::size_t n = adjacency.
rows
();
85
if
(source >= n || destination >= n)
return
std::vector<std::size_t>();
86
const
T zero =
num_traits<T>::from_int
(0);
87
std::vector<bool> visited(n,
false
);
88
std::vector<int> parent(n, -1);
89
std::deque<std::size_t> queue;
90
queue.push_back(source);
91
visited[source] =
true
;
92
while
(!queue.empty()) {
93
const
std::size_t current = queue.front();
94
queue.pop_front();
95
if
(current == destination) {
96
std::vector<std::size_t> path;
97
int
node =
static_cast<
int
>
(destination);
98
while
(node != -1) {
99
path.insert(path.begin(),
static_cast<
std::size_t
>
(node));
100
node = parent[node];
101
}
102
return
path;
103
}
104
for
(std::size_t next = 0; next < n; ++next)
105
if
(!visited[next] && adjacency(current, next) > zero) {
106
visited[next] =
true
;
107
parent[next] =
static_cast<
int
>
(current);
108
queue.push_back(next);
109
}
110
}
111
return
std::vector<std::size_t>();
112
}
113
114
}
// namespace detail
115
116
/**
117
* @brief Access factors of a multi-list cache whose lists form a general
118
* access GRAPH.
119
*
120
* @param lambda (u) matrices of size (n x (h+1)): lambda[v](i,t) is the rate at
121
* which user v requests item i while it sits at node t
122
* @param R (u x n) routing matrices of size ((h+1) x (h+1))
123
*/
124
template
<
class
T>
125
CacheGammaGraphResult<T>
cache_gamma
(
const
std::vector<
Matrix<T>
>& lambda,
126
const
std::vector<std::vector<
Matrix<T>
>>& R) {
127
if
(lambda.empty())
throw
InputError
(
"cache_gamma: no user streams"
);
128
const
std::size_t u = lambda.size();
129
const
std::size_t n = lambda[0].rows();
130
if
(lambda[0].cols() == 0)
throw
InputError
(
"cache_gamma: empty lambda"
);
131
const
std::size_t h = lambda[0].cols() - 1;
132
if
(R.size() != u)
throw
InputError
(
"cache_gamma: R and lambda disagree on the user count"
);
133
for
(std::size_t v = 0; v < u; ++v)
134
if
(R[v].size() != n)
135
throw
InputError
(
"cache_gamma: R and lambda disagree on the item count"
);
136
137
const
T zero =
num_traits<T>::from_int
(0);
138
CacheGammaGraphResult<T>
res;
139
res.
u
= u;
140
res.
n
= n;
141
res.
h
= h;
142
res.
gamma
=
Matrix<T>
(n, h, zero);
143
144
for
(std::size_t i = 0; i < n; ++i) {
145
const
Matrix<T>
& graph = R[0][i];
146
for
(std::size_t j = 0; j < h; ++j) {
147
const
std::vector<std::size_t> Pj = detail::cache_bfs_path(graph, 0, j);
148
if
(Pj.empty())
continue
;
// unreachable list: no access factor
149
T g = zero;
150
for
(std::size_t v = 0; v < u; ++v) g += lambda[v](i, 0);
151
for
(std::size_t li = 1; li < Pj.size(); ++li) {
152
const
std::size_t a = Pj[li - 1];
153
const
std::size_t b = Pj[li];
154
T y = zero;
155
for
(std::size_t v = 0; v < u; ++v) y += lambda[v](i, a) * R[v][i](a, b);
156
g *= y;
157
}
158
res.
gamma
(i, j) = g;
159
}
160
}
161
return
res;
162
}
163
164
}
// namespace cache
165
}
// namespace line
166
167
#endif
// LINE_API_CACHE_GAMMA_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::Matrix
Definition
matrix.h:56
line::Matrix::Matrix
Matrix()
Definition
matrix.h:58
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::cache
Definition
cache_cost.h:42
line::cache::cache_gamma
CacheGammaGraphResult< T > cache_gamma(const std::vector< Matrix< T > > &lambda, const std::vector< std::vector< Matrix< T > > > &R)
Access factors of a multi-list cache whose lists form a general access GRAPH.
Definition
cache_gamma.h:125
line
Definition
aoi_dist2ph.h:52
number.h
Number-type abstraction for the templated API port.
line::cache::CacheGammaGraphResult
Return value of cache_gamma, mirroring the JAR's Ret.cacheGamma.
Definition
cache_gamma.h:68
line::cache::CacheGammaGraphResult::h
std::size_t h
number of lists
Definition
cache_gamma.h:72
line::cache::CacheGammaGraphResult::gamma
Matrix< T > gamma
(n x h) access factors
Definition
cache_gamma.h:69
line::cache::CacheGammaGraphResult::u
std::size_t u
number of user streams
Definition
cache_gamma.h:70
line::cache::CacheGammaGraphResult::n
std::size_t n
number of items
Definition
cache_gamma.h:71
line::num_traits
Definition
number.h:111
include
line
api
cache
cache_gamma.h
Generated by
1.18.0