<commit_before>%% -------------------------------------------------------------------
%%
%% Copyright (c) 2019 <NAME>. All Rights Reserved.
%% Copyright (c) 2022 <NAME>. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License.  You may obtain
%% a copy of the License at
%%
%%   http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied.  See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------
-module(partisan_peer_connections).

-include("partisan.hrl").
-include("partisan_logger.hrl").

-define(SELECT(Arg),
    try
        ets:select(?MODULE, Arg)
    catch
        error:badarg ->
            []
    end
).


%% We store two records on the same table, and using the first field as a key
%% (keypos 2). Since both keys differ on type (node() and pid()) this is fine.
-record(partisan_peer_info, {
    node                    ::  maybe_var(node()),
    node_spec               ::  maybe_var(node_spec()),
    connection_count = 0    ::  maybe_var(non_neg_integer())
}).

-record(partisan_peer_connection, {
    pid                     ::  maybe_var(pid()),
    node                    ::  maybe_var(node()),
    channel                 ::  maybe_var(channel_spec()),
    listen_addr             ::  maybe_var(listen_addr())
}).

-type info()                ::  #partisan_peer_info{}.
-type connection()          ::  #partisan_peer_connection{}.
-type connections()         ::  [connection()].
%% Use when pattern matching e.g. '_', '$1'
-type maybe_var(T)          ::  T | atom().
-type channel_spec()        ::  channel() | {monotonic, channel()}.
-type maybe(T)              ::  T | undefined.

-export_type([connection/0]).
-export_type([info/0]).
-export_type([connections/0]).
-export_type([channel_spec/0]).

-export([channel/1]).
-export([connection_count/1]).
-export([connection_count/2]).
-export([connections/0]).
-export([connections/1]).
-export([connections/2]).
-export([dispatch/1]).
-export([dispatch_pid/1]).
-export([dispatch_pid/2]).
-export([dispatch_pid/3]).
-export([erase/1]).
-export([fold/2]).
-export([foreach/1]).
-export([info/1]).
-export([init/0]).
-export([is_connected/1]).
-export([is_connected/2]).
-export([is_fully_connected/1]).
-export([listen_addr/1]).
-export([node/1]).
-export([node_spec/1]).
-export([node_specs/0]).
-export([nodes/0]).
-export([nodes/1]).
-export([pid/1]).
-export([processes/1]).
-export([processes/2]).
-export([prune/1]).
-export([store/4]).


-compile({no_auto_import, [nodes/1]}).
-compile({no_auto_import, [erase/1]}).


%% =============================================================================
%% API
%% =============================================================================


%% -----------------------------------------------------------------------------
%% @doc Creates a new connections table. The owner of the table is the calling
%% process and the table is protected so only the owner can write to it.
%% @end
%% -----------------------------------------------------------------------------
-spec init() -> ok.

init() ->
    case ets:info(?MODULE, name) of
        ?MODULE ->
            %% Already initialised
            ok;
        undefined ->
            Pos = #partisan_peer_info.node,

            ?MODULE = ets:new(?MODULE, [
                named_table,
                protected,
                ordered_set,
                {keypos, Pos},
                %% We enable both as we have concurrent reads and writes, although
                %% writes will only happen when a connection is started/stopped for a
                %% peer node.
                {read_concurrency, true},
                {write_concurrency, true}
            ]),

            ok
    end.


%% -----------------------------------------------------------------------------
%% @doc Returns a list of all nodes connected to this node through normal
%% connections (that is, hidden nodes are not listed). Same as nodes(visible).
%% @end
%% -----------------------------------------------------------------------------
-spec nodes() -> [node()].

nodes() ->
    nodes(visible).<commit_msg>doc changes<commit_after>%% -------------------------------------------------------------------
%%
%% Copyright (c) 2019 <NAME>. All Rights Reserved.
%% Copyright (c) 2022 <NAME>. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License.  You may obtain
%% a copy of the License at
%%
%%   http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied.  See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------
-module(partisan_peer_connections).

-include("partisan.hrl").
-include("partisan_logger.hrl").

-define(SELECT(Arg),
    try
        ets:select(?MODULE, Arg)
    catch
        error:badarg ->
            []
    end
).


%% We store two records on the same table, and using the first field as a key
%% (keypos 2). Since both keys differ on type (node() and pid()) this is fine.
-record(partisan_peer_info, {
    node                    ::  maybe_var(node()),
    node_spec               ::  maybe_var(node_spec()),
    connection_count = 0    ::  maybe_var(non_neg_integer())
}).

-record(partisan_peer_connection, {
    pid                     ::  maybe_var(pid()),
    node                    ::  maybe_var(node()),
    channel                 ::  maybe_var(channel_spec()),
    listen_addr             ::  maybe_var(listen_addr())
}).

-type info()                ::  #partisan_peer_info{}.
-type connection()          ::  #partisan_peer_connection{}.
-type connections()         ::  [connection()].
%% Use when pattern matching e.g. '_', '$1'
-type maybe_var(T)          ::  T | atom().
-type channel_spec()        ::  channel() | {monotonic, channel()}.
-type maybe(T)              ::  T | undefined.

-export_type([connection/0]).
-export_type([info/0]).
-export_type([connections/0]).
-export_type([channel_spec/0]).

-export([channel/1]).
-export([connection_count/1]).
-export([connection_count/2]).
-export([connections/0]).
-export([connections/1]).
-export([connections/2]).
-export([dispatch/1]).
-export([dispatch_pid/1]).
-export([dispatch_pid/2]).
-export([dispatch_pid/3]).
-export([erase/1]).
-export([fold/2]).
-export([foreach/1]).
-export([info/1]).
-export([init/0]).
-export([is_connected/1]).
-export([is_connected/2]).
-export([is_fully_connected/1]).
-export([listen_addr/1]).
-export([node/1]).
-export([node_spec/1]).
-export([node_specs/0]).
-export([nodes/0]).
-export([nodes/1]).
-export([pid/1]).
-export([processes/1]).
-export([processes/2]).
-export([prune/1]).
-export([store/4]).


-compile({no_auto_import, [nodes/1]}).
-compile({no_auto_import, [erase/1]}).


%% =============================================================================
%% API
%% =============================================================================


%% -----------------------------------------------------------------------------
%% @doc Creates a new connections table. The owner of the table is the calling
%% process and the table is protected so only the owner can write to it.
%% @end
%% -----------------------------------------------------------------------------
-spec init() -> ok.

init() ->
    case ets:info(?MODULE, name) of
        ?MODULE ->
            %% Already initialised
            ok;
        undefined ->
            Pos = #partisan_peer_info.node,

            ?MODULE = ets:new(?MODULE, [
                named_table,
                protected,
                ordered_set,
                {keypos, Pos},
                %% We enable both as we have concurrent reads and writes,
                %% although writes will only happen when a connection is
                %% started/stopped for a peer node.
                {read_concurrency, true},
                {write_concurrency, true}
            ]),

            ok
    end.


%% -----------------------------------------------------------------------------
%% @doc Returns a list of all nodes connected to this node through normal
%% connections (that is, hidden nodes are not listed). Same as nodes(visible).
%% @end
%% -----------------------------------------------------------------------------
-spec nodes() -> [node()].

nodes() ->
    nodes(visible).
{'fraction_non_alphanumeric': 0.2706350962602346, 'fraction_numerical': 0.011064394777605666, 'mean_word_length': 1.9347402597402596, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2343649', 'n_tokens_mistral': 2460, 'n_tokens_neox': 2355, 'n_words': 664}