Full refund within 14 days of purchase date.
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.
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.
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.
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
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;
}
}
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.)
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.
Questions & Comments