mirror of
https://github.com/vale981/ray
synced 2025-03-08 19:41:38 -05:00
Convert eviction code to STL (#534)
* temp commit * convert eviction policy to C++ * temp commit * fix plasma tests * fix * linting * fixes * fix linting
This commit is contained in:
parent
b4788ae518
commit
3a0e86395e
2 changed files with 72 additions and 129 deletions
|
@ -1,109 +1,64 @@
|
||||||
#include "eviction_policy.h"
|
#include "eviction_policy.h"
|
||||||
|
|
||||||
#include "utlist.h"
|
#include <list>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
/** An element representing a released object in a doubly-linked list. This is
|
class LRUCache {
|
||||||
* used to implement an LRU cache. */
|
private:
|
||||||
typedef struct ReleasedObject {
|
/** A doubly-linked list containing the items in the cache and
|
||||||
/** The object_id of the released object. */
|
* their sizes in LRU order. */
|
||||||
ObjectID object_id;
|
typedef std::list<std::pair<ObjectID, int64_t>> ItemList;
|
||||||
/** Needed for the doubly-linked list macros. */
|
ItemList item_list_;
|
||||||
struct ReleasedObject *prev;
|
/** A hash table mapping the object ID of an object in the cache to its
|
||||||
/** Needed for the doubly-linked list macros. */
|
* location in the doubly linked list item_list_. */
|
||||||
struct ReleasedObject *next;
|
std::unordered_map<ObjectID, ItemList::iterator, UniqueIDHasher> item_map_;
|
||||||
} ReleasedObject;
|
|
||||||
|
|
||||||
/** This type is used to define a hash table mapping the object ID of a released
|
public:
|
||||||
* object to its location in the doubly-linked list of released objects. */
|
LRUCache(){};
|
||||||
typedef struct {
|
|
||||||
/** Object ID of this object. */
|
void add(const ObjectID &key, int64_t size) {
|
||||||
ObjectID object_id;
|
auto it = item_map_.find(key);
|
||||||
/** A pointer to the corresponding entry for this object in the doubly-linked
|
CHECK(it == item_map_.end());
|
||||||
* list of released objects. */
|
item_list_.push_front(std::make_pair(key, size));
|
||||||
ReleasedObject *released_object;
|
item_map_.insert(std::make_pair(key, item_list_.begin()));
|
||||||
/** Handle for the uthash table. */
|
}
|
||||||
UT_hash_handle handle;
|
|
||||||
} released_object_entry;
|
void remove(const ObjectID &key) {
|
||||||
|
auto it = item_map_.find(key);
|
||||||
|
CHECK(it != item_map_.end());
|
||||||
|
item_list_.erase(it->second);
|
||||||
|
item_map_.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t choose_objects_to_evict(int64_t num_bytes_required,
|
||||||
|
std::vector<ObjectID> &objects_to_evict) {
|
||||||
|
int64_t bytes_evicted = 0;
|
||||||
|
auto it = item_list_.end();
|
||||||
|
while (bytes_evicted < num_bytes_required && it != item_list_.begin()) {
|
||||||
|
it--;
|
||||||
|
objects_to_evict.push_back(it->first);
|
||||||
|
bytes_evicted += it->second;
|
||||||
|
}
|
||||||
|
return bytes_evicted;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** The part of the Plasma state that is maintained by the eviction policy. */
|
/** The part of the Plasma state that is maintained by the eviction policy. */
|
||||||
struct EvictionState {
|
struct EvictionState {
|
||||||
/** The amount of memory (in bytes) currently being used. */
|
/** The amount of memory (in bytes) currently being used. */
|
||||||
int64_t memory_used;
|
int64_t memory_used;
|
||||||
/** A doubly-linked list of the released objects in order from least recently
|
/** Datastructure for the LRU cache. */
|
||||||
* released to most recently released. */
|
LRUCache cache;
|
||||||
ReleasedObject *released_objects;
|
|
||||||
/** A hash table mapping the object ID of a released object to its location in
|
|
||||||
* the doubly linked list of released objects. */
|
|
||||||
released_object_entry *released_object_table;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is used to define the array of object IDs used to define the
|
EvictionState *EvictionState_init() {
|
||||||
* released_objects type. */
|
EvictionState *s = new EvictionState();
|
||||||
UT_icd released_objects_entry_icd = {sizeof(ObjectID), NULL, NULL, NULL};
|
s->memory_used = 0;
|
||||||
|
return s;
|
||||||
EvictionState *EvictionState_init(void) {
|
|
||||||
EvictionState *state = (EvictionState *) malloc(sizeof(EvictionState));
|
|
||||||
state->memory_used = 0;
|
|
||||||
state->released_objects = NULL;
|
|
||||||
state->released_object_table = NULL;
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvictionState_free(EvictionState *s) {
|
void EvictionState_free(EvictionState *s) {
|
||||||
/* Delete each element in the doubly-linked list. */
|
delete s;
|
||||||
ReleasedObject *element, *temp;
|
|
||||||
DL_FOREACH_SAFE(s->released_objects, element, temp) {
|
|
||||||
DL_DELETE(s->released_objects, element);
|
|
||||||
free(element);
|
|
||||||
}
|
|
||||||
/* Delete each element in the hash table. */
|
|
||||||
released_object_entry *current_entry, *temp_entry;
|
|
||||||
HASH_ITER(handle, s->released_object_table, current_entry, temp_entry) {
|
|
||||||
HASH_DELETE(handle, s->released_object_table, current_entry);
|
|
||||||
free(current_entry);
|
|
||||||
}
|
|
||||||
/* Free the eviction state. */
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_object_to_lru_cache(EvictionState *eviction_state,
|
|
||||||
ObjectID object_id) {
|
|
||||||
/* Add the object ID to the doubly-linked list. */
|
|
||||||
ReleasedObject *linked_list_entry =
|
|
||||||
(ReleasedObject *) malloc(sizeof(ReleasedObject));
|
|
||||||
linked_list_entry->object_id = object_id;
|
|
||||||
DL_APPEND(eviction_state->released_objects, linked_list_entry);
|
|
||||||
/* Check that the object ID is not already in the hash table. */
|
|
||||||
released_object_entry *hash_table_entry;
|
|
||||||
HASH_FIND(handle, eviction_state->released_object_table, &object_id,
|
|
||||||
sizeof(object_id), hash_table_entry);
|
|
||||||
CHECK(hash_table_entry == NULL);
|
|
||||||
/* Add the object ID to the hash table. */
|
|
||||||
hash_table_entry =
|
|
||||||
(released_object_entry *) malloc(sizeof(released_object_entry));
|
|
||||||
hash_table_entry->object_id = object_id;
|
|
||||||
hash_table_entry->released_object = linked_list_entry;
|
|
||||||
HASH_ADD(handle, eviction_state->released_object_table, object_id,
|
|
||||||
sizeof(object_id), hash_table_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_object_from_lru_cache(EvictionState *eviction_state,
|
|
||||||
ObjectID object_id) {
|
|
||||||
/* Check that the object ID is in the hash table. */
|
|
||||||
released_object_entry *hash_table_entry;
|
|
||||||
HASH_FIND(handle, eviction_state->released_object_table, &object_id,
|
|
||||||
sizeof(object_id), hash_table_entry);
|
|
||||||
/* Only remove the object ID if it is in the LRU cache. */
|
|
||||||
CHECK(hash_table_entry != NULL);
|
|
||||||
/* Remove the object ID from the doubly-linked list. */
|
|
||||||
DL_DELETE(eviction_state->released_objects,
|
|
||||||
hash_table_entry->released_object);
|
|
||||||
/* Free the entry from the doubly-linked list. */
|
|
||||||
free(hash_table_entry->released_object);
|
|
||||||
/* Remove the object ID from the hash table. */
|
|
||||||
HASH_DELETE(handle, eviction_state->released_object_table, hash_table_entry);
|
|
||||||
/* Free the entry from the hash table. */
|
|
||||||
free(hash_table_entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t EvictionState_choose_objects_to_evict(
|
int64_t EvictionState_choose_objects_to_evict(
|
||||||
|
@ -112,47 +67,33 @@ int64_t EvictionState_choose_objects_to_evict(
|
||||||
int64_t num_bytes_required,
|
int64_t num_bytes_required,
|
||||||
int64_t *num_objects_to_evict,
|
int64_t *num_objects_to_evict,
|
||||||
ObjectID **objects_to_evict) {
|
ObjectID **objects_to_evict) {
|
||||||
int64_t num_objects = 0;
|
std::vector<ObjectID> objs_to_evict;
|
||||||
int64_t num_bytes = 0;
|
int64_t bytes_evicted = eviction_state->cache.choose_objects_to_evict(
|
||||||
/* Figure out how many objects need to be evicted in order to recover a
|
num_bytes_required, objs_to_evict);
|
||||||
* sufficient number of bytes. */
|
/* Update the LRU cache. */
|
||||||
ReleasedObject *element, *temp;
|
for (auto &object_id : objs_to_evict) {
|
||||||
DL_FOREACH_SAFE(eviction_state->released_objects, element, temp) {
|
eviction_state->cache.remove(object_id);
|
||||||
if (num_bytes >= num_bytes_required) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Find the object table entry for this object. */
|
|
||||||
ObjectTableEntry *entry = plasma_store_info->objects[element->object_id];
|
|
||||||
/* Update the cumulative bytes and the number of objects so far. */
|
|
||||||
num_bytes += (entry->info.data_size + entry->info.metadata_size);
|
|
||||||
num_objects += 1;
|
|
||||||
}
|
}
|
||||||
/* Construct the return values. */
|
/* Construct the return values. */
|
||||||
*num_objects_to_evict = num_objects;
|
*num_objects_to_evict = objs_to_evict.size();
|
||||||
if (num_objects == 0) {
|
if (objs_to_evict.size() == 0) {
|
||||||
*objects_to_evict = NULL;
|
*objects_to_evict = NULL;
|
||||||
} else {
|
} else {
|
||||||
*objects_to_evict = (ObjectID *) malloc(num_objects * sizeof(ObjectID));
|
int64_t result_size = objs_to_evict.size() * sizeof(ObjectID);
|
||||||
int counter = 0;
|
*objects_to_evict = (ObjectID *) malloc(result_size);
|
||||||
DL_FOREACH_SAFE(eviction_state->released_objects, element, temp) {
|
memcpy(*objects_to_evict, objs_to_evict.data(), result_size);
|
||||||
if (counter == num_objects) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
(*objects_to_evict)[counter] = element->object_id;
|
|
||||||
/* Update the LRU cache. */
|
|
||||||
remove_object_from_lru_cache(eviction_state, element->object_id);
|
|
||||||
counter += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Update the number used. */
|
/* Update the number of bytes used. */
|
||||||
eviction_state->memory_used -= num_bytes;
|
eviction_state->memory_used -= bytes_evicted;
|
||||||
return num_bytes;
|
return bytes_evicted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvictionState_object_created(EvictionState *eviction_state,
|
void EvictionState_object_created(EvictionState *eviction_state,
|
||||||
PlasmaStoreInfo *plasma_store_info,
|
PlasmaStoreInfo *plasma_store_info,
|
||||||
ObjectID obj_id) {
|
ObjectID object_id) {
|
||||||
add_object_to_lru_cache(eviction_state, obj_id);
|
ObjectTableEntry *entry = plasma_store_info->objects[object_id];
|
||||||
|
eviction_state->cache.add(object_id,
|
||||||
|
entry->info.data_size + entry->info.metadata_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EvictionState_require_space(EvictionState *eviction_state,
|
bool EvictionState_require_space(EvictionState *eviction_state,
|
||||||
|
@ -192,22 +133,24 @@ bool EvictionState_require_space(EvictionState *eviction_state,
|
||||||
|
|
||||||
void EvictionState_begin_object_access(EvictionState *eviction_state,
|
void EvictionState_begin_object_access(EvictionState *eviction_state,
|
||||||
PlasmaStoreInfo *plasma_store_info,
|
PlasmaStoreInfo *plasma_store_info,
|
||||||
ObjectID obj_id,
|
ObjectID object_id,
|
||||||
int64_t *num_objects_to_evict,
|
int64_t *num_objects_to_evict,
|
||||||
ObjectID **objects_to_evict) {
|
ObjectID **objects_to_evict) {
|
||||||
/* If the object is in the LRU cache, remove it. */
|
/* If the object is in the LRU cache, remove it. */
|
||||||
remove_object_from_lru_cache(eviction_state, obj_id);
|
eviction_state->cache.remove(object_id);
|
||||||
*num_objects_to_evict = 0;
|
*num_objects_to_evict = 0;
|
||||||
*objects_to_evict = NULL;
|
*objects_to_evict = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvictionState_end_object_access(EvictionState *eviction_state,
|
void EvictionState_end_object_access(EvictionState *eviction_state,
|
||||||
PlasmaStoreInfo *plasma_store_info,
|
PlasmaStoreInfo *plasma_store_info,
|
||||||
ObjectID obj_id,
|
ObjectID object_id,
|
||||||
int64_t *num_objects_to_evict,
|
int64_t *num_objects_to_evict,
|
||||||
ObjectID **objects_to_evict) {
|
ObjectID **objects_to_evict) {
|
||||||
|
ObjectTableEntry *entry = plasma_store_info->objects[object_id];
|
||||||
/* Add the object to the LRU cache.*/
|
/* Add the object to the LRU cache.*/
|
||||||
add_object_to_lru_cache(eviction_state, obj_id);
|
eviction_state->cache.add(object_id,
|
||||||
|
entry->info.data_size + entry->info.metadata_size);
|
||||||
*num_objects_to_evict = 0;
|
*num_objects_to_evict = 0;
|
||||||
*objects_to_evict = NULL;
|
*objects_to_evict = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ killall plasma_store
|
||||||
redis_pid=$!
|
redis_pid=$!
|
||||||
sleep 1
|
sleep 1
|
||||||
# flush the redis server
|
# flush the redis server
|
||||||
../common/thirdparty/redis/src/redis-cli flushall &
|
./src/common/thirdparty/redis/src/redis-cli flushall &
|
||||||
sleep 1
|
sleep 1
|
||||||
./src/plasma/plasma_store -s /tmp/store1 -m 1000000000 &
|
./src/plasma/plasma_store -s /tmp/store1 -m 1000000000 &
|
||||||
plasma1_pid=$!
|
plasma1_pid=$!
|
||||||
|
|
Loading…
Add table
Reference in a new issue