Personal License


  • Perpetual license (does not expire)
  • 1 application
  • Can distribute binary products only
  • Non-commercial use only
  • Attribution required
$23.99 Read License

Developer License


  • Perpetual license (does not expire)
  • Unlimited projects
  • Can distribute code and binary products
  • Commercial use allowed
  • 1 year support
$149.99 Read License

14 Day money-back guarantee

Full refund within 14 days of purchase date.

You need to log-in or create an account
  • Create an account
  • Log-in

Please use your real name.

Activation link will be sent to this address.

Minimum 8 characters

Enter your password again

Clicking this button confirms you read and agreed to the terms of use and privacy policy.

  • Released: Jan 5, 2012
    Last Update: Dec 17, 2011
  • Language: Java
  • Category: Performance
  • Time / costs savings: 250h / $15000 *

HistogramData

HistogramData
Developed by Ralph Chapin, Released Jan 5, 2012

Heavy duty storage and powerful algorithms for resource histograms and similar uses.

Java

Tags: algorithm , calculation , class , code

This component handles and manipulates the data used to generate histograms and data charts for project management and ERP software, in order to provide high-performance, real-time display and manipulation of histograms.

It tracks levels (such as resource usage rates, money spent, and available machines) over time, stores the data and provides an extensive set of methods to manipulate it.

In the fields of Project Management (PM), Project Portfolio Management (PPM), Enterprise Resource Planning (ERP), etc., such data is usually stored in arrays where each element represents a fixed time period (hour, day, week). Memory and calculation time are wasted because each array element usually has the same value as all the elements near it. HistogramData replaces those arrays with a binary tree structure that is much faster and uses much less memory.

There are many cases where this is useful or even critical:

  • A value changes over time, and is stored as a set of levels, each with a start and end time.

  • Levels do not normally change over brief time periods.

  • The levels must be condensed, summarized, or otherwise processed to produce human-readable histogram charts.

  • Multiple sets of levels (histograms) interact. HistogramData has tools to add these histograms together, subtract one from another, compare them, move them around in time, and do a lot else also.

Expanding on these points with an example from Project Management:

Consider the need to track available welders for a construction project, both for reporting purposes and to see what work can be done and when. On Monday there might be 5 available, on Tuesday 10, and on Wednesday 7. This information can be handled by a 3-element array.

But if 3 extra welders are available for a couple of hours on Tuesday, the array must be in hours instead of days. Even assuming only 8 hours in a day, the array needs 24 elements. Further, the project may run for a year, so we need still more elements--2000 of them, actually--all with a value of zero. If work may be done outside regular hours, we need to triple the number of elements to handle evenings and nights. If we schedule in half-hour increments, we can double the number again. (If scheduling in minutes, multiply by 60.)

All this wastes memory. Worse, the calculations must work through thousands of array elements, almost all with the same value. Histogram data stores this example's data simply and efficiently as five levels: 5 on Monday; 10, 13, and 10 on Tuesday; and 7 on Wednesday.

The histogram of available welders would be created by adding together the availability histogram for each welder. When a welder is assigned to a task, those hours would be subtracted from this availability. A task will have requirements for welders (and other types of workers also) that look like availabilities, but that move in time depending on when the it starts. All in all, minor changes to data--task starts, worker availability, etc.--can result in major changes in many resource histograms. HistogramData's speed, efficiency, and powerful methods let all this work be done in an interactive system without making the user wait.

Features

Beyond Project Management: Generally useful features.

  • Tracks availabilities, usages, requirements, etc. of individual people, groups of people, machines, materials, and money over time.

  • Uses sparse-array techniques so that long periods at a constant level (such as zero or one) do not use up memory or calculation time while still allowing minute-by-minute level changes.

  • Summarizes or condenses intricate usage-level patterns for use in histogram displays.

  • Adds histogram data together to produce a new summary histogram.

  • Subtracts one histogram from another to show how much of the resource is left--and when it is left--after some is used on a particular job.

  • Compares one histogram with either a constant level or another histogram to let you know if you have too much or too little--and when you have too much or too little.

