libcouchbase 0.0.4 → 0.0.5
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.
- checksums.yaml +4 -4
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -0
- data/ext/libcouchbase/cmake/source_files.cmake +2 -2
- data/ext/libcouchbase/contrib/cliopts/cliopts.c +32 -1
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +9 -1
- data/ext/libcouchbase/src/aspend.h +9 -10
- data/ext/libcouchbase/src/connspec.h +13 -0
- data/ext/libcouchbase/src/instance.cc +26 -34
- data/ext/libcouchbase/src/mcserver/negotiate.cc +617 -0
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -1
- data/ext/libcouchbase/src/n1ql/params.cc +1 -1
- data/ext/libcouchbase/src/packetutils.h +88 -2
- data/ext/libcouchbase/tests/iotests/t_misc.cc +20 -0
- data/ext/libcouchbase/tools/cbc-handlers.h +5 -5
- data/ext/libcouchbase/tools/cbc.cc +10 -1
- data/ext/libcouchbase/tools/docgen/docgen.h +1 -1
- data/lib/libcouchbase/bucket.rb +28 -5
- data/lib/libcouchbase/connection.rb +14 -2
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/bucket_spec.rb +6 -0
- data/spec/connection_spec.rb +5 -0
- data/spec/fts_spec.rb +6 -0
- data/spec/n1ql_spec.rb +5 -0
- data/spec/view_spec.rb +6 -0
- metadata +3 -6
- data/ext/libcouchbase/src/hashset.c +0 -164
- data/ext/libcouchbase/src/hashset.h +0 -86
- data/ext/libcouchbase/src/mcserver/negotiate.c +0 -657
- data/ext/libcouchbase/tests/basic/t_hashset.cc +0 -262
@@ -105,7 +105,7 @@ lcb_n1p_setconsistent_token(lcb_N1QLPARAMS *params,
|
|
105
105
|
}
|
106
106
|
|
107
107
|
params->root["scan_consistency"] = "at_plus";
|
108
|
-
encode_mutation_token(params->root["
|
108
|
+
encode_mutation_token(params->root["scan_vectors"][keyspace], sv);
|
109
109
|
return LCB_SUCCESS;
|
110
110
|
}
|
111
111
|
|
@@ -18,10 +18,11 @@
|
|
18
18
|
#ifndef LCB_PACKETUTILS_H
|
19
19
|
#define LCB_PACKETUTILS_H
|
20
20
|
|
21
|
+
#include "config.h"
|
22
|
+
|
21
23
|
#include <libcouchbase/couchbase.h>
|
22
|
-
#include
|
24
|
+
#include <memcached/protocol_binary.h>
|
23
25
|
#include "rdb/rope.h"
|
24
|
-
#include "memcached/protocol_binary.h"
|
25
26
|
|
26
27
|
#ifdef __cplusplus
|
27
28
|
extern "C" {
|
@@ -142,6 +143,91 @@ lcb_pktinfo_ior_done(packet_info *info, rdb_IOROPE *ior);
|
|
142
143
|
|
143
144
|
#ifdef __cplusplus
|
144
145
|
}
|
146
|
+
|
147
|
+
|
148
|
+
namespace lcb {
|
149
|
+
|
150
|
+
class MemcachedRequest {
|
151
|
+
public:
|
152
|
+
/**
|
153
|
+
* Declare the extras, key, and value size for the packet
|
154
|
+
* @param extlen Length of extras
|
155
|
+
* @param keylen Length of key
|
156
|
+
* @param valuelen Length of value (i.e. minus extras and key)
|
157
|
+
*/
|
158
|
+
void sizes(uint8_t extlen, uint16_t keylen, uint32_t valuelen) {
|
159
|
+
hdr.request.bodylen = htonl(extlen + keylen + valuelen);
|
160
|
+
hdr.request.keylen = htons(keylen);
|
161
|
+
hdr.request.extlen = extlen;
|
162
|
+
}
|
163
|
+
|
164
|
+
void vbucket(uint16_t vb) {
|
165
|
+
hdr.request.vbucket = htons(vb);
|
166
|
+
}
|
167
|
+
|
168
|
+
void opaque(uint32_t opaque_) {
|
169
|
+
hdr.request.opaque = opaque_;
|
170
|
+
}
|
171
|
+
|
172
|
+
MemcachedRequest(uint8_t opcode) {
|
173
|
+
hdr.request.opcode = opcode;
|
174
|
+
hdr.request.magic = PROTOCOL_BINARY_REQ;
|
175
|
+
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
176
|
+
hdr.request.cas = 0;
|
177
|
+
hdr.request.vbucket = 0;
|
178
|
+
hdr.request.opaque = 0;
|
179
|
+
hdr.request.bodylen = 0;
|
180
|
+
hdr.request.extlen = 0;
|
181
|
+
hdr.request.keylen = 0;
|
182
|
+
hdr.request.opaque = 0;
|
183
|
+
}
|
184
|
+
|
185
|
+
const void *data() const { return hdr.bytes; }
|
186
|
+
size_t size() const { return sizeof hdr.bytes; }
|
187
|
+
|
188
|
+
private:
|
189
|
+
protocol_binary_request_header hdr;
|
190
|
+
};
|
191
|
+
|
192
|
+
class MemcachedResponse : private packet_info {
|
193
|
+
public:
|
194
|
+
bool load(rdb_IOROPE *ior, unsigned *required) {
|
195
|
+
return lcb_pktinfo_ior_get(this, ior, required) != 0;
|
196
|
+
}
|
197
|
+
|
198
|
+
template <typename T>
|
199
|
+
bool load(T ctx, unsigned *required) {
|
200
|
+
return lcb_pktinfo_ectx_get(this, ctx, required);
|
201
|
+
}
|
202
|
+
|
203
|
+
void release(rdb_IOROPE *ior) {
|
204
|
+
lcb_pktinfo_ior_done(this, ior);
|
205
|
+
}
|
206
|
+
|
207
|
+
template <typename T>
|
208
|
+
void release(T ctx) {
|
209
|
+
lcb_pktinfo_ectx_done(this, ctx);
|
210
|
+
}
|
211
|
+
|
212
|
+
uint8_t opcode() const {
|
213
|
+
return PACKET_OPCODE(this);
|
214
|
+
}
|
215
|
+
|
216
|
+
uint16_t status() const {
|
217
|
+
return PACKET_STATUS(this);
|
218
|
+
}
|
219
|
+
|
220
|
+
template <typename T>
|
221
|
+
const T body() const {
|
222
|
+
return reinterpret_cast<const T>(packet_info::payload);
|
223
|
+
}
|
224
|
+
|
225
|
+
size_t bodylen() const {
|
226
|
+
return PACKET_NBODY(this);
|
227
|
+
}
|
228
|
+
};
|
229
|
+
|
230
|
+
}
|
145
231
|
#endif
|
146
232
|
|
147
233
|
#endif
|
@@ -20,6 +20,7 @@
|
|
20
20
|
#include <climits>
|
21
21
|
#include <algorithm>
|
22
22
|
#include "internal.h" /* vbucket_* things from lcb_t */
|
23
|
+
#include "auth-priv.h"
|
23
24
|
#include <lcbio/iotable.h>
|
24
25
|
#include "bucketconfig/bc_http.h"
|
25
26
|
|
@@ -711,3 +712,22 @@ TEST_F(MockUnitTest, testEmptyCtx)
|
|
711
712
|
err = mctx->done(mctx, NULL);
|
712
713
|
ASSERT_NE(LCB_SUCCESS, err);
|
713
714
|
}
|
715
|
+
|
716
|
+
TEST_F(MockUnitTest, testMultiCreds)
|
717
|
+
{
|
718
|
+
using lcb::Authenticator;
|
719
|
+
|
720
|
+
HandleWrap hw;
|
721
|
+
lcb_t instance;
|
722
|
+
createConnection(hw, instance);
|
723
|
+
|
724
|
+
lcb_BUCKETCRED cred;
|
725
|
+
cred[0] = "protected";
|
726
|
+
cred[1] = "secret";
|
727
|
+
lcb_error_t rc = lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_BUCKET_CRED, cred);
|
728
|
+
ASSERT_EQ(LCB_SUCCESS, rc);
|
729
|
+
Authenticator& auth = *instance->settings->auth;
|
730
|
+
lcb::Authenticator::Map::const_iterator res = auth.buckets().find("protected");
|
731
|
+
ASSERT_NE(auth.buckets().end(), res);
|
732
|
+
ASSERT_EQ("secret", res->second);
|
733
|
+
}
|
@@ -223,11 +223,11 @@ public:
|
|
223
223
|
o_expiry.abbrev('e').description("Expiration time for key");
|
224
224
|
}
|
225
225
|
protected:
|
226
|
-
cliopts::
|
227
|
-
cliopts::
|
226
|
+
cliopts::ULongLongOption o_initial;
|
227
|
+
cliopts::ULongLongOption o_delta;
|
228
228
|
cliopts::UIntOption o_expiry;
|
229
229
|
void run();
|
230
|
-
virtual
|
230
|
+
virtual bool shouldInvert() const = 0;
|
231
231
|
void addOptions() {
|
232
232
|
Handler::addOptions();
|
233
233
|
parser.addOption(o_initial);
|
@@ -243,7 +243,7 @@ public:
|
|
243
243
|
o_delta.description("Amount to increment by");
|
244
244
|
}
|
245
245
|
protected:
|
246
|
-
|
246
|
+
bool shouldInvert() const { return false; }
|
247
247
|
};
|
248
248
|
|
249
249
|
class DecrHandler : public ArithmeticHandler {
|
@@ -253,7 +253,7 @@ public:
|
|
253
253
|
o_delta.description("Amount to decrement by");
|
254
254
|
}
|
255
255
|
protected:
|
256
|
-
|
256
|
+
bool shouldInvert() const { return true; }
|
257
257
|
};
|
258
258
|
|
259
259
|
class ViewsHandler : public Handler {
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#define NOMINMAX
|
1
2
|
#include "common/my_inttypes.h"
|
2
3
|
#include <map>
|
3
4
|
#include <sstream>
|
@@ -7,6 +8,7 @@
|
|
7
8
|
#include <libcouchbase/vbucket.h>
|
8
9
|
#include <libcouchbase/views.h>
|
9
10
|
#include <libcouchbase/n1ql.h>
|
11
|
+
#include <limits>
|
10
12
|
#include <stddef.h>
|
11
13
|
#include "common/options.h"
|
12
14
|
#include "common/histogram.h"
|
@@ -907,7 +909,14 @@ ArithmeticHandler::run()
|
|
907
909
|
cmd.create = 1;
|
908
910
|
cmd.initial = o_initial.result();
|
909
911
|
}
|
910
|
-
|
912
|
+
uint64_t delta = o_delta.result();
|
913
|
+
if (delta > std::numeric_limits<int64_t>::max()) {
|
914
|
+
throw BadArg("Delta too big");
|
915
|
+
}
|
916
|
+
cmd.delta = static_cast<int64_t>(delta);
|
917
|
+
if (shouldInvert()) {
|
918
|
+
cmd.delta *= -1;
|
919
|
+
}
|
911
920
|
cmd.exptime = o_expiry.result();
|
912
921
|
lcb_error_t err = lcb_counter3(instance, NULL, &cmd);
|
913
922
|
if (err != LCB_SUCCESS) {
|
data/lib/libcouchbase/bucket.rb
CHANGED
@@ -12,12 +12,13 @@ module Libcouchbase
|
|
12
12
|
# http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
|
13
13
|
def self.finalize(connection)
|
14
14
|
proc {
|
15
|
+
connection.reactor.unref
|
15
16
|
connection.destroy
|
16
|
-
@connection.reactor.unref
|
17
17
|
}
|
18
18
|
end
|
19
19
|
|
20
20
|
def initialize(**options)
|
21
|
+
@connection_options = options
|
21
22
|
@connection = Connection.new(**options)
|
22
23
|
connect
|
23
24
|
|
@@ -778,10 +779,21 @@ module Libcouchbase
|
|
778
779
|
|
779
780
|
connecting.synchronize {
|
780
781
|
Thread.new do
|
781
|
-
@connection.reactor.run do
|
782
|
-
|
782
|
+
@connection.reactor.run do |reactor|
|
783
|
+
reactor.ref
|
784
|
+
|
785
|
+
attempt = 0
|
783
786
|
begin
|
784
787
|
co @connection.connect
|
788
|
+
rescue Libcouchbase::Error::ConnectError => e
|
789
|
+
attempt += 1
|
790
|
+
if attempt < 3
|
791
|
+
reactor.sleep 100
|
792
|
+
# Requires a new connection object or the retry will always fail
|
793
|
+
@connection = Connection.new(**@connection_options)
|
794
|
+
retry
|
795
|
+
end
|
796
|
+
error = e
|
785
797
|
rescue => e
|
786
798
|
error = e
|
787
799
|
end
|
@@ -804,10 +816,21 @@ module Libcouchbase
|
|
804
816
|
error = nil
|
805
817
|
|
806
818
|
Thread.new do
|
807
|
-
@connection.reactor.run do
|
808
|
-
|
819
|
+
@connection.reactor.run do |reactor|
|
820
|
+
reactor.ref
|
821
|
+
|
822
|
+
attempt = 0
|
809
823
|
begin
|
810
824
|
co @connection.connect
|
825
|
+
rescue Libcouchbase::Error::ConnectError => e
|
826
|
+
attempt += 1
|
827
|
+
if attempt < 3
|
828
|
+
reactor.sleep 100
|
829
|
+
# Requires a new connection object or the retry will always fail
|
830
|
+
@connection = Connection.new(**@connection_options)
|
831
|
+
retry
|
832
|
+
end
|
833
|
+
error = e
|
811
834
|
rescue => e
|
812
835
|
error = e
|
813
836
|
end
|
@@ -753,7 +753,13 @@ module Libcouchbase
|
|
753
753
|
view.received(row_data)
|
754
754
|
end
|
755
755
|
else
|
756
|
-
|
756
|
+
error_klass = Error.lookup(row_data[:rc])
|
757
|
+
if error_klass == Error::HttpError
|
758
|
+
http_resp = row_data[:htresp]
|
759
|
+
view.error error_klass.new(http_resp[:body].read_string(http_resp[:nbody]))
|
760
|
+
else
|
761
|
+
view.error error_klass.new
|
762
|
+
end
|
757
763
|
end
|
758
764
|
end
|
759
765
|
|
@@ -783,7 +789,13 @@ module Libcouchbase
|
|
783
789
|
view.received(value)
|
784
790
|
end
|
785
791
|
else
|
786
|
-
|
792
|
+
error_klass = Error.lookup(row_data[:rc])
|
793
|
+
if error_klass == Error::HttpError
|
794
|
+
http_resp = row_data[:htresp]
|
795
|
+
view.error error_klass.new(http_resp[:body].read_string(http_resp[:nbody]))
|
796
|
+
else
|
797
|
+
view.error error_klass.new
|
798
|
+
end
|
787
799
|
end
|
788
800
|
end
|
789
801
|
end
|
data/lib/libcouchbase/version.rb
CHANGED
data/spec/bucket_spec.rb
CHANGED
data/spec/connection_spec.rb
CHANGED
@@ -10,6 +10,11 @@ describe Libcouchbase::Connection do
|
|
10
10
|
@reactor = ::Libuv::Reactor.default
|
11
11
|
end
|
12
12
|
|
13
|
+
after :each do
|
14
|
+
@reactor = nil
|
15
|
+
@log = nil
|
16
|
+
end
|
17
|
+
|
13
18
|
it "should connect and disconnect from the default bucket" do
|
14
19
|
@reactor.run { |reactor|
|
15
20
|
connection = Libcouchbase::Connection.new
|
data/spec/fts_spec.rb
CHANGED
@@ -11,6 +11,12 @@ describe Libcouchbase::QueryFullText, full_text_search: true do
|
|
11
11
|
@log = []
|
12
12
|
end
|
13
13
|
|
14
|
+
after :each do
|
15
|
+
@bucket = nil
|
16
|
+
@reactor = nil
|
17
|
+
@log = nil
|
18
|
+
end
|
19
|
+
|
14
20
|
describe 'perform native queries' do
|
15
21
|
it "should iterate a full text search with results" do
|
16
22
|
results = @bucket.full_text_search(:default, 'Toshiba')
|
data/spec/n1ql_spec.rb
CHANGED
@@ -10,6 +10,11 @@ describe Libcouchbase::N1QL, n1ql_query: true do
|
|
10
10
|
@log = []
|
11
11
|
end
|
12
12
|
|
13
|
+
after :each do
|
14
|
+
@bucket = nil
|
15
|
+
@log = nil
|
16
|
+
end
|
17
|
+
|
13
18
|
it "should build a basic query" do
|
14
19
|
@n1ql.select('*').from(:default).where('port == 10001')
|
15
20
|
expect(@n1ql.to_s).to eq("SELECT *\nFROM default\nWHERE port == 10001\n")
|
data/spec/view_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libcouchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen von Takach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -407,8 +407,6 @@ files:
|
|
407
407
|
- ext/libcouchbase/src/getconfig.c
|
408
408
|
- ext/libcouchbase/src/gethrtime.c
|
409
409
|
- ext/libcouchbase/src/handler.c
|
410
|
-
- ext/libcouchbase/src/hashset.c
|
411
|
-
- ext/libcouchbase/src/hashset.h
|
412
410
|
- ext/libcouchbase/src/hashtable.c
|
413
411
|
- ext/libcouchbase/src/hdr_timings.c
|
414
412
|
- ext/libcouchbase/src/hostlist.cc
|
@@ -456,7 +454,7 @@ files:
|
|
456
454
|
- ext/libcouchbase/src/mc/mcreq.h
|
457
455
|
- ext/libcouchbase/src/mcserver/mcserver.c
|
458
456
|
- ext/libcouchbase/src/mcserver/mcserver.h
|
459
|
-
- ext/libcouchbase/src/mcserver/negotiate.
|
457
|
+
- ext/libcouchbase/src/mcserver/negotiate.cc
|
460
458
|
- ext/libcouchbase/src/mcserver/negotiate.h
|
461
459
|
- ext/libcouchbase/src/n1ql/ixmgmt.cc
|
462
460
|
- ext/libcouchbase/src/n1ql/n1ql-internal.h
|
@@ -535,7 +533,6 @@ files:
|
|
535
533
|
- ext/libcouchbase/tests/basic/t_connstr.cc
|
536
534
|
- ext/libcouchbase/tests/basic/t_creds.cc
|
537
535
|
- ext/libcouchbase/tests/basic/t_ctlcodes.cc
|
538
|
-
- ext/libcouchbase/tests/basic/t_hashset.cc
|
539
536
|
- ext/libcouchbase/tests/basic/t_host.cc
|
540
537
|
- ext/libcouchbase/tests/basic/t_jsparse.cc
|
541
538
|
- ext/libcouchbase/tests/basic/t_jsparse.h
|
@@ -1,164 +0,0 @@
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
-
/*
|
3
|
-
* Copyright 2012 Couchbase, Inc.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
#include "internal.h"
|
19
|
-
|
20
|
-
static const unsigned int prime_1 = 73;
|
21
|
-
static const unsigned int prime_2 = 5009;
|
22
|
-
|
23
|
-
hashset_t hashset_create()
|
24
|
-
{
|
25
|
-
hashset_t set = calloc(1, sizeof(struct hashset_st));
|
26
|
-
|
27
|
-
if (set == NULL) {
|
28
|
-
return NULL;
|
29
|
-
}
|
30
|
-
set->nbits = 3;
|
31
|
-
set->capacity = (lcb_size_t)(1 << set->nbits);
|
32
|
-
set->mask = set->capacity - 1;
|
33
|
-
set->items = calloc(set->capacity, sizeof(lcb_size_t));
|
34
|
-
if (set->items == NULL) {
|
35
|
-
hashset_destroy(set);
|
36
|
-
return NULL;
|
37
|
-
}
|
38
|
-
set->nitems = 0;
|
39
|
-
return set;
|
40
|
-
}
|
41
|
-
|
42
|
-
lcb_size_t hashset_num_items(hashset_t set)
|
43
|
-
{
|
44
|
-
return set->nitems;
|
45
|
-
}
|
46
|
-
|
47
|
-
void hashset_destroy(hashset_t set)
|
48
|
-
{
|
49
|
-
if (set) {
|
50
|
-
free(set->items);
|
51
|
-
}
|
52
|
-
free(set);
|
53
|
-
}
|
54
|
-
|
55
|
-
static int hashset_add_member(hashset_t set, void *item)
|
56
|
-
{
|
57
|
-
lcb_size_t value = (lcb_size_t)item;
|
58
|
-
lcb_size_t ii;
|
59
|
-
|
60
|
-
if (value == 0 || value == 1) {
|
61
|
-
return -1;
|
62
|
-
}
|
63
|
-
|
64
|
-
ii = set->mask & (prime_1 * value);
|
65
|
-
|
66
|
-
while (set->items[ii] != 0 && set->items[ii] != 1) {
|
67
|
-
if (set->items[ii] == value) {
|
68
|
-
return 0;
|
69
|
-
} else {
|
70
|
-
/* search free slot */
|
71
|
-
ii = set->mask & (ii + prime_2);
|
72
|
-
}
|
73
|
-
}
|
74
|
-
set->nitems++;
|
75
|
-
set->items[ii] = value;
|
76
|
-
return 1;
|
77
|
-
}
|
78
|
-
|
79
|
-
static void maybe_rehash(hashset_t set)
|
80
|
-
{
|
81
|
-
lcb_size_t *old_items;
|
82
|
-
lcb_size_t old_capacity, ii;
|
83
|
-
|
84
|
-
|
85
|
-
if ((float)set->nitems >= (lcb_size_t)((double)set->capacity * 0.85)) {
|
86
|
-
old_items = set->items;
|
87
|
-
old_capacity = set->capacity;
|
88
|
-
set->nbits++;
|
89
|
-
set->capacity = (lcb_size_t)(1 << set->nbits);
|
90
|
-
set->mask = set->capacity - 1;
|
91
|
-
set->items = calloc(set->capacity, sizeof(lcb_size_t));
|
92
|
-
set->nitems = 0;
|
93
|
-
lcb_assert(set->items);
|
94
|
-
for (ii = 0; ii < old_capacity; ii++) {
|
95
|
-
hashset_add_member(set, (void *)old_items[ii]);
|
96
|
-
}
|
97
|
-
free(old_items);
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
int hashset_add(hashset_t set, void *item)
|
102
|
-
{
|
103
|
-
int rv = hashset_add_member(set, item);
|
104
|
-
maybe_rehash(set);
|
105
|
-
return rv;
|
106
|
-
}
|
107
|
-
|
108
|
-
int hashset_remove(hashset_t set, void *item)
|
109
|
-
{
|
110
|
-
lcb_size_t value = (lcb_size_t)item;
|
111
|
-
lcb_size_t ii = set->mask & (prime_1 * value);
|
112
|
-
|
113
|
-
while (set->items[ii] != 0) {
|
114
|
-
if (set->items[ii] == value) {
|
115
|
-
set->items[ii] = 1;
|
116
|
-
set->nitems--;
|
117
|
-
return 1;
|
118
|
-
} else {
|
119
|
-
ii = set->mask & (ii + prime_2);
|
120
|
-
}
|
121
|
-
}
|
122
|
-
return 0;
|
123
|
-
}
|
124
|
-
|
125
|
-
int hashset_is_member(hashset_t set, void *item)
|
126
|
-
{
|
127
|
-
lcb_size_t value = (lcb_size_t)item;
|
128
|
-
lcb_size_t ii = set->mask & (prime_1 * value);
|
129
|
-
|
130
|
-
while (set->items[ii] != 0) {
|
131
|
-
if (set->items[ii] == value) {
|
132
|
-
return 1;
|
133
|
-
} else {
|
134
|
-
ii = set->mask & (ii + prime_2);
|
135
|
-
}
|
136
|
-
}
|
137
|
-
return 0;
|
138
|
-
}
|
139
|
-
|
140
|
-
void **hashset_get_items(hashset_t set, void **itemlist)
|
141
|
-
{
|
142
|
-
lcb_size_t ii, oix;
|
143
|
-
|
144
|
-
if (!set->nitems) {
|
145
|
-
return NULL;
|
146
|
-
}
|
147
|
-
|
148
|
-
if (!itemlist) {
|
149
|
-
itemlist = malloc(set->nitems * sizeof(void *));
|
150
|
-
if (!itemlist) {
|
151
|
-
return NULL;
|
152
|
-
}
|
153
|
-
}
|
154
|
-
|
155
|
-
for (ii = 0, oix = 0; ii < set->capacity; ii++) {
|
156
|
-
|
157
|
-
if (set->items[ii] > 1) {
|
158
|
-
itemlist[oix] = (void *)set->items[ii];
|
159
|
-
oix++;
|
160
|
-
}
|
161
|
-
}
|
162
|
-
|
163
|
-
return itemlist;
|
164
|
-
}
|