forked from openrs2/openrs2
parent
e0a2df889b
commit
6aea0cfc8e
@ -0,0 +1,91 @@ |
||||
package org.openrs2.cache |
||||
|
||||
import io.netty.buffer.ByteBuf |
||||
import java.nio.file.attribute.FileTime |
||||
import java.time.Instant |
||||
import java.util.zip.Deflater |
||||
import java.util.zip.ZipEntry |
||||
import java.util.zip.ZipOutputStream |
||||
|
||||
/** |
||||
* A specialised [Store] implementation that writes a cache in the |
||||
* [FlatFileStore] format to a [ZipOutputStream]. |
||||
* |
||||
* The cache is not buffered to disk. |
||||
* |
||||
* This implementation only supports the [create] and [write] methods. All |
||||
* other methods throw [UnsupportedOperationException]. |
||||
* |
||||
* It is only intended for use by the cache archiving service's web interface. |
||||
*/ |
||||
public class FlatFileStoreZipWriter( |
||||
private val out: ZipOutputStream, |
||||
private val prefix: String = "cache/", |
||||
level: Int = Deflater.BEST_COMPRESSION, |
||||
timestamp: Instant = Instant.EPOCH |
||||
) : Store { |
||||
private val timestamp = FileTime.from(timestamp) |
||||
|
||||
init { |
||||
out.setLevel(level) |
||||
} |
||||
|
||||
private fun createZipEntry(name: String): ZipEntry { |
||||
val entry = ZipEntry(prefix + name) |
||||
entry.creationTime = timestamp |
||||
entry.lastAccessTime = timestamp |
||||
entry.lastModifiedTime = timestamp |
||||
return entry |
||||
} |
||||
|
||||
override fun exists(archive: Int): Boolean { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun exists(archive: Int, group: Int): Boolean { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun list(): List<Int> { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun list(archive: Int): List<Int> { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun create(archive: Int) { |
||||
require(archive in 0..Store.MAX_ARCHIVE) |
||||
|
||||
out.putNextEntry(createZipEntry("$archive/")) |
||||
} |
||||
|
||||
override fun read(archive: Int, group: Int): ByteBuf { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun write(archive: Int, group: Int, buf: ByteBuf) { |
||||
require(archive in 0..Store.MAX_ARCHIVE) |
||||
require(group >= 0) |
||||
require(buf.readableBytes() <= Store.MAX_GROUP_SIZE) |
||||
|
||||
out.putNextEntry(createZipEntry("$archive/$group.dat")) |
||||
buf.readBytes(out, buf.readableBytes()) |
||||
} |
||||
|
||||
override fun remove(archive: Int) { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun remove(archive: Int, group: Int) { |
||||
throw UnsupportedOperationException() |
||||
} |
||||
|
||||
override fun flush() { |
||||
out.flush() |
||||
} |
||||
|
||||
override fun close() { |
||||
out.close() |
||||
} |
||||
} |
@ -0,0 +1,125 @@ |
||||
package org.openrs2.cache |
||||
|
||||
import com.google.common.jimfs.Configuration |
||||
import com.google.common.jimfs.Jimfs |
||||
import io.netty.buffer.Unpooled |
||||
import org.openrs2.buffer.copiedBuffer |
||||
import org.openrs2.buffer.use |
||||
import org.openrs2.util.io.recursiveEquals |
||||
import java.io.OutputStream |
||||
import java.nio.file.Files |
||||
import java.nio.file.Path |
||||
import java.util.zip.ZipOutputStream |
||||
import kotlin.test.Test |
||||
import kotlin.test.assertFailsWith |
||||
import kotlin.test.assertTrue |
||||
|
||||
public class FlatFileStoreZipWriterTest { |
||||
@Test |
||||
fun testBounds() { |
||||
FlatFileStoreZipWriter(ZipOutputStream(OutputStream.nullOutputStream())).use { store -> |
||||
// create |
||||
assertFailsWith<IllegalArgumentException> { |
||||
store.create(-1) |
||||
} |
||||
|
||||
store.create(0) |
||||
store.create(1) |
||||
store.create(254) |
||||
store.create(255) |
||||
|
||||
assertFailsWith<IllegalArgumentException> { |
||||
store.create(256) |
||||
} |
||||
|
||||
// write archive |
||||
assertFailsWith<IllegalArgumentException> { |
||||
store.write(-1, 0, Unpooled.EMPTY_BUFFER) |
||||
} |
||||
|
||||
store.write(0, 0, Unpooled.EMPTY_BUFFER) |
||||
store.write(1, 0, Unpooled.EMPTY_BUFFER) |
||||
store.write(254, 0, Unpooled.EMPTY_BUFFER) |
||||
store.write(255, 0, Unpooled.EMPTY_BUFFER) |
||||
|
||||
assertFailsWith<IllegalArgumentException> { |
||||
store.write(256, 0, Unpooled.EMPTY_BUFFER) |
||||
} |
||||
|
||||
// write group |
||||
assertFailsWith<IllegalArgumentException> { |
||||
store.write(0, -1, Unpooled.EMPTY_BUFFER) |
||||
} |
||||
|
||||
store.write(2, 0, Unpooled.EMPTY_BUFFER) |
||||
store.write(2, 1, Unpooled.EMPTY_BUFFER) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testUnsupported() { |
||||
FlatFileStoreZipWriter(ZipOutputStream(OutputStream.nullOutputStream())).use { store -> |
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.exists(0) |
||||
} |
||||
|
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.exists(0, 0) |
||||
} |
||||
|
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.list() |
||||
} |
||||
|
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.list(0) |
||||
} |
||||
|
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.read(0, 0) |
||||
} |
||||
|
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.remove(0) |
||||
} |
||||
|
||||
assertFailsWith<UnsupportedOperationException> { |
||||
store.remove(0, 0) |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testWrite() { |
||||
Jimfs.newFileSystem(Configuration.forCurrentPlatform()).use { fs -> |
||||
val actual = fs.rootDirectories.first().resolve("zip") |
||||
Files.createDirectories(actual) |
||||
|
||||
Files.newOutputStream(actual.resolve("cache.zip")).use { out -> |
||||
FlatFileStoreZipWriter(ZipOutputStream(out)).use { store -> |
||||
store.create(0) |
||||
|
||||
copiedBuffer("OpenRS2").use { buf -> |
||||
store.write(2, 0, buf) |
||||
} |
||||
|
||||
copiedBuffer("OpenRS2".repeat(100)).use { buf -> |
||||
store.write(2, 65535, buf) |
||||
} |
||||
|
||||
copiedBuffer("OpenRS2".repeat(100)).use { buf -> |
||||
store.write(2, 65536, buf) |
||||
} |
||||
} |
||||
} |
||||
|
||||
assertTrue(ROOT.recursiveEquals(actual)) |
||||
} |
||||
} |
||||
|
||||
private companion object { |
||||
private val ROOT = Path.of( |
||||
FlatFileStoreZipWriterTest::class.java.getResource("flat-file-store-zip").toURI() |
||||
) |
||||
} |
||||
} |
Binary file not shown.
Loading…
Reference in new issue