www.gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/+matlab/+bigdata/+internal/+adaptors/AbstractAdaptor.m
%AbstractAdaptor Adaptor base class. % Each tall array instance holds a PartitionedArray and an Adaptor. The % Adaptor is responsible for holding metadata relating to the PartitionedArray % that is known at the client. The Adaptor also is responsible for % implementing methods that depend on that metadata. % % In practice, this means that the all Adaptor classes hold at least the % following information about the PartitionedArray: % - Class - the underlying class of the data, or '' if not known % - NDims - NDIMS for the underlying array, or NaN if not known % - Size - when NDIMS is non-NaN, a 1xNDims vector of size information, % where any element might be NaN if it is not known. % % The primary responsibility of the Adaptor class is to implement the various % forms of indexing supported by tall arrays. The tall array methods SUBSREF % and SUBSASGN perform simple analysis to determine which form of indexing is % being performed, and then invoke one of the subsref* or subsasgn* methods on % the Adaptor, passing the corresponding PartitionedArray to operate on. % Copyright 2016 The MathWorks, Inc. classdef (Abstract) AbstractAdaptor properties (SetAccess = 'immutable') % Modifying class post-construction is a bad idea since this might allow an % adaptor to be used for an inappropriate type. Class = ''; end properties (SetAccess = 'protected') % Size only valid if NDims is non-NaN NDims = NaN; end properties (Dependent) Size TallSizeId end properties (SetAccess = 'private') % TallSize is a handle to an object that can be shared by many Adaptors and thus % allows sizes to be injected. TallSize; % SmallSizes is a standard numeric array. SmallSizes = []; end methods function sz = get.Size(obj) if isnan(obj.NDims) sz = []; else sz = [obj.TallSize.Size, obj.SmallSizes]; end end function tid = get.TallSizeId(obj) tid = obj.TallSize.Id; end end methods (Abstract) %getProperties return a cellstr of property names names = getProperties(obj) %displayImpl Implementation of DISPLAY. % displayInfo is matlab.bigdata.internal.display.DisplayInfo. displayImpl(obj, displayInfo, pa) %Various subsref implementations. subsrefParens(obj, pa, szPa, S) subsasgnParens(obj, pa, szPa, S, b) subsasgnParensDeleting(obj, pa, szPa, S) subsrefBraces(obj, pa, szPa, S) subsasgnBraces(obj, pa, szPa, S, b) end methods function varargout = subsrefDot(obj, pa, szPa, S) %#ok<INUSD,STOUT> error(message('MATLAB:structRefFromNonStruct')); end function obj = subsasgnDotDeleting(obj, pa, szPa, S) %#ok<INUSD> error(message('MATLAB:structAssToNonStruct')); end function obj = subsasgnDot(obj, pa, szPa, S, b) %#ok<INUSD> error(message('MATLAB:structAssToNonStruct')); end % For various reductions - convert strings into "missing" flags and "precision" % flags. Each return must be a cell array to enable forwarding of flags. function [nanFlagCell, precisionFlagCell] = interpretReductionFlags(obj, FCN_NAME, ~) %#ok<STOUT> error(message('MATLAB:bigdata:array:FcnNotSupportedForType', FCN_NAME, obj.Class)); end end methods function obj = AbstractAdaptor(clz, tsz) obj.Class = clz; if nargin < 2 obj.TallSize = matlab.bigdata.internal.adaptors.TallSize(); else obj.TallSize = tsz; end end function tf = isSizeKnown(obj, optIdx) %isSizeKnown Call this to find out if the size of the tall is known %isSizeKnown(idx) checks whether one specific size entry is known if nargin>1 tf = ~isnan(obj.getSizeInDim(optIdx)); else tf = ~isnan(obj.NDims) && ~any(isnan(obj.Size)); end end function sz = getSizeInDim(obj, dim) % Return the size of the array in the specified dimension % Will be nan for unknown dimensions. if dim <= length(obj.Size) % Part of the size vector sz = obj.Size(dim); else % Trailing dimension. If we know the number of % dimensions then this is definitely 1. Otherwise % unknown. if isnan(obj.NDims) sz = nan; else sz = 1; end end end function obj = setSizeInDim(obj, dim, sz) % Set the size of the array in the specified dimension. % Note that this will create a new tall size rather than updating % the tall size of existing arrays. assert(nargout==1); if dim==1 obj.TallSize = matlab.bigdata.internal.adaptors.TallSize(sz); elseif ~isnan(obj.NDims) % Only set a small size if ndims is known. We may relax this % constraint later. We may need to extend the size vector. dim = dim - 1; if dim > length(obj.SmallSizes) % pad with trailing ones n = dim - length(obj.SmallSizes); obj.SmallSizes = [obj.SmallSizes, ones(1,n)]; end obj.SmallSizes(dim) = sz; % Make sure the dimensions are still consistent obj = packDims(obj); end end function obj = setKnownSize(obj, szVec) %setKnownSize Call this when you know the size of the tall szVec = iFixSizeVector(szVec); nd = numel(szVec); assert(isnan(obj.NDims) || obj.NDims == nd); obj.NDims = numel(szVec); if isnan(szVec(1)) obj.TallSize = matlab.bigdata.internal.adaptors.TallSize(); else obj.TallSize.Size = szVec(1); end obj.SmallSizes = szVec(2:end); % Make sure the dimensions are still consistent obj = packDims(obj); end function obj = setSmallSizes(obj, smallSizes) %setSmallSizes Call this when the tall size is unchanged, and now you know the %small sizes % Note iFixSizeVector wants to work on a full size vector, so we prepend a dummy % NaN, and then strip it out again. if ~isnan(obj.NDims) assert(obj.NDims == 1 + numel(smallSizes)); assert(all(obj.SmallSizes(~isnan(obj.SmallSizes)) == smallSizes(~isnan(obj.SmallSizes)))); end tmp = iFixSizeVector([NaN smallSizes]); obj.SmallSizes = tmp(2:end); obj.NDims = numel(obj.SmallSizes) + 1; end function obj = resetSizeInformation(obj) %resetSizeInformation Call this when an operation has been performed that means %that all size information is lost obj.NDims = NaN; obj.TallSize = matlab.bigdata.internal.adaptors.TallSize(); obj.SmallSizes = []; end function obj = resetTallSize(obj, m) %resetTallSize Call this when an operation has been performed that %changes the tall size but leaves other dimensions alone. Note that %this will update the tall size for all linked adaptors. % % ad = resetTallSize(ad) indicates unknown tall size (nan) % ad = resetTallSize(ad,m) sets the tall size to 'm' if nargin<2 || isnan(m) % Reset to unknown obj.TallSize = matlab.bigdata.internal.adaptors.TallSize(); else obj.TallSize.Size = m; end end function obj = resetSmallSizes(obj, szVec) %resetSmallSizes Call this when an operation has been performed that %changes the small sizes but leaves the tall dimension alone (i.e. %slicefun) % % ad = resetSmallSizes(ad) indicates unknown small sizes (ndims = nan) % ad = resetSmallSizes(ad,szVec) sets the small sizes to szVec % (ndims = numel(szVec)+1) if nargin<2 obj.NDims = NaN; obj.SmallSizes = []; else obj.NDims = numel(szVec)+1; obj.SmallSizes = szVec; end end function obj = copyTallSize(obj, copyFrom) % Call this when two arrays are guaranteed to have the same tall size. This % updates obj to use the same handle for 'TallSize'. obj.TallSize = copyFrom.TallSize; end function obj = copySizeInformation(obj, copyFrom) %copySizeInformation Call this to copy size information from one adaptor to %another. if isnan(copyFrom.NDims) % If copyFrom doesn't have small dimensions, reset everything obj = resetSizeInformation(obj); else obj.NDims = copyFrom.NDims; obj.SmallSizes = copyFrom.SmallSizes; end % Always sync the tall sizes. obj = copyTallSize(obj, copyFrom); end end methods (Access=private) function obj = packDims(obj) % Helper to make sure we don't keep trailing ones in the small % sizes. if length(obj.SmallSizes) > 1 lastNonTrivialDim = find(obj.SmallSizes(2:end) ~= 1, 1, 'last'); if isempty(lastNonTrivialDim) obj.SmallSizes = obj.SmallSizes(1); else obj.SmallSizes = obj.SmallSizes(1:(1 + lastNonTrivialDim)); end % Be careful about the trailing dim being NaN, since that % means it might be one (and hence ndims is not what we % think it is). if length(obj.SmallSizes)>1 && isnan(obj.SmallSizes(end)) % Since we can no longer guarantee the dimensionality, % set ndims to nan. obj.NDims = nan; else obj.NDims = length(obj.SmallSizes)+1; end end end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function szVec = iFixSizeVector(szVec) % We insist on 'isfloat' for specifying sizes because otherwise NaN values % get converted to zeros. assert(isrow(szVec) && numel(szVec) >= 2 && isfloat(szVec), ... 'Specified size vector must be a row of floats with at least 2 elements.'); lastNonTrivialDim = find(szVec(2:end) ~= 1, 1, 'last'); if isempty(lastNonTrivialDim) szVec = szVec(1:2); else szVec = szVec(1:(1 + lastNonTrivialDim)); end end