stash 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,181 @@
1
+ #include <ruby.h>
2
+ #include "mustache.h"
3
+ #include "stash.h"
4
+
5
+ const size_t INITIAL_BUFFER_SIZE = 1024;
6
+
7
+ mustache_ruby_context_t* create_mustache_ruby_context()
8
+ {
9
+ mustache_ruby_context_t* r_ctx = mustache_malloc(sizeof(mustache_ruby_context_t));
10
+ r_ctx->buffer = rb_str_buf_new(INITIAL_BUFFER_SIZE);
11
+ r_ctx->buffer_length = 0;
12
+ return r_ctx;
13
+ }
14
+
15
+ void destroy_mustache_context(mustache_context_t* m_ctx)
16
+ {
17
+ mustache_free(m_ctx);
18
+ }
19
+
20
+ mustache_context_t* create_mustache_context(mustache_context_t* parent)
21
+ {
22
+ mustache_context_t* m_ctx = mustache_malloc(sizeof(mustache_context_t));
23
+ m_ctx->get_data = convert_type;
24
+ m_ctx->get_partial = get_partial;
25
+ m_ctx->parent = parent;
26
+ m_ctx->data = NULL;
27
+ m_ctx->partials = parent ? parent->partials : NULL;
28
+ m_ctx->prefix = parent ? parent->prefix : NULL;
29
+ m_ctx->custom = parent ? parent->custom : create_mustache_ruby_context();
30
+ m_ctx->debug_mode = parent ? parent->debug_mode : false;
31
+ m_ctx->destroy = destroy_mustache_context;
32
+ return m_ctx;
33
+ }
34
+
35
+ static void destroy_mustache_object(mustache_value_t* value)
36
+ {
37
+ mustache_value_t* m_value = (mustache_value_t*) value;
38
+ m_value->data.object->destroy(m_value->data.object);
39
+ mustache_free(m_value);
40
+ }
41
+
42
+ static mustache_value_t* create_mustache_object(
43
+ mustache_context_t* m_ctx,
44
+ VALUE object)
45
+ {
46
+ mustache_value_t* val = mustache_malloc(sizeof(mustache_value_t));
47
+ val->type = VALUE_OBJECT;
48
+ val->length = 0;
49
+ val->data.object = create_mustache_context(m_ctx);
50
+ val->data.object->data = (void*) object;
51
+ val->destroy = destroy_mustache_object;
52
+ return val;
53
+ }
54
+
55
+ static void destroy_mustache_list(mustache_value_t* value)
56
+ {
57
+ mustache_context_t** m_list_ctxs = value->data.list;
58
+ for (size_t i = 0; i < value->length; i++) {
59
+ m_list_ctxs[i]->destroy(m_list_ctxs[i]);
60
+ }
61
+ mustache_free(value);
62
+ }
63
+
64
+ static mustache_value_t* create_mustache_list(
65
+ mustache_context_t* m_ctx,
66
+ VALUE rb_array)
67
+ {
68
+ size_t length = RARRAY_LEN(rb_array);
69
+ mustache_context_t** m_list_ctxs = mustache_malloc(sizeof(mustache_context_t*) * length);
70
+
71
+ for (long i = 0; i < length; i++) {
72
+ m_list_ctxs[i] = create_mustache_context(m_ctx);
73
+ m_list_ctxs[i]->data = (void*) rb_ary_entry(rb_array, i);
74
+ }
75
+
76
+ mustache_value_t* val = mustache_malloc(sizeof(mustache_value_t));
77
+ val->type = VALUE_LIST;
78
+ val->length = length;
79
+ val->data.list = m_list_ctxs;
80
+ val->destroy = destroy_mustache_list;
81
+ return val;
82
+ }
83
+
84
+ static void destroy_mustache_value(mustache_value_t* value)
85
+ {
86
+ mustache_free(value);
87
+ }
88
+
89
+ static mustache_value_t* create_mustache_value(
90
+ mustache_context_t* m_ctx,
91
+ VALUE rb_string)
92
+ {
93
+ mustache_value_t* val = mustache_malloc(sizeof(mustache_value_t));
94
+ val->type = VALUE_VALUE;
95
+ val->data.value = rb_string == Qnil ? NULL : RSTRING_PTR(rb_string);
96
+ val->length = rb_string == Qnil ? 0 : RSTRING_LEN(rb_string);
97
+ val->destroy = destroy_mustache_value;
98
+ return val;
99
+ }
100
+
101
+ static mustache_value_t* convert_value(
102
+ VALUE rb_value,
103
+ mustache_context_t* m_ctx)
104
+ {
105
+ switch (TYPE(rb_value)) {
106
+ case T_OBJECT: return create_mustache_object(m_ctx, rb_value);
107
+ case T_STRUCT: return create_mustache_object(m_ctx, rb_value);
108
+ case T_HASH: return create_mustache_object(m_ctx, rb_value);
109
+ case T_TRUE: return create_mustache_value(m_ctx, rb_str_new2("true"));
110
+ case T_FALSE: return create_mustache_value(m_ctx, Qnil);
111
+ case T_NONE: return create_mustache_value(m_ctx, Qnil);
112
+ case T_NIL: return create_mustache_value(m_ctx, Qnil);
113
+ case T_FLOAT: return create_mustache_value(m_ctx, rb_funcall(rb_value, rb_intern("to_s"), 0, 0));
114
+ case T_STRING: return create_mustache_value(m_ctx, rb_value);
115
+ case T_FIXNUM: return create_mustache_value(m_ctx, rb_fix2str(rb_value, 10));
116
+ case T_BIGNUM: return create_mustache_value(m_ctx, rb_big2str(rb_value, 10));
117
+ case T_ARRAY: return create_mustache_list(m_ctx, rb_value);
118
+ default:
119
+ if (rb_class_of(rb_value) == rb_cProc) {
120
+ return convert_value(rb_funcall(rb_value, rb_intern("call"), 0, 0), m_ctx);
121
+ }
122
+ return create_mustache_value(m_ctx, rb_any_to_s(rb_value));
123
+ }
124
+ }
125
+
126
+ static mustache_value_t* convert_hash(
127
+ VALUE hash,
128
+ char* key,
129
+ mustache_context_t* m_lookup_context,
130
+ mustache_context_t* m_exection_context)
131
+ {
132
+ VALUE rb_value;
133
+ if (NIL_P(rb_value = rb_hash_aref(hash, ID2SYM(rb_intern(key))))) {
134
+ return NULL;
135
+ }
136
+ return convert_value(rb_value, m_lookup_context);
137
+ }
138
+
139
+ static mustache_value_t* convert_object(
140
+ VALUE rb_object,
141
+ char* key,
142
+ mustache_context_t* m_lookup_context,
143
+ mustache_context_t* m_exection_context)
144
+ {
145
+ ID id = rb_intern(key);
146
+ if (rb_respond_to(rb_object, id)) {
147
+ rb_ivar_set(rb_object, rb_intern("@context"), (VALUE) m_exection_context->data);
148
+
149
+ double start = 0;
150
+ if (m_lookup_context->debug_mode) {
151
+ start = get_time();
152
+ }
153
+
154
+ VALUE result = rb_funcall(rb_object, id, 0, 0);
155
+
156
+ if (m_lookup_context->debug_mode) {
157
+ log_ruby_callback_execution_time(m_lookup_context, id, get_time() - start);
158
+ }
159
+
160
+ return convert_value(result, m_lookup_context);
161
+ }
162
+ return NULL;
163
+ }
164
+
165
+ mustache_value_t* convert_type(
166
+ char* key,
167
+ void* context,
168
+ mustache_context_t* m_lookup_context,
169
+ mustache_context_t* m_exection_context)
170
+ {
171
+ if (strcmp(key, ".") == 0) {
172
+ return convert_value((VALUE)context, m_lookup_context);
173
+ }
174
+
175
+ VALUE rb_context = (VALUE) context;
176
+ switch (TYPE(rb_context)) {
177
+ case T_OBJECT: return convert_object(rb_context, key, m_lookup_context, m_exection_context);
178
+ case T_HASH: return convert_hash(rb_context, key, m_lookup_context, m_exection_context);
179
+ default: return NULL;
180
+ }
181
+ }
@@ -1,34 +1,2 @@
1
- # Stash is an abstract interface to data structures servers
2
- class Stash
3
- attr_reader :adapter
4
-
5
- # Timeout when performing a blocking action, such as blocking pop
6
- class TimeoutError < StandardError; end
7
-
8
- def initialize(config)
9
- raise ArgumentError, "no adapter specified" unless config[:adapter]
10
- @adapter = Stash.adapter_class(config[:adapter]).new config
11
- end
12
-
13
- # Store an object in the Stash
14
- def []=(key, value)
15
- @adapter[key.to_s] = value
16
- end
17
-
18
- # Retrieve an object from the Stash
19
- def [](key)
20
- @adapter[key.to_s]
21
- end
22
-
23
- # Remove a key from the Stash
24
- def delete(key)
25
- @adapter.delete(key.to_s)
26
- true
27
- end
28
- end
29
-
30
- require 'stash/class_methods'
31
- require 'stash/redis_adapter'
32
- require 'stash/string'
33
- require 'stash/list'
34
- require 'stash/hash'
1
+ require 'stash/stash'
2
+ require 'stash/debug'
@@ -0,0 +1,46 @@
1
+ class Template::Callback
2
+ attr_accessor :name
3
+ attr_accessor :time
4
+
5
+ def initialize(name, time)
6
+ @name = name
7
+ @time = time
8
+ end
9
+
10
+ def to_s
11
+ "['#{@name}', #{@time}],"
12
+ end
13
+ end
14
+
15
+ class Template::Debug
16
+ attr_accessor :total_time
17
+ attr_accessor :callbacks
18
+
19
+ def initialize
20
+ @callbacks = []
21
+ end
22
+
23
+ def log_callback(name, time)
24
+ @callbacks.push Template::Callback.new(name, time)
25
+ end
26
+
27
+ def slowest_callbacks(n)
28
+ @callbacks.sort { |a, b| b.time <=> a.time}.first(n)
29
+ end
30
+
31
+ def group_slowest_callbacks(n)
32
+ @callbacks.group_by(&:name) \
33
+ .map { |k, v| [ k, v.inject(0) { |sum, x| sum + x.time }, v.length ] } \
34
+ .sort { |a, b| b[1] <=> a[1] } \
35
+ .first(n)
36
+ end
37
+
38
+ def mustache_time
39
+ total_time - ruby_time
40
+ end
41
+
42
+ def ruby_time
43
+ @callbacks.inject(0) { |sum, x| sum + x.time }
44
+ end
45
+
46
+ end
metadata CHANGED
@@ -1,100 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stash
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
- - 1
6
+ - 2
8
7
  - 0
