gazay-kyotocabinet-ruby 1.28 → 1.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/kyotocabinet.cc +169 -160
  2. metadata +6 -6
@@ -45,6 +45,8 @@ typedef VALUE (*METHOD)(...);
45
45
  // function prototypes
46
46
  void Init_kyotocabinet();
47
47
  static VALUE StringValueEx(VALUE vobj);
48
+ static int64_t vatoi(VALUE vobj);
49
+ static double vatof(VALUE vobj);
48
50
  static VALUE rb_str_new_ex(VALUE vdb, const char* ptr, size_t size);
49
51
  static VALUE rb_str_new_ex2(VALUE vdb, const char* str);
50
52
  static VALUE findclass(const char* name);
@@ -58,6 +60,7 @@ static VALUE kc_atoix(VALUE vself, VALUE vstr);
58
60
  static VALUE kc_atof(VALUE vself, VALUE vstr);
59
61
  static VALUE kc_hash_murmur(VALUE vself, VALUE vstr);
60
62
  static VALUE kc_hash_fnv(VALUE vself, VALUE vstr);
63
+ static VALUE kc_levdist(int argc, VALUE* argv, VALUE vself);
61
64
  static void threadyield();
62
65
  static void define_err();
63
66
  static void err_define_child(const char* name, uint32_t code);
@@ -137,6 +140,7 @@ static VALUE db_path(VALUE vself);
137
140
  static VALUE db_status(VALUE vself);
138
141
  static VALUE db_match_prefix(int argc, VALUE* argv, VALUE vself);
139
142
  static VALUE db_match_regex(int argc, VALUE* argv, VALUE vself);
143
+ static VALUE db_match_similar(int argc, VALUE* argv, VALUE vself);
140
144
  static VALUE db_merge(int argc, VALUE* argv, VALUE vself);
141
145
  static VALUE db_cursor(VALUE vself);
142
146
  static VALUE db_cursor_process(VALUE vself);
@@ -646,6 +650,70 @@ static VALUE StringValueEx(VALUE vobj) {
646
650
  }
647
651
 
648
652
 
653
+ /**
654
+ * Convert a numeric parameter to an integer.
655
+ */
656
+ static int64_t vatoi(VALUE vobj) {
657
+ switch (TYPE(vobj)) {
658
+ case T_FIXNUM: {
659
+ return FIX2INT(vobj);
660
+ }
661
+ case T_BIGNUM: {
662
+ return NUM2LL(vobj);
663
+ }
664
+ case T_FLOAT: {
665
+ double dnum = NUM2DBL(vobj);
666
+ if (kc::chknan(dnum)) {
667
+ return kc::INT64MIN;
668
+ } else if (kc::chkinf(dnum)) {
669
+ return dnum < 0 ? kc::INT64MIN : kc::INT64MAX;
670
+ }
671
+ return dnum;
672
+ }
673
+ case T_TRUE: {
674
+ return 1;
675
+ }
676
+ case T_STRING: {
677
+ const char* str = RSTRING_PTR(vobj);
678
+ double dnum = kc::atof(str);
679
+ if (kc::chknan(dnum)) {
680
+ return kc::INT64MIN;
681
+ } else if (kc::chkinf(dnum)) {
682
+ return dnum < 0 ? kc::INT64MIN : kc::INT64MAX;
683
+ }
684
+ return dnum;
685
+ }
686
+ }
687
+ return 0;
688
+ }
689
+
690
+
691
+ /**
692
+ * Convert a numeric parameter to a real number.
693
+ */
694
+ static double vatof(VALUE vobj) {
695
+ switch (TYPE(vobj)) {
696
+ case T_FIXNUM: {
697
+ return FIX2INT(vobj);
698
+ }
699
+ case T_BIGNUM: {
700
+ return NUM2LL(vobj);
701
+ }
702
+ case T_FLOAT: {
703
+ return NUM2DBL(vobj);
704
+ }
705
+ case T_TRUE: {
706
+ return 1.0;
707
+ }
708
+ case T_STRING: {
709
+ const char* str = RSTRING_PTR(vobj);
710
+ return kc::atof(str);
711
+ }
712
+ }
713
+ return 0.0;
714
+ }
715
+
716
+
649
717
  /**
650
718
  * Generate a string object with the internal encoding of the database.
651
719
  */