For Project Management: Features most likely to be of interest to people doing Project Management.

  • Distinguishes between null levels and zero levels. This allows the data to be treated as a pattern--a simple set of working periods--or the TimePeriods interface referred to in the ResourceTable documentation below.

  • Imposes TimePeriods patterns on histogram data. Take a histogram with 8 hours at level 4 followed by 8 hours at level 5. Impose an 8-hour-a-day pattern on it. The result is a histogram with a level of 4 from 9:00AM to 5:00PM on the first day, a level of 5 on the same period the second day, and a null level in between (from 5:00PM to 9:00AM).

  • Uses work calendars. (These are mostly-cyclical patterns used extensively in Project Management systems to specify work weeks, work hours, holidays, vacations, etc.)

HistogramData, as written, uses 4 byte integers for time. This allows a 4000 year time span, where the level can change from minute to minute. These numbers are used extensively in calculations, and using an "int" rather than a "long" or "double" saves space and speeds processing. 8 byte integers are used for the levels themselves. These numbers are used in calculations much less than the dates, so performance is not such a problem. While in most cases the numbers are small, often being one or zero (or null), they can represent materials or money. (With money accountants get very concerned if a multi-billion dollar amount is off by a penny, so floating point numbers cannot be used.) Changing types for times and levels to optimize HistogramData for non-resource-management uses, would be a simple job, but might take a little bit of time.

Summary

  • Condenses and combines resource histogram data for display and compares data to spot opportunities and problems.
  • Stores the data in ways that use minimal memory and enable fast calculations.
  • Scales up effortlessly for large histograms, large numbers of histograms, and extensive interactions between histograms.

HistogramData was originally written to handle Resource Management for a Project Management system (rather like Microsoft Project). It is fully Javadoc'ed. It includes the SortedList component (which is also sold separately). Three programs are included: one simple usage example (also shown below) and two complex examples/tests.

Author's Note

I spent over twenty years working in Project Management algorithms. Resource histograms presented unending problems. I spent most of those twenty years thinking about a solution. When I found myself with time to start from first principles and do it right I wrote ResourceTable, the core class in HistogramData. Certainly any Project Management system needs this class, or one like it.

I think it must be useful in many other fields as well, and I hope my Project Management examples and terminology explain rather than obscure the fundamental ideas and capabilities.

--Ralph Chapin

Back to top

Usage Example

package histogramdata;
import java.util.*;
import rrc76.utilities.utils.timeperiod.*;

/** An example of using the HistogramTable component. */
public class HistogramDataExample  {
    /** The start date of the main histogram as an integer. */
    private static int  startDate;
    /** The primary histogram. */
    private static final ResourceTable  theTable = new ResourceTable();

    /** Create a histogram and modify the data somewhat. */
    public static void main(String[] args)  {
        Calendar  calendar = new GregorianCalendar();
        calendar.set( 2012, 0, 1, 0, 0 );
        startDate = IntDates.getInt( calendar );

        // Add a level of 5 from day 1 through day 8.
        theTable.add( getDay( 1 ), getDay( 9 ), 5, UsageTable.CREATE );

        // Add a level of 3 from day 6 through day 10, with a spike to
        // 1443 at noon on day 10.  (1440 is one day in minutes, making
        // for a neat summary.  Day 10 will have a total level of 4:
        // (1440 * 3 + 1 * 1440) / 1440.)
        // Use a second ResourceTable to do this.
        {
            ResourceTable  temp = new ResourceTable();
            temp.add( getDay( 6 ), getDay( 11 ), 3, UsageTable.CREATE );
            int  noon = getDay( 10 ) + 720;
            temp.add( noon, noon + 1, 1440, UsageTable.CREATE );
            theTable.add( temp, UsageTable.CREATE );
        }
        // Transfer data to an array that sumarizes on days.  Start
        // one day before the 10 and finish one day after.
        long[]  summary = new long[12];
        int  end = getDay( 0 );
        for (int i = 0; i < 12; i++)  {
            int  start = end;
            end += 1440;
            long  sum = theTable.getResourceAmount( start, end,
                        UsageTable.TOTAL );
            summary[i] = sum / 1440;
        }
        // Could use "summary" to display a histogram.  Instead, just
        // make sure all the values are correct.
        if (summary[0] != 0L  ||  summary[11] != 0L)
            System.out.println( "Error:  values outside time period." );
        for (int i = 1; i <= 5; i++)
            if (summary[i] != 5L)
                System.out.println( "Error:  value of " + summary[i] +
                            " on day " + i + "." );
        for (int i = 6; i <= 8; i++)
            if (summary[i] != 8L)
                System.out.println( "Error:  value of " + summary[i] +
                            " on day " + i + "." );
        if (summary[9] != 3L)
            System.out.println( "Error:  value of " + summary[9] +
                        " on day " + 9 + "." );
        if (summary[10] != 4L)
            System.out.println( "Error:  value of " + summary[10] +
                        " on day " + 10 + "." );
    }

