Commit 93adc112 authored by Chris Jewell's avatar Chris Jewell
Browse files

Added C++ std::map based HashTable module.

parent 95cea69e
......@@ -19,8 +19,9 @@ Depends:
tensorA,
assertthat
Imports:
methods,
Rcpp (>= 1.0.4),
gtools,
fastmap,
R6,
cluster,
stats,
......@@ -28,7 +29,9 @@ Imports:
SPIn,
grDevices,
reshape2
RoxygenNote: 6.0.1
LinkingTo: Rcpp
DynLib: sourceR
RoxygenNote: 7.1.0
KeepSource: TRUE
LazyData: TRUE
Suggests:
......
......@@ -24,3 +24,4 @@ importFrom(SPIn,SPIn)
importFrom(grDevices,col2rgb)
importFrom(grDevices,colorRampPalette)
importFrom(stats,median)
useDynLib(sourceR)
HashTable = function(keys=character(0), vals=numeric(0)) {
new("Rcpp_HashTable", keys, vals)
}
......@@ -7,4 +7,5 @@
#' The main sourceR method is \code{\link{HaldDP}}.
#' @docType package
#' @name sourceR
#' @useDynLib sourceR
NULL
Rcpp::loadModule("HashTable_module")
#include <Rcpp.h>
#include <iostream>
#include <string>
#include <map>
using namespace Rcpp;
//[[Rcpp::plugins(cpp11)]]
class HashTable {
public:
HashTable(SEXP key, SEXP val)
{
CharacterVector key_(key);
NumericVector val_(val);
insert(key_, val_);
}
void insert(CharacterVector key, NumericVector val)
{
if (key.size() != val.size())
throw Rcpp::exception("length(keys) must match length(val)");
CharacterVector::iterator k;
NumericVector::iterator v;
for(k=key.begin(), v=val.begin();
k!=key.end(); ++k, ++v) {
std::string key_str = std::string(*k);
ht_[key_str] = *v;
}
}
NumericVector find(CharacterVector keys) const
{
NumericVector rv;
for (auto k = keys.begin(); k != keys.end(); ++k)
{
auto val = ht_.find(std::string(*k));
if (val != ht_.end())
rv.push_back(val->second);
else
rv.push_back(NA_REAL);
}
return rv;
}
void erase(CharacterVector keys)
{
for (auto k = keys.begin(); k != keys.end(); ++k)
{
auto it = ht_.find(std::string(*k));
if (it != ht_.end())
ht_.erase(it);
else
throw Rcpp::exception("no such key in hashtable");
}
}
NumericVector values() const
{
NumericVector vals;
for (auto it = ht_.begin(); it!=ht_.end(); ++it)
vals.push_back(it->second);
return vals;
}
CharacterVector keys() const
{
CharacterVector keys;
for(auto it = ht_.begin(); it!=ht_.end(); ++it)
keys.push_back(it->first);
return keys;
}
void print() const
{
for(auto it = ht_.begin(); it!=ht_.end(); ++it)
Rcout << it->first << ": " << it->second << "\n";
Rcout << std::flush;
}
private:
typedef std::map<std::string, double> HashTable_t;
HashTable_t ht_;
};
/* hashtable is a lightweight wrapper around C++ std::map
* for creating a hash table of character => numeric pairs.
*/
RCPP_MODULE(HashTable_module)
{
class_<HashTable>("HashTable")
.constructor<SEXP, SEXP>()
.method("find", &HashTable::find)
.method("insert", &HashTable::insert)
.method("erase", &HashTable::erase)
.method("keys", &HashTable::keys)
.method("values", &HashTable::values)
.method("print", &HashTable::print)
;
}
// Generated by using Rcpp::compileAttributes() -> do not edit by hand
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
#include <Rcpp.h>
using namespace Rcpp;
RcppExport SEXP _rcpp_module_boot_HashTable_module();
static const R_CallMethodDef CallEntries[] = {
{"_rcpp_module_boot_HashTable_module", (DL_FUNC) &_rcpp_module_boot_HashTable_module, 0},
{NULL, NULL, 0}
};
RcppExport void R_init_sourceR(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
}
context("HashTable")
test_that("HashTable setup", {
keys = as.character(1:4)
vals = 1:4/10
ht = HashTable(keys, vals)
expect_equal(ht$keys(), keys)
expect_equal(ht$values(), vals)
})
test_that("HashTable insert", {
keys = as.character(1:4)
vals = 1:4/10
ht = HashTable(keys, vals)
ht$insert("5", 0.5)
expect_equal(ht$keys(), c(keys, "5"))
expect_equal(ht$values(), c(vals, 0.5))
})
test_that("HashTable erase", {
keys = as.character(1:4)
vals = 1:4/10
ht = HashTable(keys, vals)
ht$erase("1")
expect_equal(ht$keys(), keys[-1])
expect_equal(ht$values(), vals[-1])
})
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment