"StorageAllocation.bist"
package: com.ecodepot.storage;
import: com.ecodepot.assets.StorageBuilding;
"StorageAllocation responsibilities:
- knows a kind of hazard,
- knows a drum count assigned to a storage building,
- allocates drum storage to a storage building,
- applies drum storage safety policies during allocation.
StorageAllocation class responsibilities:
- produces prospective storage allocations,
- balances storage across prospective allocations.
"
@author Copyright 2004 Nikolas S. Boyd. All rights reserved."
Object subclass: StorageAllocation
metaclass: [
"prospecting"
"Returns the storage allocation prospects containing a given hazard."
prospectsContaining: hazard [
^((StorageBuilding structuresLicensedToStore: hazard)
collect: [ :building | self new initialize: building containing: hazard ])
asSortedCollection: self allocationSortBlock
]
"Returns a block to sort prospective allocations in decreasing order by capacity."
allocationSortBlock [
^[ :priorAlloc :nextAlloc |
priorAlloc remainingStorageCapacity >
nextAlloc remainingStorageCapacity ]
]
"sharing storage"
"Returns the largest portion that can be shared between some allocations."
maximalShareBetween: allocations [
allocations isEmpty ifTrue: [ ^0 ].
^(self capacityRemaining: allocations) / allocations size
]
"Returns the smallest portion of a drum count that can be shared between some allocations."
minimalShare: drumCount between: allocations [
allocations isEmpty ifTrue: [ ^0 ].
^drumCount / allocations size
]
"Returns the total building storage capacity of some allocations."
capacityOfBuildings: allocations [
allocations isEmpty ifTrue: [ ^0 ].
^(allocations collect: [ :allocation | allocation buildingStorageCapacity ]) sum
]
"Returns the total remaining storage capacity of some allocations."
capacityRemaining: allocations [
allocations isEmpty ifTrue: [ ^0 ].
^(allocations collect: [ :allocation | allocation remainingStorageCapacity ]) sum
]
]
class: [
private hazard.
private drumCount.
private building.
"accessing"
"Returns the allocation hazard."
hazard [ ^hazard ]
"Returns the allocation drum count."
drumCount [ ^drumCount ]
"Returns the allocation building."
building [ ^building ]
"allocating storage"
"Returns the remaining building storage capacity before ."
buildingStorageCapacity [
^(self building drumStorage: self hazard) capacity
]
"Returns the storage capacity remaining in the associated building after this allocation."
remainingStorageCapacity [
^self buildingStorageCapacity - self drumCount
]
"Returns the drum count that this allocation can consume."
consumableDrums: count [
^self remainingStorageCapacity min: count
]
"Returns the largest portion of a drum count that can be removed from the associated building."
releasableDrums: count [
^self drumCount min: count
]
"Returns the remaining drum count after consuming as many as possible."
remainderAfterConsumingSome: count [
delta := self consumableDrums: count.
drumCount := drumCount + delta.
^count - delta
]
"Transfers as many drums as possible from this allocation to another."
transferDrums: count to: allocation [
transferDrums := allocation consumableDrums: (self releasableDrums: count).
allocation remainderAfterConsumingSome: transferDrums.
drumCount := drumCount - transferDrums.
]
"ensuring safety"
"Indicates whether the allocated drums fill the building."
fillsBuilding [
^self remainingStorageCapacity = 0
]
"Returns those allocations that (would) fill the neigboring buildings."
fullNeighbors: allocations [
^(self neighboringAllocations: allocations)
select: [ :allocation | allocation fillsBuilding ]
]
"Indicates whether this allocation makes the depot vulnerable along with other allocations."
makesDepotVulnerableWith: allocations [
^self fillsBuilding and: [ (self fullNeighbors: allocations) notEmpty ]
]
"Returns those allocations whose buildings neighbor the one associated with this allocation."
neighboringAllocations: allocations [
^(allocations copyWithout: self)
select: [ :allocation | allocation building neighbors: self building ]
]
] "StorageAllocation"