|
|
- #ifndef NEURALTABLE_H
- #define NEURALTABLE_H
-
- #include "erl_nif.h"
- #include "neural_utils.h"
- #include <string>
- #include <stdio.h>
- #include <string.h>
- #include <unordered_map>
- #include <queue>
- #include <atomic>
- #ifdef _WIN32
- #include <windows.h>
- #include <io.h>
- #include <process.h>
- #else
- #include <unistd.h>
- #endif
-
- #define BUCKET_COUNT 64
- #define BUCKET_MASK (BUCKET_COUNT - 1)
- #define GET_BUCKET(key) key & BUCKET_MASK
- #define GET_LOCK(key) key & BUCKET_MASK
- #define RECLAIM_THRESHOLD 1048576
-
- using namespace std;
-
- class NeuralTable;
-
- typedef unordered_map<string, NeuralTable*> table_set;
- typedef unordered_map<unsigned long int, ERL_NIF_TERM> hash_table;
- typedef void (NeuralTable::*BatchFunction)(ErlNifPid pid);
-
- class NeuralTable {
- public:
- static ERL_NIF_TERM MakeTable(ErlNifEnv *env, ERL_NIF_TERM name, ERL_NIF_TERM keypos);
- static ERL_NIF_TERM Insert(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key, ERL_NIF_TERM object);
- static ERL_NIF_TERM InsertNew(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key, ERL_NIF_TERM object);
- static ERL_NIF_TERM Delete(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key);
- static ERL_NIF_TERM Empty(ErlNifEnv *env, ERL_NIF_TERM table);
- static ERL_NIF_TERM Get(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key);
- static ERL_NIF_TERM Increment(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key, ERL_NIF_TERM ops);
- static ERL_NIF_TERM Shift(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key, ERL_NIF_TERM ops);
- static ERL_NIF_TERM Unshift(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key, ERL_NIF_TERM ops);
- static ERL_NIF_TERM Swap(ErlNifEnv *env, ERL_NIF_TERM table, ERL_NIF_TERM key, ERL_NIF_TERM ops);
- static ERL_NIF_TERM Dump(ErlNifEnv *env, ERL_NIF_TERM table);
- static ERL_NIF_TERM Drain(ErlNifEnv *env, ERL_NIF_TERM table);
- static ERL_NIF_TERM GetKeyPosition(ErlNifEnv *env, ERL_NIF_TERM table);
- static ERL_NIF_TERM GarbageCollect(ErlNifEnv *env, ERL_NIF_TERM table);
- static ERL_NIF_TERM GarbageSize(ErlNifEnv *env, ERL_NIF_TERM table);
- static NeuralTable* GetTable(ErlNifEnv *env, ERL_NIF_TERM name);
- static void* DoGarbageCollection(void *table);
- static void* DoBatchOperations(void *table);
- static void* DoReclamation(void *table);
- static void Initialize() {
- table_mutex = enif_mutex_create("neural_table_maker");
- }
- static void Shutdown() {
- running = false;
- table_set::iterator it(tables.begin());
-
- while (it != tables.end()) {
- delete it->second;
- tables.erase(it);
- it = tables.begin();
- }
-
- enif_mutex_destroy(table_mutex);
- }
-
- void rlock(unsigned long int key) { enif_rwlock_rlock(locks[GET_LOCK(key)]); }
- void runlock(unsigned long int key) { enif_rwlock_runlock(locks[GET_LOCK(key)]); }
- void rwlock(unsigned long int key) { enif_rwlock_rwlock(locks[GET_LOCK(key)]); }
- void rwunlock(unsigned long int key) { enif_rwlock_rwunlock(locks[GET_LOCK(key)]); }
-
- ErlNifEnv *get_env(unsigned long int key);
- bool erase(unsigned long int key, ERL_NIF_TERM &ret);
- bool find(unsigned long int key, ERL_NIF_TERM &ret);
- void put(unsigned long int key, ERL_NIF_TERM tuple);
- void batch_dump(ErlNifPid pid);
- void batch_drain(ErlNifPid pid);
- void start_gc();
- void stop_gc();
- void start_batch();
- void stop_batch();
- void gc();
- void reclaim(unsigned long int key, ERL_NIF_TERM reclaim);
- unsigned long int garbage_size();
- void add_batch_job(ErlNifPid pid, BatchFunction fun);
-
- protected:
- static table_set tables;
- static atomic<bool> running;
- static ErlNifMutex *table_mutex;
-
- struct BatchJob {
- ErlNifPid pid;
- BatchFunction fun;
- };
-
- NeuralTable(unsigned int kp);
- ~NeuralTable();
-
- unsigned int garbage_cans[BUCKET_COUNT];
- hash_table hash_buckets[BUCKET_COUNT];
- ErlNifEnv *env_buckets[BUCKET_COUNT];
- ERL_NIF_TERM reclaimable[BUCKET_COUNT];
- ErlNifRWLock *locks[BUCKET_COUNT];
- ErlNifCond *gc_cond;
- ErlNifMutex *gc_mutex;
- ErlNifTid gc_tid;
- ErlNifTid rc_tid;
- ErlNifCond *batch_cond;
- ErlNifMutex *batch_mutex;
- queue<BatchJob> batch_jobs;
- ErlNifTid batch_tid;
-
- unsigned int key_pos;
- };
-
- #endif
|