Record Class MergeOptions
- Record Components:
asymmetricMergeMode- Whether to merge everything, only partially-occupied periods or nothing.recurse- If true, merged items may be merged again if necessary; so that an arbitrary number of RoomScheduleItems may be merged into one (as long as the criteria are fulfilled). If false, two RoomScheduleItems newly merged together shall not be merged a second time.maximumComponentLength- If set, RoomScheduleItems whose duration is longer than thisDurationshall not be merged.maximumGap- If set, then two items are considered “consecutive” if they are no further than thisDurationapart. If unset, there must be no gap between two items in order to be considered consecutive.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumSpecifies which RoomScheduleItems are allowed to be merged. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final MergeOptions.AsymmetricMergeModeThe field for theasymmetricMergeModerecord component.private final @Nullable DurationThe field for themaximumComponentLengthrecord component.private final @Nullable DurationThe field for themaximumGaprecord component.private final booleanThe field for therecurserecord component. -
Constructor Summary
ConstructorsConstructorDescriptionMergeOptions(MergeOptions.AsymmetricMergeMode asymmetricMergeMode, boolean recurse, @Nullable Duration maximumComponentLength, @Nullable Duration maximumGap) Creates an instance of aMergeOptionsrecord class. -
Method Summary
Modifier and TypeMethodDescriptionReturns the value of theasymmetricMergeModerecord component.doublecomputeMergeScore(@NonNull RoomScheduleItem lastItem, @NonNull RoomScheduleItem newItem, int roomCapacity) Calculates a score that indicates how well the given RoomScheduleItems are suited for merging.final booleanIndicates whether some other object is "equal to" this one.final inthashCode()Returns a hash code value for this object.booleanisMergeRequired(@NonNull RoomScheduleItem lastItem, @NonNull RoomScheduleItem newItem, int roomCapacity) Determines whether the given two RoomScheduleItems shall be merged.private static booleanisPairing(@NonNull RoomScheduleItem item1, @NonNull RoomScheduleItem item2, @NonNull RoomStatus status1, @NonNull RoomStatus status2, boolean orderMatters) Checks whether the given RoomScheduleItems have the given RoomStatuses as theRoomScheduleItem.status.@Nullable DurationReturns the value of themaximumComponentLengthrecord component.@Nullable DurationReturns the value of themaximumGaprecord component.booleanrecurse()Returns the value of therecurserecord component.final StringtoString()Returns a string representation of this record class.private booleanviolatesMergeMode(@NonNull RoomScheduleItem item1, @NonNull RoomScheduleItem item2) Checks whether theasymmetricMergeModeprohibits merging the given two RoomScheduleItems.
-
Field Details
-
asymmetricMergeMode
The field for theasymmetricMergeModerecord component. -
recurse
private final boolean recurseThe field for therecurserecord component. -
maximumComponentLength
The field for themaximumComponentLengthrecord component. -
maximumGap
The field for themaximumGaprecord component.
-
-
Constructor Details
-
MergeOptions
public MergeOptions(@NonNull MergeOptions.AsymmetricMergeMode asymmetricMergeMode, boolean recurse, @Nullable @Nullable Duration maximumComponentLength, @Nullable @Nullable Duration maximumGap) Creates an instance of aMergeOptionsrecord class.- Parameters:
asymmetricMergeMode- the value for theasymmetricMergeModerecord componentrecurse- the value for therecurserecord componentmaximumComponentLength- the value for themaximumComponentLengthrecord componentmaximumGap- the value for themaximumGaprecord component
-
-
Method Details
-
getMaximumComponentLength
- Returns:
- The
maximumComponentLengthin a null-safe manner.
-
isMergeRequired
@Contract(pure=true) public boolean isMergeRequired(@NonNull @NonNull RoomScheduleItem lastItem, @NonNull @NonNull RoomScheduleItem newItem, int roomCapacity) Determines whether the given two RoomScheduleItems shall be merged.- Parameters:
lastItem- The RoomScheduleItem that comes first in time.newItem- The RoomScheduleItem that comes second in time.roomCapacity- TheRoom.capacityof theReservation.roomwhich the given RoomScheduleItems correspond to.- Returns:
- True if they shall be merged, false otherwise.
-
computeMergeScore
@Contract(pure=true) public double computeMergeScore(@NonNull @NonNull RoomScheduleItem lastItem, @NonNull @NonNull RoomScheduleItem newItem, int roomCapacity) Calculates a score that indicates how well the given RoomScheduleItems are suited for merging. The higher the score, the better the two items are suited to be merged together.
The result will be calculated as follows, in this exact order of importance:
- 0 if the two items overlap or if the
newItemcomes before thelastItem. - 0 if the gap between the
RoomScheduleItem.endTimeof thelastItemand theRoomScheduleItem.startTimeof thenewItemis greater than themaximumGap. - 0 if no
maximumGapis set and the end time of thelastItemdoes not match the start time of thenewItem. Double.MAX_VALUEif both items have the sameRoomScheduleItem.occupancyand there is no gap.- 0 if
asymmetricMergeModeis set to NONE. - 0 if
asymmetricMergeModeprohibits merging. - 0 if
maximumComponentLengthis set and both items have a longer duration. - Otherwise, the result is
min{1, |1/x|} * min{1, |1/y|} * min{1, |o - u|} * min{1, √g} ∈ (0,1]wherexis thelastItem's duration in minutes,yis thenewItem's duration in minutes,ois thelastItem'sRoomScheduleItem.occupancy(or 0 if null),uis thenewItem's occupancy (or 0 if null) andgis the gap between the two items in minutes
In other words, items that are not consecutive shall never be merged, and consecutive items with the same occupancy shall always be merged.
- Parameters:
lastItem- The RoomScheduleItem that comes first.newItem- The RoomScheduleItem that comes second.roomCapacity- TheRoom.capacityof theReservation.roomwhich the given RoomScheduleItems correspond to.- Returns:
- The merge score.
- Implementation Note:
- This method has constant time complexity.
- 0 if the two items overlap or if the
-
violatesMergeMode
@Contract(pure=true) private boolean violatesMergeMode(@NonNull @NonNull RoomScheduleItem item1, @NonNull @NonNull RoomScheduleItem item2) Checks whether the
asymmetricMergeModeprohibits merging the given two RoomScheduleItems.Merging is allowed if:
- The merge mode is not
MergeOptions.AsymmetricMergeMode.PARTIAL_OCCUPANCIESor - both items have
RoomStatus.PARTIALLY_OCCUPIEDas theRoomScheduleItem.status.
Merging a partially occupied and a free item
Naturally, when there is a gap between two RoomScheduleItems
o1ando2which both indicate that the Room is partially or fully occupied, then those items are usually separated by a free itemfinstead of empty space:o1 f o2. If the gap – i.e. the free itemf– does not exceed themaximumGapthreshold, then the two partially/fully occupied itemso1ando2shall be merged. Technically, however, the free itemfwhich represents the gap must be included in the merge, i.e. all three items must be merged.So, if one of the two items given to this method is a “partially occupied” item while the other one is a free item, then they are allowed to be merged if there is no gap between them and if the free item is shorter than the
maximumGapduration.If no
maximumGapis set, theno1ando2would only be allowed to be merged if there were no gap (i.e. free itemf). But there is a gap (namely itemf), so mergingo1ando2is not permitted in the absence of themaximumGap, and thuso1cannot be merged withfeither.- Parameters:
item1- The item that comes first in time.item2- The item that comes second in time.- Returns:
- True if the two items must not be merged because of the merge mode. False if the merge mode does not ban merging the two items. However, some other condition might prevent the items from being merged.
- The merge mode is not
-
isPairing
@Contract(pure=true) private static boolean isPairing(@NonNull @NonNull RoomScheduleItem item1, @NonNull @NonNull RoomScheduleItem item2, @NonNull @NonNull RoomStatus status1, @NonNull @NonNull RoomStatus status2, boolean orderMatters) Checks whether the given RoomScheduleItems have the given RoomStatuses as theRoomScheduleItem.status.- Parameters:
item1- The first RoomScheduleItem to check.item2- The second RoomScheduleItem to check.status1- The status thatitem1must have if theorderMatters. If the order does not matter, eitheritem1oritem2must have this status.status2- The status thatitem2must have if theorderMatters. If the order does not matter, eitheritem1oritem2must have this status.orderMatters- If true, thenitem1must matchstatus2anditem2must matchstatus2. If false, then the combination “item1matchesstatus2anditem2matchesstatus1” is also permitted.- Returns:
- True if the items match the specified pairing, false otherwise.
-
toString
-
hashCode
-
equals
Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. Reference components are compared withObjects::equals(Object,Object); primitive components are compared with thecomparemethod from their corresponding wrapper classes. -
asymmetricMergeMode
Returns the value of theasymmetricMergeModerecord component.- Returns:
- the value of the
asymmetricMergeModerecord component
-
recurse
-
maximumComponentLength
Returns the value of themaximumComponentLengthrecord component.- Returns:
- the value of the
maximumComponentLengthrecord component
-
maximumGap
Returns the value of themaximumGaprecord component.- Returns:
- the value of the
maximumGaprecord component
-