LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
ssa_event_cache.h File Reference

Port of EventCache.m and of the lookup that State.afterEvent performs against it (afterEvent.m lines 24-44 and its write-back sites). More...

#include <cstddef>
#include <map>
#include <vector>
#include "line/lang/lang_types.h"
#include "line/lang/qn/network_struct.h"
#include "line/lang/qn/state_events.h"
#include "line/num/number.h"
#include "line/util/error.h"
Include dependency graph for ssa_event_cache.h:

Go to the source code of this file.

Classes

struct  line::ssa::SsaEventKey
 The memoization key: the argument list of after_event, in fields. More...
class  line::ssa::SsaEventCache< T >
 EventCache: the per-state enabled-event memo of the serial SSA engine. More...

Namespaces

namespace  line
namespace  line::ssa

Detailed Description

Port of EventCache.m and of the lookup that State.afterEvent performs against it (afterEvent.m lines 24-44 and its write-back sites).

WHAT IS BEING MEMOIZED, AND WHY IT IS SOUND. after_event is a pure function of (sn, ind, inspace, event, cls, no_promote, aux_rate): it reads no mutable state, draws no random number and touches nothing outside its arguments. So its value may be stored against those arguments and returned again, and a hit is EXACTLY what recomputation would produce. That is the whole correctness condition, and it is the one the tests assert directly, state by state, rather than inferring it from the metrics.

THE KEY IS THE WHOLE ARGUMENT LIST. The reference keys on mat2str([ind, event, class, noPromote, inspace]), and each of those five pieces earns its place: noPromote distinguishes the departure half of an immediate-feedback self-loop (which leaves the vacated server held) from an ordinary departure at the same station in the same state, and dropping it would return one where the other was asked for. This port keys on the same five plus aux_rate, which the C++ handler takes and MATLAB does not: it is the rate carried into the RENEGE, RETRY, FAILURE and REPAIR branches, so two calls that differ only in it have different answers.

A HIT AND A MISS ARE INDISTINGUISHABLE HERE, WHICH IS STRONGER THAN THE REFERENCE. MATLAB stores the full enumeration and then, on a hit, SAMPLES one successor row from it, spending a rand. This port's after_event is the enumeration-mode handler in every case and the sampling happens downstream in the engine, so enabling the cache changes neither the value nor the random stream. The seed-fixed sample path is therefore identical with and without caching, which is what lets a test compare the two runs bit for bit.

THE CACHE IS BOUND TO ONE sn. The reference's create takes sn and ignores it (its loops are commented out). Here it is retained and checked: the memoized value is computed from the rates, capacities and routing of one network struct, so serving it to a query about a different struct would return another model's successors. The binding is a pointer identity test because the engines hold sn by const reference for their whole lifetime.

A DISABLED CACHE IS NOT AN ABSENT ONE. EventCache.create(false, sn) returns [] and afterEvent then takes the uncached path. Here a disabled cache is an object that computes on every call and stores nothing, so the caller has one code path rather than two and cannot accidentally diverge between them.

Definition in file ssa_event_cache.h.