Skip to content
This repository was archived by the owner on Sep 17, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,403 changes: 805 additions & 598 deletions arklib/Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion arklib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ name = "arklib"
crate-type = ["cdylib", "staticlib"]

[dependencies]
arklib = { git = "https://github.com/ARK-builders/arklib", rev = "1b3a4519d17a35960bfde2d9ed25cb96f9f0" }
arklib = { git = "https://github.com/ARK-builders/arklib", rev = "0d25eb0" }
anyhow = "1.0.58"
env_logger = "0.9.0"
canonical-path = "2.0.2"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mberry That's what we want to get rid of and keep the bindings thin.

url = { version = "2.2.2", features = ["serde"] }
openssl = { version = "0.10.42", features = ["vendored"] }
image = "0.24.2"
Expand Down
159 changes: 106 additions & 53 deletions arklib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ pub mod android {
use arklib::pdf::PDFQuality;

use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use std::{fs::File, path::Path};

use anyhow::Error;

use image::EncodableLayout;
use log::{debug, trace, Level};
use url::Url;
Expand All @@ -23,6 +23,8 @@ pub mod android {
use jni::JNIEnv;
extern crate android_logger;
use android_logger::Config;

pub type Result<T> = std::result::Result<T, arklib::ArklibError>;

#[no_mangle]
pub extern "C" fn Java_dev_arkbuilders_arklib_LibKt_initRustLogger(_: JNIEnv, _: JClass) {
Expand All @@ -48,31 +50,8 @@ pub mod android {

let resourceId = ResourceId::compute(data_size.try_into().unwrap(), file_path).unwrap();

let resource_id_cls = env.find_class("dev/arkbuilders/arklib/ResourceId").unwrap();

let create_resource_id_fn = env
.get_static_method_id(
resource_id_cls,
"create",
"(JJ)Ldev/arkbuilders/arklib/ResourceId;",
)
.unwrap();

let data_size: jlong = resourceId.data_size as usize as i64;
let crc32: jlong = resourceId.crc32 as usize as i64;

trace!("after uszie");
let resource_id = env
.call_static_method_unchecked(
resource_id_cls,
create_resource_id_fn,
JavaType::Object(String::from("dev/arkbuilders/arklib/ResourceId")),
&[JValue::from(data_size), JValue::from(crc32)],
)
.unwrap()
.l()
.unwrap();
resource_id.into_inner()
let resource_id = id_to_jni_id(env, &resourceId);
resource_id.l().unwrap().into_inner()
}

#[no_mangle]
Expand Down Expand Up @@ -421,7 +400,7 @@ pub mod android {
}

#[no_mangle]
pub extern "C" fn Java_dev_arkbuilders_arklib_binding_BindingIndex_updateNative(
pub extern "C" fn Java_dev_arkbuilders_arklib_binding_BindingIndex_updateAllNative(
env: JNIEnv,
_: JClass,
jni_root: JString,
Expand All @@ -436,45 +415,106 @@ pub mod android {
}
};

let jni_deleted_list = env.new_object("java/util/ArrayList", "()V", &[]).unwrap();
let jni_deleted_set = env.new_object("java/util/HashSet", "()V", &[]).unwrap();
let jni_added_map = env.new_object("java/util/HashMap", "()V", &[]).unwrap();

for id in &result.deleted {
let id = env.new_string(id.to_string()).unwrap().into();
let jni_id = id_to_jni_id(env, id);

env.call_method(jni_deleted_list, "add", "(Ljava/lang/Object;)Z", &[id])
env.call_method(jni_deleted_set, "add", "(Ljava/lang/Object;)Z", &[jni_id])
.unwrap();
}

for (path, id) in &result.added {
let id = env.new_string(id.to_string()).unwrap().into();
let path = env.new_string(path.to_str().unwrap()).unwrap().into();
let jni_id = id_to_jni_id(env, id);
let jni_path = env.new_string(path.to_str().unwrap()).unwrap().into();

env.call_method(
jni_added_map,
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
&[id, path],
&[jni_id, jni_path],
)
.unwrap();
}

let jni_params_list = env.new_object("java/util/ArrayList", "()V", &[]).unwrap();
env.call_method(
jni_params_list,
"add",
"(Ljava/lang/Object;)Z",
&[jni_deleted_list.into()],
)
.unwrap();
env.call_method(
jni_params_list,
"add",
"(Ljava/lang/Object;)Z",
&[jni_added_map.into()],
)
.unwrap();
let jni_raw_updates = env
.new_object(
"dev/arkbuilders/arklib/binding/RawUpdates",
"(Ljava/util/HashSet;Ljava/util/HashMap;)V",
&[jni_deleted_set.into(), jni_added_map.into()],
)
.unwrap();

jni_params_list.into_inner()
jni_raw_updates.into_inner()
}

#[no_mangle]
pub extern "C" fn Java_dev_arkbuilders_arklib_binding_BindingIndex_updateOneNative(
env: JNIEnv,
_: JClass,
jni_root: JString,
jni_path: JString,
jni_old_id: JString,
) -> jobject {
let path: String = env
.get_string(jni_path)
.expect("Failed to parse path")
.into();

let path: &Path = Path::new(&path);

let old_id_str: String = env
.get_string(jni_old_id)
.expect("Failed to parse old id")
.into();

let old_id = ResourceId::from_str(&old_id_str).unwrap();

let result = match provide_index(env, jni_root) {
Ok(rwlock) => {
let mut index = rwlock.write().unwrap();
index
.update_one(&path, old_id)
.unwrap()
}
Err(err) => {
panic!("couldn't provide index {}", err)
}
};

let jni_deleted_set = env.new_object("java/util/HashSet", "()V", &[]).unwrap();
let jni_added_map = env.new_object("java/util/HashMap", "()V", &[]).unwrap();

for id in &result.deleted {
let jni_id = id_to_jni_id(env, id);

env.call_method(jni_deleted_set, "add", "(Ljava/lang/Object;)Z", &[jni_id])
.unwrap();
}

for (path, id) in &result.added {
let jni_id = id_to_jni_id(env, id);
let jni_path = env.new_string(path.to_str().unwrap()).unwrap().into();

env.call_method(
jni_added_map,
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
&[jni_id, jni_path],
)
.unwrap();
}

let jni_raw_updates = env
.new_object(
"dev/arkbuilders/arklib/binding/RawUpdates",
"(Ljava/util/HashSet;Ljava/util/HashMap;)V",
&[jni_deleted_set.into(), jni_added_map.into()],
)
.unwrap();

jni_raw_updates.into_inner()
}

#[no_mangle]
Expand All @@ -500,20 +540,33 @@ pub mod android {
let jni_map = env.new_object("java/util/HashMap", "()V", &[]).unwrap();

for (id, path) in &index.id2path {
let id = env.new_string(id.to_string()).unwrap().into();
let path = env.new_string(path.to_str().unwrap()).unwrap().into();
let jni_id = id_to_jni_id(env, id);
let jni_path = env.new_string(path.to_str().unwrap()).unwrap().into();
env.call_method(
jni_map,
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
&[id, path],
&[jni_id, jni_path],
)
.unwrap();
}

jni_map.into_inner()
}

fn id_to_jni_id<'a>(env: JNIEnv<'a>, id: &'a ResourceId) -> JValue<'a> {
let data_size: jlong = id.data_size as usize as i64;
let crc32: jlong = id.crc32 as usize as i64;

env.new_object(
"dev/arkbuilders/arklib/ResourceId",
"(JJ)V",
&[JValue::from(data_size), JValue::from(crc32)],
)
.unwrap()
.into()
}

#[no_mangle]
pub extern "C" fn Java_dev_arkbuilders_arklib_ArkFiles_provideNativeArkFiles(
env: JNIEnv,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/main/java/dev/arkbuilders/arklib/Lib.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ data class ResourceId(

fun fromString(str: String): ResourceId {
val parts = str.split(KEY_VALUE_SEPARATOR)
return ResourceId(
return ResourceId(
parts[0].toLong(),
parts[1].toLong()
)
Expand Down
32 changes: 16 additions & 16 deletions lib/src/main/java/dev/arkbuilders/arklib/binding/BindingIndex.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@ import java.nio.file.Path
import kotlin.io.path.Path

class RawUpdates(
val deleted: Set<ResourceId>,
val added: Map<ResourceId, Path>
val deleted: HashSet<ResourceId>,
val added: HashMap<ResourceId, String>,
)

object BindingIndex {
private external fun loadNative(root: String): Boolean
fun load(root: Path): Boolean = loadNative(root.toString())

private external fun updateNative(root: String): List<Any>
fun update(root: Path): RawUpdates {
val list = updateNative(root.toString())
val deleted = (list[0] as List<String>).map {
ResourceId.fromString(it)
}.toSet()
val added = (list[1] as HashMap<String, String>).map { (id, path) ->
ResourceId.fromString(id) to Path(path)
}.toMap()
return RawUpdates(deleted, added)
}
private external fun updateAllNative(root: String): RawUpdates
fun updateAll(root: Path) = updateAllNative(root.toString())

private external fun updateOneNative(
root: String,
path: String,
oldId: String
): RawUpdates

fun updateOne(root: Path, path: Path, oldId: ResourceId) =
updateOneNative(root.toString(), path.toString(), oldId.toString())

private external fun storeNative(root: String)
fun store(root: Path) = storeNative(root.toString())

private external fun id2pathNative(root: String): HashMap<String, String>
private external fun id2pathNative(root: String): HashMap<ResourceId, String>
fun id2path(root: Path): Map<ResourceId, Path> =
id2pathNative(root.toString()).map { (idStr, pathStr) ->
ResourceId.fromString(idStr) to Path(pathStr)
id2pathNative(root.toString()).map { (id, pathStr) ->
id to Path(pathStr)
}.toMap()
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,16 @@ class IndexAggregation(
override suspend fun updateAll() {
shards.forEach { it.updateAll() }
}

override suspend fun updateOne(
resourcePath: Path,
oldId: ResourceId
): ResourceUpdates {
return shards.find { resourcePath.startsWith(it.path) }
?.updateOne(resourcePath, oldId)
?: error(
"At least one shard must contain the passed path" +
"shards: ${shards.map { it.path }} path: $resourcePath"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class IndexProjection(

override suspend fun updateAll() = root.updateAll()

override suspend fun updateOne(resourcePath: Path, oldId: ResourceId) =
root.updateOne(resourcePath, oldId)

override fun allResources(): Map<ResourceId, Resource> {
val allPathsMap = root.allPaths()
return root
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ interface ResourceIndex {

suspend fun updateAll()

suspend fun updateOne(resourcePath: Path, oldId: ResourceId): ResourceUpdates

suspend fun updateOne(oldId: ResourceId): ResourceUpdates = updateOne(
allPaths()[oldId]!!,
oldId
)

fun allResources(): Map<ResourceId, Resource>

fun getResource(id: ResourceId): Resource?
Expand Down
Loading