function dh = dispInternal( obj, className, objName )
;%#ok undocumented

% Return a distributedutil.DisplayHelper object

% Copyright 2008-2022 The MathWorks, Inc.

% Deal with closed pool / invalid object up front, with early return.
if ~obj.isValid()
    
    if ~obj.isResourceSetOpen()
        % The pool that this referred to has been closed
        msg = getString(message('parallel:array:DisplayInvalidDueToClosedPool', className));
    else
        % No clear reason - could have been load/save
        msg = getString(message('parallel:array:DisplayInvalid', className));
    end
    
    dh = parallel.internal.shared.DisplayHelperInvalid( objName, className, msg );
else
    N  = 1000;
    dh = parallel.internal.shared.buildDisplayHelper( ...
        obj, @transferPortion, @iSparseNTruncate, ...
        objName, className, N );
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display the first N entries of a sparse distributed
function truncated = iSparseNTruncate( x, N )
% Sparse truncation - simply pick the first N elements
truncated = spmd_feval_fcn( @iSparseNTruncateI, {x, N} );
truncated = truncated.Value;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Run in parallel on a sparse codistributed - pick the first N using "find 'first'",
% let's hope that's a good choice for codistributed.
function truncated = iSparseNTruncateI( x, N )

% Find the indices of the first N
[i, j, v] = find( x, N, 'first' );

% Gather to worker 1 that portion of x, and the indices
i = gather( i, 1 );
j = gather( j, 1 );
v = gather( v, 1 );

if spmdIndex == 1
    % Put i,j,v into a cell and transfer it using AutoTransfer. Ensure
    % i,j,v are column vectors.
    truncated = {i(:), j(:), v(:)};
else
    truncated = [];
end

% truncated has the correct value only on worker 1
truncated = distributedutil.AutoTransfer( truncated, 1 );
end
