Resizes existing memory mapping, reusing or creating new mapping as needed.
(int fd, long mmapCacheKey, long address, long previousSize, long newSize, long offset, int flags, int memoryTag)
| 127 | * Resizes existing memory mapping, reusing or creating new mapping as needed. |
| 128 | */ |
| 129 | public long mremap(int fd, long mmapCacheKey, long address, long previousSize, long newSize, long offset, int flags, int memoryTag) { |
| 130 | if (newSize < 1) { |
| 131 | throw CairoException.critical(0) |
| 132 | .put("could not remap file, invalid newSize [previousSize=").put(previousSize) |
| 133 | .put(", newSize=").put(newSize) |
| 134 | .put(", offset=").put(offset) |
| 135 | .put(", fd=").put(fd) |
| 136 | .put(", memoryTag=").put(memoryTag) |
| 137 | .put(']'); |
| 138 | } |
| 139 | if (offset != 0 || mmapCacheKey == 0 || !Files.FS_CACHE_ENABLED || flags == Files.MAP_RW) { |
| 140 | return mremap0(fd, address, previousSize, newSize, offset, flags, memoryTag, memoryTag); |
| 141 | } |
| 142 | if (previousSize == 0) { |
| 143 | // If previous size is 0, we cannot remap, just mmap a new region |
| 144 | return cacheMmap(fd, mmapCacheKey, newSize, offset, flags, memoryTag); |
| 145 | } |
| 146 | |
| 147 | long unmapPtr = 0, unmapLen = 0; |
| 148 | int unmapTag = 0; |
| 149 | long newAddress = 0; |
| 150 | |
| 151 | synchronized (this) { |
| 152 | |
| 153 | int addrMapIndex = mmapAddrCache.keyIndex(address); |
| 154 | assert addrMapIndex < 0 : "old address is not found in mmap cache"; |
| 155 | |
| 156 | MmapCacheRecord record = mmapAddrCache.valueAt(addrMapIndex); |
| 157 | |
| 158 | int fdIndex = Integer.MAX_VALUE; |
| 159 | if (newSize >= previousSize) { |
| 160 | if (record.length >= newSize) { |
| 161 | // Address is already long enough, just return it |
| 162 | return address; |
| 163 | } |
| 164 | |
| 165 | // Check if someone else remapped this to a larger size |
| 166 | fdIndex = mmapFileCache.keyIndex(mmapCacheKey); |
| 167 | if (fdIndex < 0) { |
| 168 | MmapCacheRecord updatedCacheRecord = mmapFileCache.valueAt(fdIndex); |
| 169 | if (updatedCacheRecord.length >= newSize) { |
| 170 | // Cache for the FD is updated by someone else |
| 171 | // The fd cache record is already long enough, just return the address |
| 172 | updatedCacheRecord.count++; |
| 173 | newAddress = updatedCacheRecord.address; |
| 174 | // We should not store zero addresses in the cache. We do not cache if someone maps 0 length, |
| 175 | // and we do not allow to remap to 0 length. |
| 176 | assert newAddress != 0; |
| 177 | mmapReuseCount++; |
| 178 | |
| 179 | record.count--; |
| 180 | if (record.count == 0) { |
| 181 | // The old cache record is not used anymore |
| 182 | mmapAddrCache.removeAt(addrMapIndex); |
| 183 | unmapPtr = record.address; |
| 184 | unmapLen = record.length; |
| 185 | unmapTag = record.memoryTag; |
| 186 | record.address = 0; |
nothing calls this directly
no test coverage detected