From 863337c789dd28997e59192641b8d60a1aaa3d5a Mon Sep 17 00:00:00 2001 From: tarsin Date: Mon, 23 May 2022 17:34:59 +0800 Subject: [PATCH] Support fskip for better decompress perf * Actually the whole impl can't be more sucks, will import algorithm to manage buffer and read strategy further --- .../gallery/ArchiveGalleryProvider.java | 2 +- .../java/com/hippo/UriArchiveAccessor.java | 20 +++++++++++++++++++ native/src/main/jni/archive.c | 12 +++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java index 252f807f9..5fd9bc3a8 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java @@ -194,7 +194,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 { continue; } - Pipe pipe = new Pipe(32 * 2048); + Pipe pipe = new Pipe(4096); synchronized (streams) { if (streams.get(index) != null) { diff --git a/native/src/main/java/com/hippo/UriArchiveAccessor.java b/native/src/main/java/com/hippo/UriArchiveAccessor.java index 22c47a3f5..1087a8392 100644 --- a/native/src/main/java/com/hippo/UriArchiveAccessor.java +++ b/native/src/main/java/com/hippo/UriArchiveAccessor.java @@ -72,6 +72,26 @@ public class UriArchiveAccessor implements Closeable { Os.lseek(fd, 0, OsConstants.SEEK_SET); } + public long skip(long n) throws IOException, ErrnoException { + long pos; + long len; + long newpos; + + if (n <= 0) { + return 0; + } + pos = Os.lseek(fd, 0L, OsConstants.SEEK_CUR); + len = length(); + newpos = pos + n; + if (newpos > len) { + newpos = len; + } + seek(newpos, OsConstants.SEEK_SET); + + /* return the actual number of bytes skipped */ + return newpos - pos; + } + public void close() throws IOException { pfd.close(); try { diff --git a/native/src/main/jni/archive.c b/native/src/main/jni/archive.c index 1e293eb38..e5d0a1b38 100644 --- a/native/src/main/jni/archive.c +++ b/native/src/main/jni/archive.c @@ -61,6 +61,7 @@ static void archive_list_all_entries(struct archive_inst_sc *inst) while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { if(filename_is_playable_file(archive_entry_pathname(entry))) count++; + archive_read_data_skip(a); } inst->entry_num = count; } @@ -90,17 +91,26 @@ la_int64_t ins_seek(struct archive *a, void *client_data, la_int64_t offset, int return ret; } +la_int64_t ins_skip(struct archive *a, void *client_data, la_int64_t request) +{ + archive_inst *arc = client_data; + jlong ret = (*arc->env)->CallLongMethod(arc->env, arc->file, arc->skipID, request); + return ret; +} + static archive_inst *archive_create_inst(JNIEnv *env, jobject file) { archive_inst *inst = malloc(sizeof(archive_inst)); inst->archive = archive_read_new(); archive_read_set_seek_callback(inst->archive, ins_seek); + archive_read_set_skip_callback(inst->archive, ins_skip); archive_read_support_format_all(inst->archive); archive_read_support_filter_all(inst->archive); inst->env = env; inst->file = file; inst->readID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, file), "read", "([B)I"); inst->seekID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, file), "seek", "(JI)J"); + inst->skipID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, file), "skip", "(J)J"); inst->jbr = (*env)->NewByteArray(env, BLOCK_SIZE); inst->read_buffer = malloc(BLOCK_SIZE); inst->output_buffer = malloc(BLOCK_SIZE); @@ -158,6 +168,8 @@ Java_com_hippo_UriArchiveAccessor_extracttoOutputStream(JNIEnv *env, jobject thi (*arc->env)->CallVoidMethod(env, os, flushID); } break; + } else { + archive_read_data_skip(arc->archive); } count++; }