stash 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.