    /** Return an integer date given the day number.  Note that the
     * returned time is the START of the specified day! */
    public static int getDay( int index )  {
        // 1440 is the number of minutes in a day.
        return (1440 * (index - 1)) + startDate;
    }
}
Back to top

ResourceTable, the Core Class and Its Methods

Descriptions of methods for the class ResourceTable, which is at the core of the HistogramData component. ResourceTable implements both the TimePeriods and UsageTable interfaces.

Note: the TimePeriods interface is a set of time periods that need not have associated levels. The UsageTable interface is the same, but must have levels.

add

public void add(int start,
                int end,
                long level,
                int key)

Adds an amount to this 'ResourceTable'. Negatives work, so the caller can add and subtract.

  • start - the start of the amount's period.
  • end - the end of the amount's period.
  • level - the rate at which the resource exists over the period. The actual amount of the resource is the given level multiplied by the duration of the period (end - start).
  • key - valid values are CREATE and DEFAULT. Generally, use CREATE when setting up resource availabilities and DEFAULT when removing them or otherwise adjusting them.

add

public void add(TimePeriods tp,
                int key)

Adds the passed TimePeriods instance to this ResourceTable. This effectively adds the two levels at all times in this table.

  • tp - the TimePeriods instance to add to this ResourceTable. This TimePeriods instance, tp, will not get modified. It may be null, in which case this ResourceTable will remain unchanged.
  • key - valid values are CREATE and DEFAULT. Generally, use CREATE when setting up resource availabilities and DEFAULT when removing them or otherwise adjusting them.

add

public void add(TimePeriods tp,
                int date,
                int dur,
                int key)

Adds (a part of) the table in a TimePeriods instance to this ResourceTable.

  • tp - the TimePeriods instance. This TimePeriods instance, tp, will not get modified. It may be null, in which case this ResourceTable will remain unchanged.
  • date - the start (or end) date of the data taken from tp. The duration is measured along the active periods in tp.
  • dur - the duration of the data taken from tp. Make negative to make date an end date rather than a start date.
  • key - valid values are CREATE and DEFAULT.

add

public void add(TimePeriods tp,
                int start,
                int end)

Adds a part of the table in a TimePeriods instance to this ResourceTable. Undefined time periods in this table are treated as having a level of zero if levels are added to them.

  • tp - the TimePeriods instance.
  • start - the start of the range over which the add should be done.
  • end - the end of the range over which the add should be done.

getResourceAmount

public long getResourceAmount(int start, int end, int info)

Gets the resource amount over this time span. Use this method to condense levels into arbitrary time periods such as months, weeks, or days by calling once for each such period.

  • start - the start of the span.
  • end - the end of the span.
  • info - instructions on how to deal with multiple levels over the span. If there is only one level, key is irrelevant (except for TOTAL). Value is one of: MAXIMUM, MINIMUM, AVERAGE, and TOTAL.

Returns: the amount over the span.

shift

public void shift(int offset)

Shifts the whole table into the future by the specified amount. Using a date will change a zero-based table into a date-based table. (And a negative date will change a date-based table into a zero-based table.)

  • offset - the amount by which the table is to be shifted. Positive values will shift the table into the future, negative values will shift it into the past.

extend

public void extend(int date,
                   boolean future)

Extends this pattern into the future (or past) to the specified date. The last (or first) level will be used. If the date is less than or equal to the last date of the table (or greater than or equal to the first date) nothing will be done.

  • date - the desired finish (or start) date.
  • future - if true the pattern is extended into the future. If false, into the past.

getFirstPeriod

public int[] getFirstPeriod()

Returns the first work period.

Returns: a two-element integer array, the first element being the start of the first work period and the second being its end. Value will be null if this ResourceTable is empty!

getLastPeriod

public int[] getLastPeriod()

Returns the last work period.

Returns: a two-element integer array, the first element being the start of the last work period and the second being its end. Value will be null if this ResourceTable is empty!

align

public void align(TimePeriods table)

