#include "symboltable.hpp"
#include "builtin/string.hpp"
#include "builtin/symbol.hpp"

namespace rubinius {
size_t SymbolTable::add(std::string str) {
strings.push_back(str);
return strings.size() - 1;
}

SYMBOL SymbolTable::lookup(STATE, std::string str) {
size_t sym;

hashval hash = String::hash_str((unsigned char*)str.c_str(), str.size());

symbol_map::iterator entry = symbols.find(hash);
if(entry == symbols.end()) {
sym = add(str);
symbol_ids v(1, sym);
symbols[hash] = v;
} else {
symbol_ids v = entry->second;
for(symbol_ids::iterator i = v.begin(); i != v.end(); i++) {
if(strings[*i] == str) return Symbol::from_index(state, *i);
}
sym = add(str);
v.push_back(sym);
}

return Symbol::from_index(state, sym);
}

SYMBOL SymbolTable::lookup(STATE, const char* str) {
return lookup(state, std::string(str));
}

SYMBOL SymbolTable::lookup(STATE, String* str) {
return lookup(state, str->byte_address());
}

String* SymbolTable::symbol_to_string(STATE, Symbol* sym) {
std::string str = strings[sym->index()];
return String::create(state, str.c_str(), str.size());
}

size_t SymbolTable::size() {
return strings.size();
}
}