001    package org.hd.d.pg2k.svrCore.vars;
002    
003    import java.util.Map;
004    
005    /**
006     * Created by IntelliJ IDEA.
007     * User: Damon
008     * Date: 14-Aug-2004
009     * Time: 18:07:57
010     */
011    
012    /**Generic stats on a variable.
013     * More specific instances may be useful in many cases,
014     * but this will do for simple cases,
015     * and just shows a mapping from participating system to value
016     * without interpreting those values.
017     */
018    public class SimpleVarStats
019        {
020        /**Construct a new instance, filtering variable globalMap members by age.
021         *
022         * @param originalVar  the variable to compute; must be non-null
023         *     but getValue() is permitted to return null
024         *     so that we can handle TYPE_NONE values for example
025         * @param oldestAllowed  any globalMap entry than this will
026         *     be ignored, which allows only up-to-date information
027         *     to be included
028         * @param sysID  identifies this system so we can select the local
029         *     value of a global variable if available; can be null
030         */
031        public SimpleVarStats(final SimpleVariableValue originalVar,
032                              final long oldestAllowed,
033                              final InstanceID sysID)
034            {
035            if(originalVar == null)
036                { throw new IllegalArgumentException("null variable not allowed"); }
037    
038            filteredVar = originalVar.removeAllKeysOlder(oldestAllowed);
039            thisSys = sysID;
040            }
041    
042        /**This system ID, or null if none selected. */
043        private final InstanceID thisSys;
044    
045        /**The TYPE_NUMBER variable we were constructed from after filtering; never null. */
046        protected final SimpleVariableValue filteredVar;
047    
048        /**Get the variable stripped of old globalMap entries. */
049        public SimpleVariableValue getFilteredVar()
050            {
051            return(filteredVar);
052            }
053    
054        /**Get "main" value; may be null.
055         * For a local value it is simply the result of getValue().
056         * <p>
057         * For a global, if a system ID is supplied and has an entry
058         * in the globalMap, its value is used, else the normal getValue()
059         * is used as for a local.
060         */
061        public Object getMainValue()
062            {
063            final Map<InstanceID,SimpleVariableValue> globalMap = filteredVar.getGlobalMap();
064            if((thisSys != null) &&
065               (globalMap != null) &&
066               (globalMap.get(thisSys) != null))
067                {
068                return(globalMap.get(thisSys).getValue());
069                }
070            else
071                { return(filteredVar.getValue()); }
072            }
073    
074        /**Get count of participating systems (ie globalMap entries); 0 for local variable or no globalMap.
075         * A local value will never have globalMap entries;
076         * a global value will not if all the entries were too old to use.
077         */
078        public int getSystemCount()
079            {
080            final Map<InstanceID,SimpleVariableValue> globalMap = filteredVar.getGlobalMap();
081            if(globalMap == null)
082                { return(0); }
083            return(globalMap.size());
084            }
085    
086        /**Get count of globalMap entries with non-null values.
087         * This can never be greater than the result of getSystemCount()
088         * and never negative.
089         */
090        public int getNonNullValueCount()
091            {
092            assert(filteredVar != null);
093            final Map<InstanceID,SimpleVariableValue> globalMap = filteredVar.getGlobalMap();
094            if(globalMap == null)
095                { return(0); }
096    
097            int count = 0;
098            for(final SimpleVariableValue svv : globalMap.values())
099                {
100                assert(svv != null);
101                if(svv.getValue() != null) { ++count; }
102                }
103            return(count);
104            }
105    
106        /**Force deriving class to provide a toString() implementation. */
107    
108        /**Returns HTML- and human- friendly summary of stats.
109         * This does <em>not</em> include the variable name.
110         * <p>
111         * If the count is zero,
112         * just returns a formatted version of the value.
113         * <p>
114         * Note that this simply relies on the toString() method
115         * of the value type, and shows a direct map of all the values,
116         * so may not work well for large numbers of systems or unfriendly values.
117         * <p>
118         * It may be best to override this for many/most variable types.
119         */
120        @Override
121        public String toString()
122            {
123            final StringBuilder sb = new StringBuilder(71);
124    
125            sb.append(getMainValue());
126    
127            final Map<InstanceID,SimpleVariableValue> globalMap = filteredVar.getGlobalMap();
128            if(globalMap != null)
129                {
130                final int n = globalMap.size();
131                sb.append(", n=").append(n);
132    
133                for(final Map.Entry<InstanceID,SimpleVariableValue> e : globalMap.entrySet())
134                    {
135                    sb.append(", ");
136                    sb.append(e.getKey());
137                    sb.append("-->");
138                    sb.append(e.getValue());
139                    }
140                }
141    
142            return(sb.toString());
143            }
144        }