| 265 | |
| 266 | /* write a chunk at (x,z) with length bytes of data to disk */ |
| 267 | protected synchronized void write(int x, int z, byte[] data, int length) { |
| 268 | try { |
| 269 | int offset = this.getOffset(x, z); |
| 270 | int sectorNumber = offset >> 8; |
| 271 | int sectorsAllocated = offset & 0xFF; |
| 272 | int sectorsNeeded = (length + RegionFile.CHUNK_HEADER_SIZE) / RegionFile.SECTOR_BYTES + 1; |
| 273 | |
| 274 | // maximum chunk size is 1MB |
| 275 | if (sectorsNeeded >= 256) { |
| 276 | return; |
| 277 | } |
| 278 | |
| 279 | if (sectorNumber != 0 && sectorsAllocated == sectorsNeeded) { |
| 280 | /* we can simply overwrite the old sectors */ |
| 281 | this.debug("SAVE", x, z, length, "rewrite"); |
| 282 | this.write(sectorNumber, data, length); |
| 283 | } else { |
| 284 | /* we need to allocate new sectors */ |
| 285 | |
| 286 | /* mark the sectors previously used for this chunk as free */ |
| 287 | for (int i = 0; i < sectorsAllocated; ++i) { |
| 288 | this.sectorFree.set(sectorNumber + i, true); |
| 289 | } |
| 290 | |
| 291 | /* scan for a free space large enough to store this chunk */ |
| 292 | int runStart = this.sectorFree.indexOf(true); |
| 293 | int runLength = 0; |
| 294 | if (runStart != -1) { |
| 295 | for (int i = runStart; i < this.sectorFree.size(); ++i) { |
| 296 | if (runLength != 0) { |
| 297 | if (this.sectorFree.get(i)) { |
| 298 | runLength++; |
| 299 | } else { |
| 300 | runLength = 0; |
| 301 | } |
| 302 | } else if (this.sectorFree.get(i)) { |
| 303 | runStart = i; |
| 304 | runLength = 1; |
| 305 | } |
| 306 | if (runLength >= sectorsNeeded) { |
| 307 | break; |
| 308 | } |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | if (runLength >= sectorsNeeded) { |
| 313 | /* we found a free space large enough */ |
| 314 | this.debug("SAVE", x, z, length, "reuse"); |
| 315 | sectorNumber = runStart; |
| 316 | this.setOffset(x, z, (sectorNumber << 8) | sectorsNeeded); |
| 317 | for (int i = 0; i < sectorsNeeded; ++i) { |
| 318 | this.sectorFree.set(sectorNumber + i, false); |
| 319 | } |
| 320 | this.write(sectorNumber, data, length); |
| 321 | } else { |
| 322 | /* |
| 323 | * no free space large enough found -- we need to grow the file |
| 324 | */ |