libcouchbase 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
}
|