38 private array $entries = [];
39 private bool $clean =
false;
45 foreach($entries as $entry){
46 $this->entries[$entry->getFirstSector()] = $entry;
55 foreach($locationTable as $entry){
59 if(isset($usedMap[$entry->getFirstSector()])){
62 $usedMap[$entry->getFirstSector()] = $entry;
65 ksort($usedMap, SORT_NUMERIC);
70 foreach($usedMap as $entry){
71 $prevEndPlusOne = ($prevEntry !==
null ? $prevEntry->getLastSector() + 1 : RegionLoader::FIRST_SECTOR);
72 $currentStart = $entry->getFirstSector();
73 if($prevEndPlusOne < $currentStart){
76 }elseif($prevEndPlusOne > $currentStart){
83 return new self($garbageMap);
92 ksort($this->entries, SORT_NUMERIC);
96 foreach($this->entries as $k => $entry){
97 if($prevIndex !==
null && $this->entries[$prevIndex]->getLastSector() + 1 === $entry->getFirstSector()){
100 $this->entries[$prevIndex]->getFirstSector(),
101 $this->entries[$prevIndex]->getSectorCount() + $entry->getSectorCount(),
104 unset($this->entries[$k]);
111 return $this->entries;
114 public function add(RegionLocationTableEntry $entry) : void{
115 if(isset($this->entries[$k = $entry->getFirstSector()])){
116 throw new \InvalidArgumentException(
"Overlapping entry starting at " . $k);
118 $this->entries[$k] = $entry;
119 $this->clean =
false;
122 public function remove(RegionLocationTableEntry $entry) : void{
123 if(isset($this->entries[$k = $entry->getFirstSector()])){
125 unset($this->entries[$k]);
129 public function end() : ?RegionLocationTableEntry{
130 $array = $this->getArray();
132 return $end !==
false ? $end :
null;
135 public function allocate(
int $newSize) : ?RegionLocationTableEntry{
136 foreach($this->getArray() as $start => $candidate){
137 $candidateSize = $candidate->getSectorCount();
138 if($candidateSize < $newSize){
142 $newLocation =
new RegionLocationTableEntry($candidate->getFirstSector(), $newSize, time());
143 $this->
remove($candidate);
145 if($candidateSize > $newSize){
146 $newGarbageStart = $candidate->getFirstSector() + $newSize;
147 $newGarbageSize = $candidateSize - $newSize;
148 $this->add(
new RegionLocationTableEntry($newGarbageStart, $newGarbageSize, 0));