9
8
  - 0
10
- version: 1.0.0
9
+ version: 2.0.0
11
10
  platform: ruby
12
11
  authors:
13
- - Tony Arcieri
12
+ - J.P. Cummins
14
13
  autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-12-07 00:00:00 -07:00
17
+ date: 2012-06-24 00:00:00 -07:00
19
18
  default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: redis
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 11
30
- segments:
31
- - 2
32
- - 1
33
- - 0
34
- version: 2.1.0
35
- type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: redis-namespace
39
- prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 55
46
- segments:
47
- - 0
48
- - 10
49
- - 0
50
- version: 0.10.0
51
- type: :runtime
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: rspec
55
- prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 7
62
- segments:
63
- - 2
64
- - 2
65
- - 0
66
- version: 2.2.0
67
- type: :development
68
- version_requirements: *id003
69
- description: Stash maps the facilities provided by data structures servers onto classes which mimic Ruby's built-in types
70
- email: tony@medioh.com
19
+ dependencies: []
20
+
21
+ description: stash, a lower-level mustache
22
+ email: jpcummins@gmail.com
71
23
  executables: []
72
24
 
73
- extensions: []
25
+ extensions:
26
+ - ext/stash/extconf.rb
27
+ extra_rdoc_files: []
74
28
 
