Requires N:M (2:2) mapping.

This mapping has 11 all-to-all groups: every node on one side corresponds to every node on the other, and none is deleted or inserted. Each member carries an all N:M badge; selecting one highlights all of its counterparts, in the tree and in the code view alike.

Before

…lines 1–91 unchanged (91 lines)
92 {
93 await item.Key.CancelAsync().ConfigureAwait(false);
94 _taskRunners.Remove(item.Key);
95 }
96 }
97 }
98
99 private void Worker()
100 {
101 lock (_taskLock)
102 {
103 var fanoutConcurrency = _serverConfigurationManager.Configuration.LibraryScanFanoutConcurrency;
104 var parallelism = (fanoutConcurrency > 0 ? fanoutConcurrency : Environment.ProcessorCount) - _taskRunners.Count;
105 _logger.LogDebug("Spawn {NumberRunners} new runners.", parallelism);
106 for (int i = 0; i < parallelism; i++)
107 {
108 var stopToken = new CancellationTokenSource();
109 var combinedSource = CancellationTokenSource.CreateLinkedTokenSource(stopToken.Token, _hostApplicationLifetime.ApplicationStopping);
110 _taskRunners.Add(
111 combinedSource,
112 Task.Factory.StartNew(
…lines 113–219 unchanged (107 lines)
220 }),
221 Worker = (val) => worker((T)val, queueItem.Progress),
222 CancellationToken = cancellationToken
223 };
224 }).ToArray();
225
226 if (_serverConfigurationManager.Configuration.LibraryScanFanoutConcurrency == 1)
227 {
228 _logger.LogDebug("Process sequentially.");
229 try
230 {
231 foreach (var item in workItems)
232 {
…lines 233–317 unchanged (85 lines)

After

…lines 1–92 unchanged (92 lines)
93 await item.Key.CancelAsync().ConfigureAwait(false);
94 _taskRunners.Remove(item.Key);
95 }
96 }
97 }
98
99 private bool ShouldForceSequentialOperation()
100 {
101 // if the user either set the setting to 1 or it's unset and we have fewer than 4 cores it's better to run sequentially.
102 var fanoutSetting = _serverConfigurationManager.Configuration.LibraryScanFanoutConcurrency;
103 return fanoutSetting == 1 || (fanoutSetting <= 0 && Environment.ProcessorCount <= 3);
104 }
105
106 private int CalculateScanConcurrencyLimit()
107 {
108 // when this is invoked, we already checked ShouldForceSequentialOperation for the sequential check.
109 var fanoutConcurrency = _serverConfigurationManager.Configuration.LibraryScanFanoutConcurrency;
110 if (fanoutConcurrency <= 0)
111 {
112 // in case the user did not set a limit manually, we can assume he has 3 or more cores as already checked by ShouldForceSequentialOperation.
113 return Environment.ProcessorCount - 3;
114 }
115
116 return fanoutConcurrency;
117 }
118
119 private void Worker()
120 {
121 lock (_taskLock)
122 {
123 var operationFanout = Math.Max(0, CalculateScanConcurrencyLimit() - _taskRunners.Count);
124 _logger.LogDebug("Spawn {NumberRunners} new runners.", operationFanout);
125 for (int i = 0; i < operationFanout; i++)
126 {
127 var stopToken = new CancellationTokenSource();
128 var combinedSource = CancellationTokenSource.CreateLinkedTokenSource(stopToken.Token, _hostApplicationLifetime.ApplicationStopping);
129 _taskRunners.Add(
130 combinedSource,
131 Task.Factory.StartNew(
…lines 132–238 unchanged (107 lines)
239 }),
240 Worker = (val) => worker((T)val, queueItem.Progress),
241 CancellationToken = cancellationToken
242 };
243 }).ToArray();
244
245 if (ShouldForceSequentialOperation())
246 {
247 _logger.LogDebug("Process sequentially.");
248 try
249 {
250 foreach (var item in workItems)
251 {
…lines 252–336 unchanged (85 lines)

Before

compilation_unit
using_directive
using "using"
identifier "System"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "System"
. "."
identifier "Collections"
. "."
identifier "Concurrent"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "System"
. "."
identifier "Collections"
. "."
identifier "Generic"
; ";"
using_directive
using "using"
qualified_name
identifier "System"
. "."
identifier "Diagnostics"
; ";"
using_directive
using "using"
qualified_name
identifier "System"
. "."
identifier "Linq"
; ";"
using_directive
using "using"
qualified_name
identifier "System"
. "."
identifier "Threading"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "System"
. "."
identifier "Threading"
. "."
identifier "Tasks"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "MediaBrowser"
. "."
identifier "Controller"
. "."
identifier "Configuration"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "Microsoft"
. "."
identifier "Extensions"
. "."
identifier "Hosting"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "Microsoft"
. "."
identifier "Extensions"
. "."
identifier "Logging"
; ";"
file_scoped_namespace_declaration
namespace "namespace"
qualified_name
qualified_name
identifier "MediaBrowser"
. "."
identifier "Controller"
. "."
identifier "LibraryTaskScheduler"
; ";"
comment "/// <summary>"
comment "/// Provides Parallel action interface to process tasks with"...
comment "/// </summary>"
class_declaration
modifier
public "public"
modifier
sealed "sealed"
class "class"
identifier "LimitedConcurrencyLibraryScheduler"
base_list
: ":"
identifier "ILimitedConcurrencyLibraryScheduler"
, ","
identifier "IAsyncDisposable"
declaration_list
{ "{"
field_declaration
modifier
private "private"
modifier
const "const"
variable_declaration
predefined_type "int"
variable_declarator
identifier "CleanupGracePeriod"
= "="
integer_literal "60"
; ";"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
identifier "IHostApplicationLifetime"
variable_declarator
identifier "_hostApplicationLifetime"
; ";"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
generic_name
identifier "ILogger"
type_argument_list
< "<"
identifier "LimitedConcurrencyLibraryScheduler"
> ">"
variable_declarator
identifier "_logger"
; ";"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
identifier "IServerConfigurationManager"
variable_declarator
identifier "_serverConfigurationManager"
; ";"
field_declaration (+23 nodes collapsed)
field_declaration (+23 nodes collapsed)
comment "/// <summary>"
comment "/// Gets used to lock all operations on the Tasks queue and "...
comment "/// </summary>"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
identifier "Lock"
variable_declarator
identifier "_taskLock"
= "="
implicit_object_creation_expression
new "new"
argument_list
( "("
) ")"
; ";"
field_declaration (+21 nodes collapsed)
field_declaration
modifier
private "private"
modifier
volatile "volatile"
variable_declaration
predefined_type "int"
variable_declarator
identifier "_workCounter"
; ";"
field_declaration
modifier
private "private"
variable_declaration
nullable_type
identifier "Task"
? "?"
variable_declarator
identifier "_cleanupTask"
; ";"
field_declaration
modifier
private "private"
variable_declaration
predefined_type "bool"
variable_declarator
identifier "_disposed"
; ";"
comment "/// <summary>"
comment "/// Initializes a new instance of the <see cref=\"LimitedConc"...
comment "/// </summary>"
comment "/// <param name=\"hostApplicationLifetime\">The hosting lifeti"...
comment "/// <param name=\"logger\">The logger.</param>"
comment "/// <param name=\"serverConfigurationManager\">The server conf"...
constructor_declaration (+44 nodes collapsed)
method_declaration (+282 nodes collapsed)
method_declaration
modifier
private "private"
predefined_type "void"
identifier "Worker"
parameter_list
( "("
) ")"
block
{ "{"
lock_statement
lock "lock"
( "("
identifier "_taskLock"
) ")"
block
{ "{"
local_declaration_statement
variable_declaration
implicit_type
var "var"
variable_declarator
identifier "fanoutConcurrency"
= "="
member_access_expression all 2:2
member_access_expression all 2:2
identifier "_serverConfigurationManager" all 2:2
. "." all 2:2
identifier "Configuration" all 2:2
. "." all 2:2
identifier "LibraryScanFanoutConcurrency" all 2:2
; ";"
local_declaration_statement
variable_declaration
implicit_type
var "var"
variable_declarator
identifier "parallelism"
= "="
binary_expression
parenthesized_expression
( "("
conditional_expression
binary_expression
identifier "fanoutConcurrency"
> ">"
integer_literal "0"
? "?"
identifier "fanoutConcurrency"
: ":"
member_access_expression all 1:2
identifier "Environment" all 1:2
. "." all 1:2
identifier "ProcessorCount" all 1:2
) ")"
- "-"
member_access_expression
identifier "_taskRunners"
. "."
identifier "Count"
; ";"
expression_statement
invocation_expression
member_access_expression
identifier "_logger"
. "."
identifier "LogDebug"
argument_list
( "("
argument
string_literal
" "\""
string_literal_content "Spawn {NumberRunners} new runners."
" "\""
, ","
argument
identifier "parallelism"
) ")"
; ";"
for_statement
for "for"
( "("
variable_declaration
predefined_type "int"
variable_declarator
identifier "i"
= "="
integer_literal "0"
; ";"
binary_expression
identifier "i"
< "<"
identifier "parallelism"
; ";"
postfix_unary_expression
identifier "i"
++ "++"
) ")"
block (+99 nodes collapsed)
} "}"
} "}"
method_declaration (+328 nodes collapsed)
method_declaration (+130 nodes collapsed)
comment "/// <inheritdoc/>"
method_declaration
modifier
public "public"
modifier
async "async"
identifier "Task"
identifier "Enqueue"
type_parameter_list
< "<"
type_parameter
identifier "T"
> ">"
parameter_list (+41 nodes collapsed)
block
{ "{"
if_statement
if "if"
( "("
identifier "_disposed"
) ")"
block
{ "{"
return_statement
return "return"
; ";"
} "}"
if_statement (+35 nodes collapsed)
expression_statement (+21 nodes collapsed)
local_declaration_statement
variable_declaration
array_type
identifier "TaskQueueItem"
array_rank_specifier
[ "["
] "]"
variable_declarator
identifier "workItems"
= "="
postfix_unary_expression
null_literal "null"
! "!"
; ";"
local_function_statement (+43 nodes collapsed)
expression_statement (+162 nodes collapsed)
if_statement
if "if"
( "("
binary_expression
member_access_expression all 2:2
member_access_expression all 2:2
identifier "_serverConfigurationManager" all 2:2
. "." all 2:2
identifier "Configuration" all 2:2
. "." all 2:2
identifier "LibraryScanFanoutConcurrency" all 2:2
== "=="
integer_literal "1"
) ")"
block (+92 nodes collapsed)
for_statement (+61 nodes collapsed)
if_statement (+262 nodes collapsed)
} "}"
comment "/// <inheritdoc/>"
method_declaration (+129 nodes collapsed)
class_declaration (+114 nodes collapsed)
} "}"

After

compilation_unit
using_directive
using "using"
identifier "System"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "System"
. "."
identifier "Collections"
. "."
identifier "Concurrent"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "System"
. "."
identifier "Collections"
. "."
identifier "Generic"
; ";"
using_directive
using "using"
qualified_name
identifier "System"
. "."
identifier "Diagnostics"
; ";"
using_directive
using "using"
qualified_name
identifier "System"
. "."
identifier "Linq"
; ";"
using_directive
using "using"
qualified_name
identifier "System"
. "."
identifier "Threading"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "System"
. "."
identifier "Threading"
. "."
identifier "Tasks"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "MediaBrowser"
. "."
identifier "Controller"
. "."
identifier "Configuration"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "Microsoft"
. "."
identifier "Extensions"
. "."
identifier "Hosting"
; ";"
using_directive
using "using"
qualified_name
qualified_name
identifier "Microsoft"
. "."
identifier "Extensions"
. "."
identifier "Logging"
; ";"
file_scoped_namespace_declaration
namespace "namespace"
qualified_name
qualified_name
identifier "MediaBrowser"
. "."
identifier "Controller"
. "."
identifier "LibraryTaskScheduler"
; ";"
comment "/// <summary>"
comment "/// Provides Parallel action interface to process tasks with"...
comment "/// </summary>"
class_declaration
modifier
public "public"
modifier
sealed "sealed"
class "class"
identifier "LimitedConcurrencyLibraryScheduler"
base_list
: ":"
identifier "ILimitedConcurrencyLibraryScheduler"
, ","
identifier "IAsyncDisposable"
declaration_list
{ "{"
field_declaration
modifier
private "private"
modifier
const "const"
variable_declaration
predefined_type "int"
variable_declarator
identifier "CleanupGracePeriod"
= "="
integer_literal "60"
; ";"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
identifier "IHostApplicationLifetime"
variable_declarator
identifier "_hostApplicationLifetime"
; ";"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
generic_name
identifier "ILogger"
type_argument_list
< "<"
identifier "LimitedConcurrencyLibraryScheduler"
> ">"
variable_declarator
identifier "_logger"
; ";"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
identifier "IServerConfigurationManager"
variable_declarator
identifier "_serverConfigurationManager"
; ";"
field_declaration (+23 nodes collapsed)
field_declaration (+23 nodes collapsed)
comment "/// <summary>"
comment "/// Gets used to lock all operations on the Tasks queue and "...
comment "/// </summary>"
field_declaration
modifier
private "private"
modifier
readonly "readonly"
variable_declaration
identifier "Lock"
variable_declarator
identifier "_taskLock"
= "="
implicit_object_creation_expression
new "new"
argument_list
( "("
) ")"
; ";"
field_declaration (+21 nodes collapsed)
field_declaration
modifier
private "private"
modifier
volatile "volatile"
variable_declaration
predefined_type "int"
variable_declarator
identifier "_workCounter"
; ";"
field_declaration
modifier
private "private"
variable_declaration
nullable_type
identifier "Task"
? "?"
variable_declarator
identifier "_cleanupTask"
; ";"
field_declaration
modifier
private "private"
variable_declaration
predefined_type "bool"
variable_declarator
identifier "_disposed"
; ";"
comment "/// <summary>"
comment "/// Initializes a new instance of the <see cref=\"LimitedConc"...
comment "/// </summary>"
comment "/// <param name=\"hostApplicationLifetime\">The hosting lifeti"...
comment "/// <param name=\"logger\">The logger.</param>"
comment "/// <param name=\"serverConfigurationManager\">The server conf"...
constructor_declaration (+44 nodes collapsed)
method_declaration (+282 nodes collapsed)
method_declaration
modifier
private "private"
predefined_type "bool"
identifier "ShouldForceSequentialOperation"
parameter_list
( "("
) ")"
block
{ "{"
comment "// if the user either set the setting to 1 or it's unset and"...
local_declaration_statement
variable_declaration
implicit_type
var "var"
variable_declarator
identifier "fanoutSetting"
= "="
member_access_expression all 2:2
member_access_expression all 2:2
identifier "_serverConfigurationManager" all 2:2
. "." all 2:2
identifier "Configuration" all 2:2
. "." all 2:2
identifier "LibraryScanFanoutConcurrency" all 2:2
; ";"
return_statement
return "return"
binary_expression
binary_expression
identifier "fanoutSetting"
== "=="
integer_literal "1"
|| "||"
parenthesized_expression
( "("
binary_expression
binary_expression
identifier "fanoutSetting"
<= "<="
integer_literal "0"
&& "&&"
binary_expression
member_access_expression all 1:2
identifier "Environment" all 1:2
. "." all 1:2
identifier "ProcessorCount" all 1:2
<= "<="
integer_literal "3"
) ")"
; ";"
} "}"
method_declaration
modifier
private "private"
predefined_type "int"
identifier "CalculateScanConcurrencyLimit"
parameter_list
( "("
) ")"
block
{ "{"
comment "// when this is invoked, we already checked ShouldForceSeque"...
local_declaration_statement
variable_declaration
implicit_type
var "var"
variable_declarator
identifier "fanoutConcurrency"
= "="
member_access_expression all 2:2
member_access_expression all 2:2
identifier "_serverConfigurationManager" all 2:2
. "." all 2:2
identifier "Configuration" all 2:2
. "." all 2:2
identifier "LibraryScanFanoutConcurrency" all 2:2
; ";"
if_statement
if "if"
( "("
binary_expression
identifier "fanoutConcurrency"
<= "<="
integer_literal "0"
) ")"
block
{ "{"
comment "// in case the user did not set a limit manually, we can ass"...
return_statement
return "return"
binary_expression
member_access_expression all 1:2
identifier "Environment" all 1:2
. "." all 1:2
identifier "ProcessorCount" all 1:2
- "-"
integer_literal "3"
; ";"
} "}"
return_statement
return "return"
identifier "fanoutConcurrency"
; ";"
} "}"
method_declaration
modifier
private "private"
predefined_type "void"
identifier "Worker"
parameter_list
( "("
) ")"
block
{ "{"
lock_statement
lock "lock"
( "("
identifier "_taskLock"
) ")"
block
{ "{"
local_declaration_statement
variable_declaration
implicit_type
var "var"
variable_declarator
identifier "operationFanout"
= "="
invocation_expression
member_access_expression
identifier "Math"
. "."
identifier "Max"
argument_list
( "("
argument
integer_literal "0"
, ","
argument
binary_expression
invocation_expression
identifier "CalculateScanConcurrencyLimit"
argument_list
( "("
) ")"
- "-"
member_access_expression
identifier "_taskRunners"
. "."
identifier "Count"
) ")"
; ";"
expression_statement
invocation_expression
member_access_expression
identifier "_logger"
. "."
identifier "LogDebug"
argument_list
( "("
argument
string_literal
" "\""
string_literal_content "Spawn {NumberRunners} new runners."
" "\""
, ","
argument
identifier "operationFanout"
) ")"
; ";"
for_statement
for "for"
( "("
variable_declaration
predefined_type "int"
variable_declarator
identifier "i"
= "="
integer_literal "0"
; ";"
binary_expression
identifier "i"
< "<"
identifier "operationFanout"
; ";"
postfix_unary_expression
identifier "i"
++ "++"
) ")"
block (+99 nodes collapsed)
} "}"
} "}"
method_declaration (+328 nodes collapsed)
method_declaration (+130 nodes collapsed)
comment "/// <inheritdoc/>"
method_declaration
modifier
public "public"
modifier
async "async"
identifier "Task"
identifier "Enqueue"
type_parameter_list
< "<"
type_parameter
identifier "T"
> ">"
parameter_list (+41 nodes collapsed)
block
{ "{"
if_statement
if "if"
( "("
identifier "_disposed"
) ")"
block
{ "{"
return_statement
return "return"
; ";"
} "}"
if_statement (+35 nodes collapsed)
expression_statement (+21 nodes collapsed)
local_declaration_statement
variable_declaration
array_type
identifier "TaskQueueItem"
array_rank_specifier
[ "["
] "]"
variable_declarator
identifier "workItems"
= "="
postfix_unary_expression
null_literal "null"
! "!"
; ";"
local_function_statement (+43 nodes collapsed)
expression_statement (+162 nodes collapsed)
if_statement
if "if"
( "("
invocation_expression
identifier "ShouldForceSequentialOperation"
argument_list
( "("
) ")"
) ")"
block (+92 nodes collapsed)
for_statement (+61 nodes collapsed)
if_statement (+262 nodes collapsed)
} "}"
comment "/// <inheritdoc/>"
method_declaration (+129 nodes collapsed)
class_declaration (+114 nodes collapsed)
} "}"