Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions test-app/runtime/src/main/cpp/JEnv.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class JEnv {

jsize GetArrayLength(jarray array);

inline bool isSameObject(jobject obj1, jobject obj2) {
return m_env->IsSameObject(obj1, obj2) == JNI_TRUE;
}

jmethodID GetMethodID(jclass clazz, const std::string& name, const std::string& sig);
jmethodID GetStaticMethodID(jclass clazz, const std::string& name, const std::string& sig);
std::pair<jmethodID,jclass> GetInterfaceStaticMethodIDAndJClass(
Expand Down
32 changes: 27 additions & 5 deletions test-app/runtime/src/main/cpp/LRUCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include <cassert>
#include <list>
#include <unordered_map>
#include "robin_hood.h"

namespace tns {
// Class providing fixed-size (by number of records)
Expand All @@ -41,12 +41,12 @@ class LRUCache {
typedef std::list<key_type> key_tracker_type;

// Key to value and key history iterator
typedef std::unordered_map< key_type, std::pair<value_type, typename key_tracker_type::iterator> > key_to_value_type;
typedef robin_hood::unordered_map< key_type, std::pair<value_type, typename key_tracker_type::iterator> > key_to_value_type;

// Constuctor specifies the cached function and
// the maximum number of records to be stored
LRUCache(value_type (*loadCallback)(const key_type&, void*), void (*evictCallback)(const value_type&, void*), size_t capacity, void* state)
: m_loadCallback(loadCallback), m_capacity(capacity), m_evictCallback(evictCallback), m_state(state) {
LRUCache(value_type (*loadCallback)(const key_type&, void*), void (*evictCallback)(const value_type&, void*), bool (*cacheValidCallback)(const key_type&, const value_type&, void*), size_t capacity, void* state)
: m_loadCallback(loadCallback), m_capacity(capacity), m_evictCallback(evictCallback), m_cacheValidCallback(cacheValidCallback), m_state(state) {
assert(m_loadCallback != nullptr);
assert((0 < m_capacity) && (m_capacity < 10000));
}
Expand All @@ -57,6 +57,15 @@ class LRUCache {
// Attempt to find existing record
auto it = m_key_to_value.find(k);

if (m_cacheValidCallback != nullptr && it != m_key_to_value.end()) {
//check if cache is still valid
if (!m_cacheValidCallback(k, (*it).second.first, m_state)) {
//cache is not valid anymore, evict the key
evictKey(k);
it = m_key_to_value.end();
}
}

if (it == m_key_to_value.end()) {

// We don't have it:
Expand Down Expand Up @@ -98,6 +107,17 @@ class LRUCache {

private:

void evictKey(const key_type& key) {
auto it = m_key_to_value.find(key);
if (it != m_key_to_value.end()) {
if (m_evictCallback != nullptr) {
m_evictCallback((*it).second.first, m_state);
}
m_key_tracker.erase((*it).second.second);
m_key_to_value.erase(it);
}
}

// Record a fresh key-value pair in the cache
void insert(const key_type& k, const value_type& v) {
// Method is only called on cache misses
Expand All @@ -113,7 +133,7 @@ class LRUCache {

// Create the key-value entry,
// linked to the usage record.
m_key_to_value.insert(std::make_pair(k, std::make_pair(v, it)));
m_key_to_value.emplace(k, std::make_pair(v, it));
// No need to check return,
// given previous assert.
}
Expand Down Expand Up @@ -141,6 +161,8 @@ class LRUCache {

void (*m_evictCallback)(const value_type&, void*);

bool (*m_cacheValidCallback)(const key_type&, const value_type&, void*);

// Maximum number of key-value pairs to be retained
const size_t m_capacity;

Expand Down
9 changes: 6 additions & 3 deletions test-app/runtime/src/main/cpp/ObjectManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) :
m_javaRuntimeObject(javaRuntimeObject),
m_numberOfGC(0),
m_currentObjectId(0),
m_cache(NewWeakGlobalRefCallback, DeleteWeakGlobalRefCallback, 1000, this) {
m_cache(NewWeakGlobalRefCallback, DeleteWeakGlobalRefCallback, ValidateWeakGlobalRefCallback, 1000, this) {

JEnv env;
auto runtimeClass = env.FindClass("com/tns/Runtime");
Expand Down Expand Up @@ -507,12 +507,15 @@ jweak ObjectManager::NewWeakGlobalRefCallback(const int &javaObjectID, void *sta
}

void ObjectManager::DeleteWeakGlobalRefCallback(const jweak &object, void *state) {
auto objManager = reinterpret_cast<ObjectManager *>(state);

JEnv env;
env.DeleteWeakGlobalRef(object);
}

bool ObjectManager::ValidateWeakGlobalRefCallback(const int &javaObjectID, const jweak &object, void *state) {
JEnv env;
return !env.isSameObject(object, NULL);
}

Local<Object> ObjectManager::GetEmptyObject(Isolate *isolate) {
auto emptyObjCtorFunc = Local<Function>::New(isolate, *m_poJsWrapperFunc);
auto context = Runtime::GetRuntime(isolate)->GetContext();
Expand Down
2 changes: 2 additions & 0 deletions test-app/runtime/src/main/cpp/ObjectManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ class ObjectManager {

static void DeleteWeakGlobalRefCallback(const jweak& object, void* state);

static bool ValidateWeakGlobalRefCallback(const int &javaObjectID, const jweak &object, void *state);

static void JSWrapperConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info);

jobject m_javaRuntimeObject;
Expand Down
Loading