ext/template/google_hash.cpp.erb in google_hash-0.2.1 vs ext/template/google_hash.cpp.erb in google_hash-0.3.0
- old
+ new
@@ -13,24 +13,40 @@
using __gnu_cxx::hash; // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS
extern "C" {
// some helpers
+<%
+ # not yet used...
+ if false
+%>
struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
}
};
-static hash<const char*> H;
+struct eqint
+{
+ inline bool operator()(int s1, int s2) const
+ {
+ return s1 == s2;
+ }
+};
-// hashing it is like hash<const char*>
+<% end %>
+
static ID id_eql, id_hash;
+<% if key_type == 'VALUE' %>
+static hash<const char*> H;
+
+// hashing it is like hash<const char*>
+
struct eqrb
{
bool operator()(const VALUE s1, const VALUE s2) const
{
// speeds up populate int 18/11
@@ -45,10 +61,14 @@
return RTEST(rb_funcall(s1, id_eql, 1, s2));
}
};
+#ifndef RBIGNUM_DIGITS
+# define RBIGNUM_DIGITS(a) RBIGNUM(a)->digits
+#endif
+
struct hashrb
{
size_t operator()(VALUE hash_me) const
{
// stolen from hash.c populate -> 0.64 0.625
@@ -66,18 +86,17 @@
case T_FIXNUM:
case T_FLOAT:
case T_SYMBOL:
// ltodo
return hash_me;
- <% unless RUBY_VERSION < '1.9' %>
case T_BIGNUM:
- return LONG2FIX(((long*)(RBIGNUM_DIGITS(hash_me)))[0]); // its first digit...I'm thinkin'
- <% end %>
- case T_STRING:
+ return LONG2FIX(((long*)(RBIGNUM_DIGITS(hash_me)))[0]); // its first digit...I'm thinkin'
+ // not sure if this is faster or not...
+ //case T_STRING:
//return H(StringValueCStr(hash_me)); // populate/lookup 0.26 -> 0.23 [core is 0.16 somehow]
// perhaps they cache?
- return H(RSTRING_PTR(hash_me)); // 0.23 -> -.22
+ //return H(RSTRING_PTR(hash_me)); // 0.23 -> -.22
}
VALUE hval = rb_funcall(hash_me, id_hash, 0);
retry:
@@ -95,20 +114,13 @@
}
}
};
+<% end %>
-
/* we end up not needing this...or at least not using it, I don't know if it would be faster than using the default or not
-struct eqint
-{
- inline bool operator()(int s1, int s2) const
- {
- return s1 == s2;
- }
-};
*/
typedef struct {
<%= type %>_hash_map< <%= key_type %>, <%= value_type %> <%= extra_hash_params %> > *hash_map;
@@ -166,22 +178,30 @@
static VALUE rb_ghash_set(VALUE cb, VALUE set_this, VALUE to_this) {
<% if assert_key_type %>
if(!(TYPE(set_this) == <%= assert_key_type %>)) {
- rb_raise(rb_eTypeError, "not valid value #{assert_key_type}");
+ rb_raise(rb_eTypeError, "not valid key #{assert_key_type}");
}
<% end %>
+
+ <% if assert_value_type %>
+ if(!(TYPE(to_this) == <%= assert_value_type %>)) {
+ rb_raise(rb_eTypeError, "not valid value #{assert_value_type}");
+ }
+ <% end %>
+
+
RCallback* cbs = GetCallbackStruct(cb);
(*cbs->hash_map)[ <%= convert_keys_from_ruby %>(set_this)] = <%= convert_values_from_ruby %>(to_this);
return to_this; // ltodo test that it returns value...
}
static VALUE rb_ghash_get(VALUE cb, VALUE get_this) {
// TODO optionally not assert [?]
<% if assert_key_type %>
if(!(TYPE(get_this) == <%= assert_key_type %>)) {
- rb_raise(rb_eTypeError, "not valid value #{assert_key_type}");
+ rb_raise(rb_eTypeError, "not valid key #{assert_key_type}");
}
<% end %>
RCallback* cbs = GetCallbackStruct(cb);
<%= type %>_hash_map< <%= key_type %>, <%= value_type %> <%= extra_hash_params %> >::iterator out = cbs->hash_map->find(<%= convert_keys_from_ruby %>(get_this));