@@ -746,6 +814,7 @@ static void define_module() {
746
814
  rb_define_method(mod_kc, "atof", (METHOD)kc_atof, 1);
747
815
  rb_define_method(mod_kc, "hash_murmur", (METHOD)kc_hash_murmur, 1);
748
816
  rb_define_method(mod_kc, "hash_fnv", (METHOD)kc_hash_fnv, 1);
817
+ rb_define_method(mod_kc, "levdist", (METHOD)kc_levdist, -1);
749
818
  cls_ex = findclass("RuntimeError");
750
819
  cls_str = findclass("String");
751
820
  id_str_force_encoding = rb_intern("force_encoding");
@@ -811,7 +880,7 @@ static VALUE kc_hash_murmur(VALUE vself, VALUE vstr) {
811
880
 
812
881
 
813
882
  /**
814
- * Implementation of fnv.
883
+ * Implementation of hash_fnv.
815
884
  */
816
885
  static VALUE kc_hash_fnv(VALUE vself, VALUE vstr) {
817
886
  vstr = StringValueEx(vstr);
@@ -820,6 +889,39 @@ static VALUE kc_hash_fnv(VALUE vself, VALUE vstr) {
820
889
  }
821
890
 
822
891
 
892
+ /**
893
+ * Implementation of levdist.
894
+ */
895
+ static VALUE kc_levdist(int argc, VALUE* argv, VALUE vself) {
896
+ volatile VALUE va, vb, vutf;
897
+ rb_scan_args(argc, argv, "21", &va, &vb, &vutf);
898
+ va = StringValueEx(va);
899
+ const char* abuf = RSTRING_PTR(va);
900
+ size_t asiz = RSTRING_LEN(va);
901
+ vb = StringValueEx(vb);
902
+ const char* bbuf = RSTRING_PTR(vb);
903
+ size_t bsiz = RSTRING_LEN(vb);
904
+ bool utf = vutf != Qnil && vutf != Qfalse;
905
+ size_t dist;
906
+ if (utf) {
907
+ uint32_t astack[128];
908
+ uint32_t* aary = asiz > sizeof(astack) / sizeof(*astack) ? new uint32_t[asiz] : astack;
909
+ size_t anum;
910
+ kc::strutftoucs(abuf, asiz, aary, &anum);
911
+ uint32_t bstack[128];
912
+ uint32_t* bary = bsiz > sizeof(bstack) / sizeof(*bstack) ? new uint32_t[bsiz] : bstack;
913
+ size_t bnum;
914
+ kc::strutftoucs(bbuf, bsiz, bary, &bnum);
915
+ dist = kc::strucsdist(aary, anum, bary, bnum);
916
+ if (bary != bstack) delete[] bary;
917
+ if (aary != astack) delete[] aary;
918
+ } else {
919
+ dist = kc::memdist(abuf, asiz, bbuf, bsiz);
920
+ }
921
+ return INT2FIX((int)dist);
922
+ }
923
+
924
+
823
925
  /**
824
926
  * Define objects of the Error class.
825
927
  */
@@ -1910,6 +2012,7 @@ static void define_db() {
1910
2012
  rb_define_method(cls_db, "status", (METHOD)db_status, 0);
1911
2013
  rb_define_method(cls_db, "match_prefix", (METHOD)db_match_prefix, -1);
1912
2014
  rb_define_method(cls_db, "match_regex", (METHOD)db_match_regex, -1);
2015
+ rb_define_method(cls_db, "match_similar", (METHOD)db_match_similar, -1);
1913
2016
  rb_define_method(cls_db, "merge", (METHOD)db_merge, -1);
1914
2017
  rb_define_method(cls_db, "cursor", (METHOD)db_cursor, 0);
1915
2018
  rb_define_method(cls_db, "cursor_process", (METHOD)db_cursor_process, 0);
@@ -1921,7 +2024,7 @@ static void define_db() {
1921
2024
  rb_define_method(cls_db, "[]=", (METHOD)db_set, 2);
1922
2025
  rb_define_method(cls_db, "store", (METHOD)db_set, 2);
1923
2026
  rb_define_method(cls_db, "delete", (METHOD)db_remove, 1);
1924
- rb_define_method(cls_db, "fetch", (METHOD)db_get, 1);
2027
+ rb_define_method(cls_db, "fetch", (METHOD)db_set, 1);
1925
2028
  rb_define_method(cls_db, "shift", (METHOD)db_shift, 0);
1926
2029
  rb_define_method(cls_db, "length", (METHOD)db_count, 0);
1927
2030
  rb_define_method(cls_db, "each", (METHOD)db_each, 0);
@@ -2487,68 +2590,8 @@ static VALUE db_increment(int argc, VALUE* argv, VALUE vself) {
2487
2590
  vkey = StringValueEx(vkey);
2488
2591
  const char* kbuf = RSTRING_PTR(vkey);
2489
2592
  size_t ksiz = RSTRING_LEN(vkey);
2490
- int64_t num = 0;
2491
- switch (TYPE(vnum)) {
2492
- case T_FIXNUM: {
2493
- num = FIX2INT(vnum);
2494
- break;
2495
- }
2496
- case T_BIGNUM: {
2497
- num = NUM2LL(vnum);
2498
- break;
2499
- }
2500
- case T_FLOAT: {
2501
- num = NUM2DBL(vnum);
2502
- break;
2503
- }
2504
- case T_TRUE: {
2505
- num = 1;
2506
- break;
2507
- }
2508
- case T_STRING: {
2509
- const char* str = RSTRING_PTR(vnum);
2510
- num = kc::atoi(str);
2511
- break;
2512
- }
2513
- }
2514
- int64_t orig = 0;
2515
- switch (TYPE(vorig)) {
2516
- case T_FIXNUM: {
2517
- orig = FIX2INT(vorig);
2518
- break;
2519
- }
2520
- case T_BIGNUM: {
2521
- orig = NUM2LL(vorig);
2522
- break;
2523
- }
2524
- case T_FLOAT: {
2525
- double dnum = NUM2DBL(vorig);
2526
- if (kc::chknan(dnum)) {
2527
- orig = kc::INT64MIN;
2528
- } else if (kc::chkinf(dnum)) {
2529
- orig = dnum < 0 ? kc::INT64MIN : kc::INT64MAX;
2530
- } else {
2531
- orig = dnum;
2532
- }
2533
- break;
2534
- }
2535
- case T_TRUE: {
2536
- orig = 1;
2537
- break;
2538
- }
2539
- case T_STRING: {
2540
- const char* str = RSTRING_PTR(vorig);
2541
- double dnum = kc::atof(str);
2542
- if (kc::chknan(dnum)) {
2543
- orig = kc::INT64MIN;
2544
- } else if (kc::chkinf(dnum)) {
2545
- orig = dnum < 0 ? kc::INT64MIN : kc::INT64MAX;
2546
- } else {
2547
- orig = dnum;
2548
- }
2549
- break;
2550
- }
2551
- }
2593
+ int64_t num = vnum == Qnil ? 0 : vatoi(vnum);
2594
+ int64_t orig = vorig == Qnil ? 0 : vatoi(vorig);
2552
2595
  volatile VALUE vrv;
2553
2596
  volatile VALUE vmutex = rb_ivar_get(vself, id_db_mutex);
2554
2597
  if (vmutex == Qnil) {
@@ -2598,54 +2641,8 @@ static VALUE db_increment_double(int argc, VALUE* argv, VALUE vself) {
2598
2641
  vkey = StringValueEx(vkey);
2599
2642
  const char* kbuf = RSTRING_PTR(vkey);
2600
2643
  size_t ksiz = RSTRING_LEN(vkey);
2601
- double num = 0;
2602
- switch (TYPE(vnum)) {
2603
- case T_FIXNUM: {
2604
- num = FIX2INT(vnum);
2605
- break;
2606
- }
2607
- case T_BIGNUM: {
2608
- num = NUM2LL(vnum);
2609
- break;
2610
- }
2611
- case T_FLOAT: {
2612
- num = NUM2DBL(vnum);
2613
- break;
2614
- }
2615
- case T_TRUE: {
2616
- num = 1;
2617
- break;
2618
- }
2619
- case T_STRING: {
2620
- const char* str = RSTRING_PTR(vnum);
2621
- num = kc::atof(str);
2622
- break;
2623
- }
2624
- }
2625
- double orig = 0;
2626
- switch (TYPE(vorig)) {
2627
- case T_FIXNUM: {
2628
- orig = FIX2INT(vorig);
2629
- break;
2630
- }
2631
- case T_BIGNUM: {
2632
- orig = NUM2LL(vorig);
2633
- break;
2634
- }
2635
- case T_FLOAT: {
2636
- orig = NUM2DBL(vorig);
2637
- break;
2638
- }
2639
- case T_TRUE: {
2640
- orig = 1;
2641
- break;
2642
- }
2643
- case T_STRING: {
2644
- const char* str = RSTRING_PTR(vorig);
2645
- orig = kc::atof(str);
2646
- break;
2647
- }
2648
- }
2644
+ double num = vnum == Qnil ? 0.0 : vatof(vnum);
2645
+ double orig = vorig == Qnil ? 0.0 : vatof(vorig);
2649
2646
  volatile VALUE vrv;
2650
2647
  volatile VALUE vmutex = rb_ivar_get(vself, id_db_mutex);
2651
2648
  if (vmutex == Qnil) {
@@ -3573,30 +3570,7 @@ static VALUE db_match_prefix(int argc, VALUE* argv, VALUE vself) {
3573
3570
  vprefix = StringValueEx(vprefix);
3574
3571
  const char* pbuf = RSTRING_PTR(vprefix);
3575
3572
  size_t psiz = RSTRING_LEN(vprefix);
3576
- int64_t max = -1;
3577
- switch (TYPE(vmax)) {
3578
- case T_FIXNUM: {
3579
- max = FIX2INT(vmax);
3580
- break;
3581
- }
3582
- case T_BIGNUM: {
3583
- max = NUM2LL(vmax);
3584
- break;
3585
- }
3586
- case T_FLOAT: {
3587
- max = NUM2DBL(vmax);
3588
- break;
3589
- }
3590
- case T_TRUE: {
3591
- max = 1;
3592
- break;
3593
- }
3594
- case T_STRING: {
3595
- const char* str = RSTRING_PTR(vmax);
3596
- max = kc::atoi(str);
3597
- break;
3598
- }
3599
- }
3573
+ int64_t max = vmax == Qnil ? -1 : vatoi(vmax);
3600
3574
  volatile VALUE vrv;
3601
3575
  volatile VALUE vmutex = rb_ivar_get(vself, id_db_mutex);
3602
3576
  StringVector keys;
@@ -3649,30 +3623,7 @@ static VALUE db_match_regex(int argc, VALUE* argv, VALUE vself) {
3649
3623
  vregex = StringValueEx(vregex);
3650
3624
  const char* rbuf = RSTRING_PTR(vregex);
3651
3625
  size_t rsiz = RSTRING_LEN(vregex);
3652
- int64_t max = -1;
3653
- switch (TYPE(vmax)) {
3654
- case T_FIXNUM: {
3655
- max = FIX2INT(vmax);
3656
- break;
3657
- }
3658
- case T_BIGNUM: {
3659
- max = NUM2LL(vmax);
3660
- break;
3661
- }
3662
- case T_FLOAT: {
3663
- max = NUM2DBL(vmax);
3664
- break;
3665
- }
3666
- case T_TRUE: {
3667
- max = 1;
3668
- break;
3669
- }
3670
- case T_STRING: {
3671
- const char* str = RSTRING_PTR(vmax);
3672
- max = kc::atoi(str);
3673
- break;
3674
- }
3675
- }
3626
+ int64_t max = vmax == Qnil ? -1 : vatoi(vmax);
3676
3627
  volatile VALUE vrv;
3677
3628
  volatile VALUE vmutex = rb_ivar_get(vself, id_db_mutex);
3678
3629
  StringVector keys;
@@ -3714,6 +3665,64 @@ static VALUE db_match_regex(int argc, VALUE* argv, VALUE vself) {
3714
3665
  }
3715
3666
 
3716
3667
 
3668
+ /**
3669
+ * Implementation of match_similar.
3670
+ */
3671
+ static VALUE db_match_similar(int argc, VALUE* argv, VALUE vself) {
3672
+ kc::PolyDB* db;
3673
+ Data_Get_Struct(vself, kc::PolyDB, db);
3674
+ volatile VALUE vorigin, vrange, vutf, vmax;
3675
+ rb_scan_args(argc, argv, "13", &vorigin, &vrange, &vutf, &vmax);
3676
+ vorigin = StringValueEx(vorigin);
3677
+ const char* obuf = RSTRING_PTR(vorigin);
3678
+ size_t osiz = RSTRING_LEN(vorigin);
3679
+ int64_t range = vrange == Qnil ? 1 : vatoi(vrange);
3680
+ bool utf = vutf != Qnil && vutf != Qfalse;
3681
+ int64_t max = vmax == Qnil ? -1 : vatoi(vmax);
3682
+ volatile VALUE vrv;
3683
+ volatile VALUE vmutex = rb_ivar_get(vself, id_db_mutex);
3684
+ StringVector keys;
3685
+ int64_t rv;
3686
+ if (vmutex == Qnil) {
3687
+ class FuncImpl : public NativeFunction {
3688
+ public:
3689
+ explicit FuncImpl(kc::PolyDB* db, const char* obuf, size_t osiz, int64_t range, bool utf,
3690
+ StringVector* keys, int64_t max) :
3691
+ db_(db), obuf_(obuf), osiz_(osiz), range_(range), utf_(utf),
3692
+ keys_(keys), max_(max), rv_(0) {}
3693
+ int64_t rv() {
3694
+ return rv_;
3695
+ }
3696
+ private:
3697
+ void operate() {
3698
+ rv_ = db_->match_similar(std::string(obuf_, osiz_), range_, utf_, keys_, max_);
3699
+ }
3700
+ kc::PolyDB* db_;
3701
+ const char* obuf_;
3702
+ size_t osiz_;
3703
+ size_t range_;
3704
+ bool utf_;
3705
+ StringVector* keys_;
3706
+ int64_t max_;
3707
+ int64_t rv_;
3708
+ } func(db, obuf, osiz, range, utf, &keys, max);
3709
+ NativeFunction::execute(&func);
3710
+ rv = func.rv();
3711
+ } else {
3712
+ rb_funcall(vmutex, id_mtx_lock, 0);
3713
+ rv = db->match_similar(std::string(obuf, osiz), range, utf, &keys, max);
3714
+ rb_funcall(vmutex, id_mtx_unlock, 0);
3715
+ }
3716
+ if (rv >= 0) {
3717
+ vrv = vectortovarray(vself, &keys);
3718
+ } else {
3719
+ vrv = Qnil;
3720
+ db_raise(vself);
3721
+ }
3722
+ return vrv;
3723
+ }
3724
+
3725
+
3717
3726
  /**
3718
3727
  * Implementation of merge.
3719
3728
  */
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gazay-kyotocabinet-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.28'
4
+ version: '1.29'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-10 00:00:00.000000000 Z
12
+ date: 2012-03-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Kyoto Cabinet is a library of routines for managing a database. The
15
15
  database is a simple data file containing records, each is a pair of a key and a
@@ -24,8 +24,8 @@ extensions:
24
24
  - extconf.rb
25
25
  extra_rdoc_files: []
26
26
  files:
27
- - extconf.rb
28
27
  - kyotocabinet.cc
28
+ - extconf.rb
29
29
  homepage: http://fallabs.com/kyotocabinet/
30
30
  licenses: []
31
31
  post_install_message:
@@ -33,20 +33,20 @@ rdoc_options: []
33
33
  require_paths:
34
34
  - lib
35
35
  required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
36
37
  requirements:
37
38
  - - ! '>='
38
39
  - !ruby/object:Gem::Version
39
40
  version: '0'
40
- none: false
41
41
  required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
42
43
  requirements:
43
44
  - - ! '>='
44
45
  - !ruby/object:Gem::Version
45
46
  version: '0'
46
- none: false
47
47
  requirements: []
48
48
  rubyforge_project: kyotocabinet-ruby
49
- rubygems_version: 1.8.12
49
+ rubygems_version: 1.8.17
50
50
  signing_key:
51
51
  specification_version: 3
52
52
  summary: ! 'Kyoto Cabinet: a straightforward implementation of DBM.'