Aligns this ResourceTable with the passed table. The amounts on this ResourceTable will start at the beginning of the first active period in table and continue for their original durations, but only during times when the passed table is active. This essentially turns the requirements, if that is what they are, in this ResourceTable into actual usages. Note that this ResourceTable will be changed. Note also that this ResourceTable starts with its first period, and all gaps between periods on it are ignored. (Use zero level periods for needed gaps.)

  • table - the table used to determine the working periods to use. (The resource is considered available after the end of the explicit working periods. Or, the last working period is considered to last into the indefinite future regardless of its explicit end date. If the table is empty, the resource is always available.) This parameter is treated as a pattern, though it need not be one. That is, its levels are ignored; all that matters is whether or not the resource is available (in positive, negative, or zero amounts) over a time span. This parameter's table will not be modified in any way.

align

public void align(TimePeriods table,
                  int date)

Aligns this ResourceTable with the passed table. The amounts on this ResourceTable will start at the date specified by date and continue for their original durations, but only during times when the passed table is active. This essentially turns the requirements in this ResourceTable into actual usages. Note that this ResourceTable will be changed. Note also that this ResourceTable starts with its first period, and all gaps between periods on it are ignored. (Use zero level periods for needed gaps.)

  • table - the table used to determine the working periods to use. (The resource is considered available after the end of the explicit working periods. Or, the last explicit working period is considered to last indefinitly regardless of its explicit end date. If the table is empty, the resource is always available.) This parameter is treated as a pattern, though it need not be one. That is, its levels are ignored; all that matters is whether or not the resource is available (at positive, negative, or zero levels) over a time span. This parameter's table will not be modified in any way.
  • date - the date when this ResourceTable's amounts are to start. From this date on, they will align with table's resource pattern.

intersectPattern

public void intersectPattern(TimePeriods pattern)

Removes any portion of this ResourceTable that falls outside the specified pattern. Those sections within the pattern are unaffected. Note that if the passed pattern has levels, they are ignored. If the passed pattern is continuous from the beginning to the end of time this ResourceTable will remain unchanged. If the passed pattern is not active for any period of time that this ResourceTable is active, this ResourceTable will become empty, or null.

  • pattern - a pattern containing the only time periods where this ResourceTable is to be active.

maskPattern

public void maskPattern(TimePeriods pattern)

Removes any portion of this ResourceTable that falls within the specified pattern. Those sections outside the pattern are unaffected. If the passed pattern has levels, they are ignored. If the passed pattern is continuous from the beginning to the end of time this ResourceTable will become null. If the passed pattern is null this method will do nothing. This method is optimized for the case where neither pattern has large numbers of active periods between any two active periods of the other pattern. One pattern with many periods before the other starts or after the other finishes will not hurt performance.

  • pattern - a pattern containing the time periods where this ResourceTable must not be active.

trim

public void trim(int start,
                 int end)

Retains only those work periods falling within the specified range.

  • start - the start of the time period to be retained. Set to zero if nothing is to be removed from the front.
  • end - the end of the time period to be retained. Set to Integer.MAX_VALUE if nothing is to be removed from the back.

removeZeros

public void removeZeros()

Removes zero level periods from this ResourceTable. Use this with caution. It can remove irrelevant periods, thus simplifying and speeding calculations. However, zero level periods are quite useful under some circumstances, indicating that a resource is there over a period even if it is not used. Availability tables should not use this method. Neither should pattern tables, where all the periods are at level zero. Requirements should not be zeroed, because they need zero periods to align properly with pattern tables. Usage tables often should be zeroed.

removeBelow

public void removeBelow(long minimumLevel)

Removes periods from this ResourceTable whose levels fall below that specified. Often useful in combination with subtract.

  • minimumLevel - The smallest level that will be retained. Usually one.

makePattern

public void makePattern()

Turns this Resource table into a pattern. (All levels will be set to zero and adjacent periods will be combined.)

removeWork

public void removeWork(long work,
                       int time_unit,
                       boolean back)

Removes work from the front of this table. For example, if the table starts on day 1 with a level of 2, then switches to a level of 1 on day 3, and runs to day 10 at that level, and a 5 is passed as the work parameter, the table will then start on day 4, have a level of 1 throughout, and finish on day 10. If the table is 10 days long with a level of 10 throughout, and the amount to be removed is 16, it will then start on the second day with a level of 4. Days 3 through 10 will remain at a level of 10.

  • work - the amount of work to be removed. If greater than or equal to the existing amount of work (which can be obtained from getResourceAmount( int )), all work will be removed.
  • time_unit - the smallest duration allowed for this operation; all durations must be a multiple of it.
  • back - if true work is removed from the end of the table rather than the front. Otherwise, the same rules apply. If false, works as described above.

