listpack 0.0.1.beta

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,61 @@
1
+ /* Listpack -- A lists of strings serialization format
2
+ *
3
+ * This file implements the specification you can find at:
4
+ *
5
+ * https://github.com/antirez/listpack
6
+ *
7
+ * Copyright (c) 2017, Salvatore Sanfilippo <antirez at gmail dot com>
8
+ * All rights reserved.
9
+ *
10
+ * Redistribution and use in source and binary forms, with or without
11
+ * modification, are permitted provided that the following conditions are met:
12
+ *
13
+ * * Redistributions of source code must retain the above copyright notice,
14
+ * this list of conditions and the following disclaimer.
15
+ * * Redistributions in binary form must reproduce the above copyright
16
+ * notice, this list of conditions and the following disclaimer in the
17
+ * documentation and/or other materials provided with the distribution.
18
+ * * Neither the name of Redis nor the names of its contributors may be used
19
+ * to endorse or promote products derived from this software without
20
+ * specific prior written permission.
21
+ *
22
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ * POSSIBILITY OF SUCH DAMAGE.
33
+ */
34
+
35
+ #ifndef __LISTPACK_H
36
+ #define __LISTPACK_H
37
+
38
+ #include <stdint.h>
39
+
40
+ #define LP_INTBUF_SIZE 21 /* 20 digits of -2^63 + 1 null term = 21. */
41
+
42
+ /* lpInsert() where argument possible values: */
43
+ #define LP_BEFORE 0
44
+ #define LP_AFTER 1
45
+ #define LP_REPLACE 2
46
+
47
+ unsigned char *lpNew(void);
48
+ void lpFree(unsigned char *lp);
49
+ unsigned char *lpInsert(unsigned char *lp, unsigned char *ele, uint32_t size, unsigned char *p, int where, unsigned char **newp);
50
+ unsigned char *lpAppend(unsigned char *lp, unsigned char *ele, uint32_t size);
51
+ unsigned char *lpDelete(unsigned char *lp, unsigned char *p, unsigned char **newp);
52
+ uint32_t lpLength(unsigned char *lp);
53
+ unsigned char *lpGet(unsigned char *p, int64_t *count, unsigned char *intbuf);
54
+ unsigned char *lpFirst(unsigned char *lp);
55
+ unsigned char *lpLast(unsigned char *lp);
56
+ unsigned char *lpNext(unsigned char *lp, unsigned char *p);
57
+ unsigned char *lpPrev(unsigned char *lp, unsigned char *p);
58
+ uint32_t lpBytes(unsigned char *lp);
59
+ unsigned char *lpSeek(unsigned char *lp, long index);
60
+
61
+ #endif
@@ -0,0 +1,45 @@
1
+ /* Listpack -- A lists of strings serialization format
2
+ * https://github.com/antirez/listpack
3
+ *
4
+ * Copyright (c) 2017, Salvatore Sanfilippo <antirez at gmail dot com>
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ * * Neither the name of Redis nor the names of its contributors may be used
16
+ * to endorse or promote products derived from this software without
17
+ * specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+
32
+ /* Allocator selection.
33
+ *
34
+ * This file is used in order to change the Rax allocator at compile time.
35
+ * Just define the following defines to what you want to use. Also add
36
+ * the include of your alternate allocator if needed (not needed in order
37
+ * to use the default libc allocator). */
38
+
39
+ #ifndef LISTPACK_ALLOC_H
40
+ #define LISTPACK_ALLOC_H
41
+ //#include "zmalloc.h"
42
+ #define lp_malloc malloc
43
+ #define lp_realloc realloc
44
+ #define lp_free free
45
+ #endif
@@ -0,0 +1,211 @@
1
+ #include <ruby.h>
2
+ #include <stdint.h>
3
+ #include "listpack.h"
4
+ #include "listpack_malloc.h"
5
+
6
+ static VALUE Listpack;
7
+
8
+ typedef struct {
9
+ unsigned char *lp;
10
+ unsigned char *p;
11
+ } listpack_rb;
12
+
13
+ // Internal methods
14
+
15
+ /* Loads a listpack format string into the internal struct */
16
+ VALUE _rb_listpack_load(VALUE self, VALUE rb_str)
17
+ {
18
+ listpack_rb *list;
19
+ Data_Get_Struct(self, listpack_rb, list);
20
+ size_t str_len = RSTRING_LENINT(rb_str);
21
+
22
+ if (list->lp != NULL) {
23
+ lp_free(list->lp);
24
+ }
25
+
26
+ list->lp = lp_malloc(str_len);
27
+
28
+ if (list->lp == NULL) {
29
+ rb_raise(rb_eNoMemError, "no memory for listpack");
30
+ }
31
+
32
+ memcpy(list->lp, RSTRING_PTR(rb_str), str_len);
33
+
34
+ return Qtrue;
35
+ }
36
+
37
+ /* Converts a value from the list to the correct Ruby type */
38
+ VALUE _rb_listpack_getvalue(unsigned char *p)
39
+ {
40
+ if(!p) {
41
+ return Qnil;
42
+ }
43
+
44
+ unsigned char * result;
45
+ int64_t num;
46
+
47
+ result = lpGet(p, &num, NULL);
48
+
49
+ if(result) {
50
+ return rb_str_new((char *) result, num);
51
+ } else {
52
+ return rb_int_new(num);
53
+ }
54
+ }
55
+
56
+ // Public methods
57
+ VALUE rb_listpack_append(VALUE self, VALUE rb_ele)
58
+ {
59
+ listpack_rb *list;
60
+ Data_Get_Struct(self, listpack_rb, list);
61
+
62
+ list->lp = lpAppend(list->lp, (unsigned char *) RSTRING_PTR(rb_ele), RSTRING_LENINT(rb_ele));
63
+
64
+ if (list->lp == NULL) {
65
+ rb_raise(rb_eNoMemError, "no memory for listpack");
66
+ }
67
+
68
+ return Qtrue;
69
+ }
70
+
71
+ VALUE rb_listpack_current(VALUE self)
72
+ {
73
+ listpack_rb *list;
74
+ Data_Get_Struct(self, listpack_rb, list);
75
+
76
+ if (list->p == NULL) {
77
+ return Qnil;
78
+ }
79
+ else {
80
+ return _rb_listpack_getvalue(list->p);
81
+ }
82
+ }
83
+
84
+ VALUE rb_listpack_first(VALUE self)
85
+ {
86
+ listpack_rb *list;
87
+ unsigned char *result;
88
+ Data_Get_Struct(self, listpack_rb, list);
89
+
90
+ result = lpFirst(list->lp);
91
+
92
+ return _rb_listpack_getvalue(result);
93
+ }
94
+
95
+ VALUE rb_listpack_initialize(int argc, VALUE* argv, VALUE self)
96
+ {
97
+ listpack_rb *list;
98
+ VALUE data;
99
+ Data_Get_Struct(self, listpack_rb, list);
100
+ rb_scan_args(argc, argv, "01", &data);
101
+
102
+ if (NIL_P(data)) {
103
+ list->lp = lpNew();
104
+ }
105
+ else {
106
+ _rb_listpack_load(self, data);
107
+ }
108
+
109
+ return Qnil;
110
+ }
111
+
112
+ VALUE rb_listpack_insert(VALUE self, VALUE rb_ele)
113
+ {
114
+ listpack_rb *list;
115
+ Data_Get_Struct(self, listpack_rb, list);
116
+
117
+ list->lp = lpInsert(list->lp, (unsigned char *) RSTRING_PTR(rb_ele), RSTRING_LENINT(rb_ele), list->p, LP_AFTER, &list->p);
118
+
119
+ if (list->lp == NULL) {
120
+ rb_raise(rb_eNoMemError, "no memory for listpack");
121
+ }
122
+
123
+ return Qtrue;
124
+ }
125
+
126
+ VALUE rb_listpack_last(VALUE self)
127
+ {
128
+ listpack_rb *list;
129
+ unsigned char *result;
130
+ Data_Get_Struct(self, listpack_rb, list);
131
+
132
+ result = lpLast(list->lp);
133
+
134
+ return _rb_listpack_getvalue(result);
135
+ }
136
+
137
+ VALUE rb_listpack_next(VALUE self)
138
+ {
139
+ listpack_rb *list;
140
+ Data_Get_Struct(self, listpack_rb, list);
141
+
142
+ if (list->p == NULL) {
143
+ list->p = lpFirst(list->lp);
144
+ } else {
145
+ list->p = lpNext(list->lp, list->p);
146
+ }
147
+
148
+ return _rb_listpack_getvalue(list->p);
149
+ }
150
+
151
+ VALUE rb_listpack_seek(VALUE self, VALUE rb_idx)
152
+ {
153
+ listpack_rb *list;
154
+ Data_Get_Struct(self, listpack_rb, list);
155
+
156
+ list->p = lpSeek(list->lp, NUM2UINT(rb_idx));
157
+
158
+ return Qnil;
159
+ }
160
+
161
+ VALUE rb_listpack_size(VALUE self)
162
+ {
163
+ listpack_rb *list;
164
+ Data_Get_Struct(self, listpack_rb, list);
165
+
166
+ return rb_uint_new(lpLength(list->lp));
167
+ }
168
+
169
+ VALUE rb_listpack_to_s(VALUE self)
170
+ {
171
+ listpack_rb *list;
172
+ Data_Get_Struct(self, listpack_rb, list);
173
+
174
+ return rb_str_new((char *) list->lp, lpBytes(list->lp));
175
+ }
176
+
177
+ static void deallocate(listpack_rb *p_list)
178
+ {
179
+ lpFree(p_list->lp);
180
+ xfree(p_list);
181
+ }
182
+
183
+ static VALUE allocate(VALUE klass)
184
+ {
185
+ listpack_rb *list;
186
+
187
+ if ((list = ALLOC(listpack_rb)) != NULL)
188
+ {
189
+ list->lp = NULL;
190
+ list->p = NULL;
191
+ }
192
+
193
+ return Data_Wrap_Struct(klass, NULL, deallocate, list);
194
+ }
195
+
196
+ void Init_listpack(void) {
197
+ Listpack = rb_define_class("Listpack", rb_cObject);
198
+ rb_define_alloc_func(Listpack, allocate);
199
+
200
+ rb_define_method(Listpack, "append", rb_listpack_append, 1);
201
+ rb_define_method(Listpack, "current", rb_listpack_current, 0);
202
+ rb_define_method(Listpack, "first", rb_listpack_first, 0);
203
+ rb_define_method(Listpack, "initialize", rb_listpack_initialize, -1);
204
+ rb_define_method(Listpack, "insert", rb_listpack_insert, 1);
205
+ rb_define_method(Listpack, "last", rb_listpack_next, 0);
206
+ rb_define_method(Listpack, "next", rb_listpack_next, 0);
207
+ rb_define_method(Listpack, "prev", rb_listpack_first, 0);
208
+ rb_define_method(Listpack, "seek", rb_listpack_seek, 1);
209
+ rb_define_method(Listpack, "size", rb_listpack_size, 0);
210
+ rb_define_method(Listpack, "to_s", rb_listpack_to_s, 0);
211
+ }
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'listpack/version'
4
+ require 'listpack/listpack'
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Listpack
4
+ VERSION = '0.0.1.beta'
5
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require "listpack/version"
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "listpack"
10
+ spec.version = Listpack::VERSION
11
+ spec.authors = ["Sebastian Wallin"]
12
+ spec.email = ["sebastian.wallin@gmail.com"]
13
+ spec.extensions = ["ext/listpack/extconf.rb"]
14
+
15
+ spec.summary = %q{Ruby wrapper for Redis listpack data structure}
16
+ spec.description = %q{Ruby wrapper for Redis listpack data structure}
17
+ spec.homepage = "https://github.com/wallin/listpack-rb"
18
+ spec.license = 'BSD-3-Clause'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_dependency "rake-compiler"
28
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: listpack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.beta
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian Wallin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Ruby wrapper for Redis listpack data structure
28
+ email:
29
+ - sebastian.wallin@gmail.com
30
+ executables: []
31
+ extensions:
32
+ - ext/listpack/extconf.rb
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".rspec"
37
+ - ".ruby-gemset"
38
+ - ".ruby-version"
39
+ - ".travis.yml"
40
+ - Gemfile
41
+ - Gemfile.lock
42
+ - README.md
43
+ - Rakefile
44
+ - bin/console
45
+ - bin/setup
46
+ - ext/listpack/extconf.rb
47
+ - ext/listpack/listpack.c
48
+ - ext/listpack/listpack.h
49
+ - ext/listpack/listpack_malloc.h
50
+ - ext/listpack/listpack_rb.c
51
+ - lib/listpack.rb
52
+ - lib/listpack/version.rb
53
+ - listpack.gemspec
54
+ homepage: https://github.com/wallin/listpack-rb
55
+ licenses:
56
+ - BSD-3-Clause
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">"
70
+ - !ruby/object:Gem::Version
71
+ version: 1.3.1
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.7.6
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Ruby wrapper for Redis listpack data structure
78
+ test_files: []