75
- extra_rdoc_files:
76
- - LICENSE
77
- - README.markdown
78
29
  files:
79
- - .document
80
- - LICENSE
81
- - README.markdown
82
- - Rakefile
83
- - VERSION
30
+ - lib/stash/debug.rb
84
31
  - lib/stash.rb
85
- - lib/stash/class_methods.rb
86
- - lib/stash/hash.rb
87
- - lib/stash/list.rb
88
- - lib/stash/redis_adapter.rb
89
- - lib/stash/string.rb
90
- - spec/hash_spec.rb
91
- - spec/list_spec.rb
92
- - spec/spec.opts
93
- - spec/spec_helper.rb
94
- - spec/string_spec.rb
95
- - stash.gemspec
32
+ - ext/stash/build.c
33
+ - ext/stash/execute.c
34
+ - ext/stash/lex.yy.c
35
+ - ext/stash/mustache.c
36
+ - ext/stash/optimize.c
37
+ - ext/stash/stash.c
38
+ - ext/stash/tokens.c
39
+ - ext/stash/types.c
40
+ - ext/stash/intern.h
41
+ - ext/stash/lex.yy.h
42
+ - ext/stash/mustache.h
43
+ - ext/stash/stash.h
44
+ - ext/stash/extconf.rb
96
45
  has_rdoc: true
97
- homepage: http://github.com/tarcieri/stash
46
+ homepage: https://github.com/jpcummins/stash
98
47
  licenses: []
99
48
 
100
49
  post_install_message:
@@ -103,32 +52,25 @@ rdoc_options: []
103
52
  require_paths:
104
53
  - lib
105
54
  required_ruby_version: !ruby/object:Gem::Requirement
106
- none: false
107
55
  requirements:
108
56
  - - ">="
109
57
  - !ruby/object:Gem::Version
110
- hash: 3
111
58
  segments:
112
59
  - 0
113
60
  version: "0"
114
61
  required_rubygems_version: !ruby/object:Gem::Requirement
115
- none: false
116
62
  requirements:
117
63
  - - ">="
118
64
  - !ruby/object:Gem::Version
119
- hash: 3
120
65
  segments:
121
66
  - 0
122
67
  version: "0"
123
68
  requirements: []
124
69
 
125
70
  rubyforge_project:
126
- rubygems_version: 1.3.7
71
+ rubygems_version: 1.3.6
127
72
  signing_key:
128
73
  specification_version: 3
129
- summary: Abstract interface to data structures servers
130
- test_files:
131
- - spec/hash_spec.rb
132
- - spec/list_spec.rb
133
- - spec/spec_helper.rb
134
- - spec/string_spec.rb
74
+ summary: High perfomance mustache rendering engine written in C with extensions for Ruby
75
+ test_files: []
76
+
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2009 Tony Arcieri
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.