copy

public ResourceTable copy(int start,
                            int end)

Returns the usage over the specified period in this ResourceTable. Similar to cut, but does not clear or otherwise change any part of this ResourceTable.

  • start - the start of the period to be copied.
  • end - the end of the period to be copied.

Returns: the usage over the specified period.

cut

public ResourceTable cut(int start,
                         int end)

Returns the usage over the specified period and sets it to null in this ResourceTable. Similar to clear, but returns the original usage over the period. (Use clear if the usage is not needed.)

  • start - the start of the period to be cut.
  • end - the end of the period to be cut.

Returns: the usage over the specified period.

combine

public void combine(TimePeriods tp,
                    int start,
                    int end,
                    int key,
                    int action)

Combines a part of the table in a TimePeriods instance with this ResourceTable. Undefined time periods in this table are treated as having a level of zero if levels are combined with them. If this ResourceTable has a calendar, all dates will be on it and all periods will be active only where the calendar is.

  • tp - the TimePeriods instance. Will not be modified in any way.
  • start - the start of the range over which the combination should be done. May be MIN_VALUE to indicate that the add should start at the beginning of time.
  • end - the end of the range over which the add should be done. May be MAX_VALUE to indicate that the add should finish at the end of time.
  • key - indicates actions to be taken. Either CREATE or DEFAULT, with ZERO_IS_NULL optionally orred in.
  • action - one of TOTAL, MAXIMUM, MINIMUM, or AVERAGE.

subtract

public void subtract(TimePeriods tp,
                     int key)

Subtracts the passed TimePeriods instance from this ResourceTable. This effectively subtracts the passed levels from this ResourceTable's levels at all times in this table.

  • tp - the TimePeriods instance to subtract from this ResourceTable.
  • key - valid values are CREATE or DEFAULT with, optionally, ZERO_IS_NULL orred in. DEFAULT will make sure the subtraction does not add periods of (usually) negative levels to this table; do not use CREATE here unless you know what you are doing.

clear

public void clear(int start,
                  int end)

Sets usage to null over the specified period.

  • start - the start of the period to be cleared. Set to zero to start as early as possible.
  • end - the end of the period to be cleared. Set to Integer.MAX_VALUE to go as late as possible.

getDifference

public long getDifference(TimePeriods tp,
                          int start,
                          int finish,
                          long def,
                          long tpdef,
                          int info)

Gets the difference resulting from subtracting the passed TimePeriods from this ResourceTable over the specified time period.

  • tp - the TimePeriods instance to subtract from this ResourceTable.
  • start - the start date of the time period.
  • finish - the finish date of the time period.
  • def - the default value to use where this ResourceTable has no defined level.
  • tpdef - the default value to use where the passed TimePeriods instance has no defined period.
  • info - determines how the returned value is calculated. One of: MAXIMUM, MINIMUM, TOTAL, or AVERAGE. Note that TOTAL and AVERAGE treat negative values identically to zeros. Hence two minutes at -2 and two minutes at 2 would yield 4 for TOTAL and 1 for AVERAGE.

Returns: the amount by which this ResourceTable exceeds tp over the time period.

exceeds

public boolean exceeds(TimePeriods tp,
                       int start,
                       int end)

Returns true if this ResourceTable exceeds the availability in the passed TimePeriod at any point over the passed duration.

  • tp - the usage against which this ResourceTable is to be checked.
  • start - the beginning of the relevant duration.
  • end - the end of the relevant duration.

Returns: true if this ResourceTable exceeds the passed availability at any point, or if it exists where the passed TimePeriods instance does not. Otherwise it returns false. Especially: it will return false if the duration is zero or less than zero; it will return true if the first parameter is null.

getNextDateAbove

public int getNextDateAbove(long level, int date, int end, boolean above)

Gets the first date at or after the specified date where the level goes above the specified level.

  • level - the level to be exceeded.
  • date - the date on or after which the exceeding must take place.
  • end - a date after which searching should stop. If this parameter is not needed, it should be set to Integer.MAX_VALUE. The closer it is to date, the more efficiently the method will work.
  • above - true if the search is for the time the level goes above the specified date, false if the search is really for the time the level goes below the specified date. Normally set to true.

Returns: the date at which the level exceeds the specified level. If it never does, Integer.MAX_VALUE will be returned.

getPreviousDateAbove

public int getPreviousDateAbove(long level, int date, int end, boolean above)

Gets the first date on or before the specified date where the level goes above the specified level.

  • level - the level to be exceeded.
  • date - the date on or before which the exceeding must take place.
  • end - a date before which searching should stop. If this parameter is not needed, it should be set to zero. The closer it is to date, the more efficiently the method will work.
  • above - true if the search is for the time the level goes above the specified date, false if the search is really for the time the level goes below the specified date. Normally set to true.

Returns: the date at which the level exceeds the specified level. If it never does, zero will be returned.

getResourceAmount

public long getResourceAmount(int info)

Gets the resource amount over all time.

  • info - instructions on how to deal with multiple levels over the span. If there is only one level, key is irrelevant (except for TOTAL). Value is one of: MAXIMUM, MINIMUM, AVERAGE, and TOTAL.

Returns: the amount over all time.

compare

public UsageTable.Within compare(TimePeriods table, int offset, long extra, int start, int end, boolean gapOK)

Compares two resource tables. Specifically, checks to see if the passed one fits within this one and for how long. Generally, this table is going to be an availability, while the passed one is going to be a requirement. The passed one will be in times rather than dates, and will need the passed date as an offset to align it with this ResourceTable.

This method was designed specifically for scheduling jobs based on resource availability ("Resource Scheduling" or "Resource Leveling" in Project Management terminology).

  • table - the table being checked to see how it fits.
  • offset - the date which should be added to the (presumed) times in the passed table to align them with this table.
  • extra - a level to be added to all the levels in this ResourceTable. By making this value large enough, any requirement can be forced to fit anywhere this resource exists. (Except across gaps in the resource.)
  • start - the comparison starts from this date. Earlier availabilities and requirements are ignored.
  • end - a date past which there is no need to check. This may be set to Integer.MAX_VALUE if the passed table is to be checked to its end.
  • gapOK - if true, the availability in a gap is considered infinite. If false, it is considered to be zero.

Returns: a Within instance. This gives the date out to which the passed table fits and the amount it misses by when it fails to fit. If it fits all the way the "miss" amount will be zero or less. Also gives the next time the resource has a possibility of fitting.

nextGap

public boolean nextGap(int date,
                       int max,
                       int[] gap)

Returns the first gap in the resource after the specified date. If the date falls within a gap--from start, inclusive, to finish, exclusive--that gap is returned. The periods before the resource starts and after it ends are treated as gaps. Gaps are periods without levels. A level of zero does not constitute a gap.

  • date - the date from which to start looking for gaps.
  • max - the date past which no more checking should be done.
  • gap - a two element integer array into which the start and end dates of the gap will be placed.

Returns: true if a valid gap was returned, false if there were no relevant gaps before the date in max.

previousGap

public boolean previousGap(int date,
                           int min,
                           int[] gap)

Returns the first gap in the resource before the specified date. If the date falls within a gap--from start, exclusive, to finish, inclusive--that gap is returned. The periods before the resource starts and after it ends are treated as gaps. Gaps are periods without levels. A level of zero does not constitute a gap.

  • date - the date from which to start looking for gaps.
  • min - the date before which no more checking should be done.
  • gap - a two element integer array into which the start and end dates of the gap will be placed.

Returns: true if a valid gap was returned, false if there were no relevant gaps.

reScale

public void reScale(int scale,
                    int resUnit,
                    int durUnit )

Time scales this resource table by the specified scaling amount. Intended primarily for adjusting work amounts based on the efficiency with which the work might be done. Meant for modifying requirements; other use is not recommended. Each usage period has its duration extended or contracted based on scale. Contiguous periods will start earlier or later as necessary to remain contiguous. If there is a gap between a period and its predecessor, that period will continue to start at the same time unless the predecessor's expansion forces it to start later. All work is rounded to the nearest resUnit. Remainders are carried over to the next period, so that even complex patterns will have their total work adjusted to the nearest resUnit.

  • scale - the amount to scale by, as a percentage of the current work. This reflects efficiency changes. The efficiency is halved, the duration doubles. So: 100 will do nothing. 50 will double all durations. 200 will halve all durations.
  • resUnit - the smallest allowable unit of work (in resource-minutes). Usually 60, indicating hours.
  • durUnit - the smallest allowable unit of duration (in minutes). Usually 1, indicating minutes.

removeAbove

public void removeAbove(long maximumLevel)

Removes periods from this ResourceTable whose levels fall above that specified. Often provides a pattern showing trouble spots in that availabilities are running out in the remaining periods. (We are using more than we have.)

  • maximumLevel - The highest level that will be retained. Usually negative one, indicating a lack of resources.

isNull

public boolean isNull(int start, int finish)

Returns true if this ResourceTable contains no working periods during the passed duration.

  • start - the start of the duration.
  • finish - the end of the duration.

isNull

public boolean isNull()

Returns true if this ResourceTable instance contains no working periods.

isTrivial

public boolean isTrivial()

Returns true if this ResourceTable instance contains no non-working periods.

copy

public ResourceTable copy()

Returns a shallow copy of this ResourceTable.

getStartDate

public int getStartDate()

Returns the earliest active date of this ResourceTable.

getFinishDate

public int getFinishDate()

Returns the latest active date of this ResourceTable.

getPatternIterator

public TimePeriodIterator getPatternIterator(int date,   
                                             int flag,
                                             boolean find)

Gets a TimePeriodIterator whose current period is as specified by the given date and flag. If no such period can be found, the current period will be null. (A null period is one where the valid field in the iterator's associated TimePeriodData instance is false.) Note that each successive set of data in the associated TimePeriodData instance will be distinct from the set of data preceeding it with a gap between the periods. This iterator will treat contiguous periods as one period, making it look like a pattern.

  • date - indicates the current period of the returned TimePeriodIterator instance.
  • flag - indicates the required relationship between date and the start of the returned period. Valid value is one of: FIND_FIRST, FIND_LESS, FIND_LESS_EQUAL, FIND_EQUAL, FIND_GREATER_EQUAL, FIND_GREATER, and FIND_LAST. (FIND_FIRST and FIND_LAST will ignore date.)
  • find - when false, works normally. If true, and if the current period would otherwise be null, it sets the current period to the first period found in the opposite direction specified by the flag. For example, setting a flag of FIND_LESS and a date of 13May2025 when the first period starts on 18May2025 will normally return a null. With this parameter set to true, it will return the 18May2025 period.

Returns: a TimePeriodIterator instance positioned as specified.

getUsageIterator

public TimePeriodIterator getUsageIterator(int date,
                                           int flag,
                                           boolean find)

Gets a TimePeriodIterator whose current period is as specified by the given date and flag. If no such period can be found, the current period will be null. (A null period is one where the valid field in the iterator's associated TimePeriodData instance is false.) Note that each successive set of data in the associated TimePeriodData instance will be distinct from the set of data preceeding it. This may result from different levels or from a gap between the periods. Each valid TimePeriodData instance will include a meaningful level.

  • date - indicates the current period of the returned TimePeriodIterator instance.
  • flag - indicates the required relationship between date and the start of the returned period. Valid value is one of: FIND_FIRST, FIND_LESS, FIND_LESS_EQUAL, FIND_EQUAL, FIND_GREATER_EQUAL, FIND_GREATER, and FIND_LAST. (FIND_FIRST and FIND_LAST will ignore date.)
  • find - when false, works normally. If true, and if the current period would otherwise be null, it sets the current period to the first period found in the direction opposite that specified by the flag. For example, setting a flag of FIND_LESS and a date of 13May2025 when the first period starts on 18May2025 will normally return a null. With this parameter set to true, it will return the 18May2025 period.

Returns: a TimePeriodIterator instance positioned as specified.

getDurationStart

public int getDurationStart(int end,
                            int duration,
                            boolean late)

Returns the start of the passed duration based on the passed end date and relative to this ResourceTable. (For the the purposes of this method, the resource is considered to run continuously from the indefinite past until the end of its first defined period. If the table has no entries, the resource is considered to be always active.)

  • end - the date on which the resource is to finish work.
  • duration - the amount of time the resource must work to complete the task.
  • late - used only when the start date falls on the edge of a non-working period. If true, the end of the non-working period will be returned, which is appropriate for start dates. If false, the finish of the non-working period will be returned.

Returns: the date the job must start so that, when the resource works on it for the required amount of time, it finishes at the given date.

getDurationFinish

public int getDurationFinish(int start,
                             int duration,
                             boolean late)

Returns the end of the passed duration based on the passed start date and relative to this ResourceTable. (For the the purposes of this method, the resource is considered to run continuously from the start of its last defined period into the indefinite future. If the table has no entries, the resource is considered to be always active. However, it will always use the calendar!)

  • start - the date on which the resource is to start work.
  • duration - the amount of time the resource must work to complete the task.
  • late - valid only when the finish date falls on the edge of a non-working period. If false, the start of the non-working period will be returned, which is appropriate for end dates. If true, the finish of the non-working period will be returned.

Returns: the date the job will be done when the resource works on it for the required amount of time starting at the given date.

getValidStart

public int getValidStart(intdate)

Gets the first valid time for this ResourceTable on or after the specified date. For the the purposes of this method, work is considered to run continuously from the start of this ResourceTable's last defined period into the indefinite future. If the table has no entries, this ResourceTable is considered to be always active and date's value will simply be returned.

  • date - the earliest valid return date.

Returns: the first valid date on or after the given date.

getValidFinish

public int getValidFinish(intdate)

Gets the last valid time for this ResourceTable on or before the specified date. For the the purposes of this method, work is considered to run continuously from the indefinite past until the end of its first defined period. If the table has no entries, this ResourceTable is considered to be always active and date's value will simply be returned.

  • date - the latest valid return date.

Returns: the last valid date on or before the given date.

getDuration

public int getDuration()

Gets the time worked by the resource over the entire table. The same as calling getResourceDuration( TimePeriods.MIN_VALUE, TimePeriods.MAX_VALUE, false, false ), but faster for both computer and programmer.

Returns: the time actually worked by the resource.

getDuration

public int getDuration(int start,
                       int end,
                       boolean before,
                       boolean after)

Gets the time worked by the resource between the two dates. If all that is needed is the knowledge that the duration is greater than zero, call hasDuration for greater speed.

  • start - the start time of the work period.
  • end - the end time of the work period. If less than (or equal to) start method returns zero.
  • before - if true, all time before the first work period is considered to be a working period.
  • after - if true, all time after the last work period is considered to be a working period.

Returns: the time actually worked by the resource.

hasDuration

public boolean hasDuration(int start,
                           int end,
                           boolean before,
                           boolean after)

Determines if time has been worked by the resource between the two dates. Faster than getDuration, but provides less information.

  • start - the start time of the work period.
  • end - the end time of the work period.
  • before - if true, all time before the first work period is considered to be a working period.
  • after - if true, all time after the last work period is considered to be a working period.

Returns: true if time was worked, false if the resource was inactive between the two dates.

clear

public void clear()

Renders this ResourceTable null. It will contain no working time. This ResourceTable will be in the same state it was in when first created.

read

public void read(java.io.DataInput in)

Reads an instance of ResourceTable from an external source.

write

public void write(java.io.DataOutput out)

Writes an instance of ResourceTable to an external source.

readExternal

public void readExternal(java.io.ObjectInput in)

Reads an instance of ResourceTable from an external source.

writeExternal

public void writeExternal(java.io.ObjectOutputout)

Writes an instance of ResourceTable to an external source.

setCalendar

public void setCalendar(TimeCalendar c,
                        long level)

Sets the calendar and default level for this ResourceTable instance. The default level causes the ResourceTable to exist everywhere the calendar is active at that level. If this method is called, the resource will only be available when the calendar is active. If this method is not called, the resource will not exist anywhere except as explicitly entered with the add methods. If this method is to be used, call it immediately after creating this ResourceTable. Then add in those periods where the level differs from the passed default (level).

  • c - the calendar for the ResourceTable. May be null, which causes the default level to run from the beginning to the end of time with no gaps. Note that this calendar will affect even those periods where the table is null yet a default value is assumed to make calculations meaningful (for example: getDurationStart).
  • level - the default level over the calendar's working period. Usually zero. Set to Long.MIN_VALUE to set a null level.

getCalendar

public TimeCalendar getCalendar()

Returns this ResourceTable's calendar. If it has no calendar, as will often be the case, it will return null.

User Reviews

No reviews have been submitted yet.

Questions & Comments


Or enter your name and Email
No comments have been posted yet.
You must be logged-in to vote. Log-in to your account or register now.