From 1575e581cd0d46ffec648367661dc411d32609f7 Mon Sep 17 00:00:00 2001 From: lion Date: Wed, 17 Sep 2025 14:43:28 +0800 Subject: [PATCH] try to apply the bytes_ip_t for the search --- binding/c/main.c | 7 +-- binding/c/test_util | Bin 22104 -> 22336 bytes binding/c/test_util.c | 4 +- binding/c/xdb_api.h | 37 +++++++++++--- binding/c/xdb_searcher.c | 102 +++++++++++++++++++++++++-------------- binding/c/xdb_util.c | 20 ++++++++ 6 files changed, 122 insertions(+), 48 deletions(-) diff --git a/binding/c/main.c b/binding/c/main.c index 9270260..ad11cf7 100644 --- a/binding/c/main.c +++ b/binding/c/main.c @@ -18,11 +18,12 @@ typedef struct searcher_test_entry searcher_test_t; int init_searcher_test(searcher_test_t *test, char *db_path, char *cache_policy) { int err; + xdb_ip_version_t *version = XDB_IPv4; test->v_index = NULL; test->c_buffer = NULL; if (strcmp(cache_policy, "file") == 0) { - err = xdb_new_with_file_only(&test->searcher, db_path); + err = xdb_new_with_file_only(version, &test->searcher, db_path); if (err != 0) { printf("failed to create searcher with errcode=%d\n", err); return 1; @@ -34,7 +35,7 @@ int init_searcher_test(searcher_test_t *test, char *db_path, char *cache_policy) return 2; } - err = xdb_new_with_vector_index(&test->searcher, db_path, test->v_index); + err = xdb_new_with_vector_index(version, &test->searcher, db_path, test->v_index); if (err != 0) { printf("failed to create vector index cached searcher with errcode=%d\n", err); return 3; @@ -46,7 +47,7 @@ int init_searcher_test(searcher_test_t *test, char *db_path, char *cache_policy) return 4; } - err = xdb_new_with_buffer(&test->searcher, test->c_buffer); + err = xdb_new_with_buffer(version, &test->searcher, test->c_buffer); if (err != 0) { printf("failed to create content cached searcher with errcode=%d\n", err); return 5; diff --git a/binding/c/test_util b/binding/c/test_util index 43fd7331bebd4a2b57b66620538a89fc722cf8d6..1b0c79fcf76d521810a14773186ac5b6db7aa120 100755 GIT binary patch delta 3664 zcmZWr3s6+o89rxaVb>w-t_$8>5OxVvP#R>7fJBf*Q5HjV)et)gso*H%I@E0ABk3cB zM4WVsRL!4uNGEl$lRDb5DRiBY+C0EV)i!moZAOi+^-+U5)wR(EI<~jpx%b?t+cUHG zJLmuY$2tFh9(#H(AAFy0D>V5RZJ)Z!8XwQJ7T12xH zj%VrG@dh0&INe-WRl-*B0u!EAdC$Pt<1*|t)xA7*hr)axH;c?ny@k}iY zKI+$5qK^X!a#u<8pd~HkxAqnjpGqqxEKSrY%0FVbTjJv<^by5)6cb>nnvA6h5LI*|R4974zIYXxscJEwgR;mOyv*Z0I+1 zugniNbhqV)8@fx^lA5ioo;-&2ZaQKKL_T{aGEy5EYl!?yODjro;0thFFOCK_pItxe zfH-jtk!z^Ui0?~Pt%)4nG^%dsharkr0`I;-;Yc$cX@6k4;Rsw+(+_e=OFxDW!}$}? zxcR}zu77HotYzAk(z5g^v>s&XJdNb!xBm<>vCv~!`3~6^Y5KM3BOx+D=Dip{NE;Fo z)fEnXm8wBl{ZtnY31Oiy6+)6iF-9uQKa#FyLO@-f@u@1RhggTfZKR!^jMQXob_k9@ zkVgkSv-w`)UME*5!&}5Fsm5E-o<6Fo4UtPolD6)e2qKmK#jb7F)pxY?T97rno?^(6 z;#(rcXR(=NiZ|&gUZYtFWj)1HbaPQ1EydT7$v{_U{s5e;3=}1Ot&lPL-0Sg`z|hG0 zXK_`%{w-CUETkNBS!8=aehBjBFGk9u<+*#(-YRig>w_C-Fnr3Q6G~2SoYUwzUyrF> zT%CD{(t8$18U4OlfOYz7_%hJmMr9`G)Z#Z=V- z?_S^};4rX6j4!Eb5Xdg8>K0%a*k@wxEQZeCAn3TFs-wVRpdGiq_o}KE0>i*c@e2H1 zRaXQ3z_)?Tz}>(YFb4EqQ`OWY@IWsx25bg;KSw}d5V#xI4Ez8X1`a2Apoq?W2>c_M zF;?0OtOSN{z>r=qEpWS#gUOfyt4$GAW%>BwvSfZ50$Yg8X<|X4VI#5i_<4z!DN}l2 znAHjO{}~Vd>=Vxmh(~Y1r(l{l#z-;8akEGxepx|MP^p> zSLyi7qIp}uYgt^JX5VBA9zu96ekY383occ6ugQ8Kd-oxknA2X!ddN{xkbD}wbC+p$ zMW%Ta-AVLfMV8rx5;oCm6;CIxM(^BJI#ID8c|deeMRT57W1`_o`+}`LJ&5rapjVEK zM}NN@8_)c4IW`{lQ-*yG^_wP=zp9WoQK;%74^#bY506o3_DkGGL*tiGNp+0&o9v~S zf!2(7UX0VEOhB^iyGrzq*d&wTp(twi+d1l%Tk}e0T*fu_*?A~&mdU(9`jvmO^_DhF zXYbPSngV{G?$ju5vp9^*$&CL>VkDZ2a_1<#m=@3RIAZdjkdgXENEKfzEGM80!wKvw zQZ61Y(az|=I)#;cr)1-JUPWuuf%Q{A;vFT2S#gg;wY-=%3rbSL72$#3)%+x5+t{Jg zk)ZP!?VPLBd%=piH7mO5cIm+<3(7q435-+V}f(a<1a;mYT-a zFy_BQ=(zVwHYnE~kbVx4uU2t?Dp_Nj{1Lej?FzNjD!!YNjmcBIPA3^hHpEI3vyn!N z=PB-7uwtdX;yyt$jyozhPvL&LgSd;J<1l41OG2)iC>I{q3Kl+CiSEJJiLVI{K9c?i zF#*wjt^<2d%Huh@U=3z3+CI(dC|EnoVn0lXm?EuW2q&6$(1D+5Yq=n;5^H*c9P<@^ zTj;b{Fg>x}ptupyv}+1DNy?2QX;iRS%A4gbt=6m8NF(dk9{R(rmXJNAm7uQ&Dnl)_IV}_%? z#dX}2X`}BhDYhC%s)_oS)bVy2TQbdITq*|UQ^nG0j@_lYy@8|A?<{Q>S6Icf9&$C> ytwwG-$k$j6`L`RZGy43x(Woqx*me`?NMn(8w>)HF8fz>c?~*Ai;B;VN&i?==#J@2B delta 3400 zcmZ`+4NR2h9e>{wGg$3JZGHE9p7(j@WZRS6 z`+J`M=kxsj&j&<)DUTeLd-DyO*7rU2zA2I@@fPX(tkC37)dqe_l?zRqglZG{G4jsQ zbUxZE-*vPu(?+u~UDo93bjWZc{gqRJQ}=g#`clWQo%MyaKb&wUWT%Ap)&yXaDa z#Tw1ltfvDS8a0sKA=zlLdKZY{y2rK0$PH~sXq8#o)6@*Dl%x6BXK61|pV1;mX~1X; z&lrsf{YkE0Da{7iPFv^KT3&TXQtbVQs`?RI#?*KqIPUB5bkX_w&zkO)Ns_N8{>w62 zkd|kgw|~H zO1I6q_gUyq(h%B=srrIveO-|~dEJWc>d)k^hjrIQuxe{D+d4TV@ReZ@yL?APPJ+6n zWr?oW6MUB?IQ~BqRB8!U=?N~d2)aMw-@{sCd-V86n0Ddg2`V@GdgghNp|Y{XXMTMM zqxf_x%~>dC)0P~o&kR+IdDjqAM#1_`L^P*XIgQ+!eMaCi2q~=2z~JtD%^>UF2BR>z zOs8^IJb4@Q?24GX{=k{tt6^1bSNAf;p2=nGz5 z7mQT}?*)SY zp2x~hh(4p~EbD_1K~Ve|j33bkLM~_qXPJ;w6@k}LO*q7a`OK9G2ZWG~L1lbMgerl6 zj@S~D&DfyGbq>1yG-S(2&eR0M5G%Lo@UL#mjG>Rby#Wxwn53rd8#T^>O?c9qQYZUu6cUB!vv58aO={$)b z+k6Fa-_DmLN^scR)o|2Vzdx<2ldq}lWPx(bWxM&2@;a1LhhvT5jgEno{v><9D=nPk zx+sUI-3JV9?4rYMAq`%`w9$|JSyfwsQQ$s?*H!fw@siZ~7gcp(+;l@#L%>$x31B<$ zJhKB%0F_ZyodLRl$+!bXfp(y4OjW%=Wn5K%3~UF63{smkjm|j;djG1bG2kdr!X53J zP}MA8JMd|s@;Po8U>&d%*a|!doCZdLt}j&eYo-S(agYP+fUdtGA+QN}5EuoXWAYd# z90#6y(TT$foBpn<4fLKT&su^tKM78xssvU$$%)@G{F-PCS|6C=Vx~gFc9Hhr=Ossx zWzk9aCNMD?vkKvN0x~4vEsKru8>HrqR_l zC@BlF01X!x$b)pNxFF*k^thCGV=M23K1%MAVnfzA?JRjJ<7re)H^37jeGP*W8Yrod z57J~wLC#U=IfeBpN{6BDEOJXM5vyE;o-fT?Gl*UsYW*BbvW8i`mY8B(pHv4^wnSFb zs{f;B&+Ihxoitqf>|8IZ8TUD5E?+yh7hUH_xMlfHLw}NwqGih3E;mbnc;bzIM~wAX z`Is2%@9=3c)?eO>x_>TxV8|qIdA?jmJIZg!Uh=QBfv+7a-;n3gt;CJwsu&Hodlgw$ zsIT$|rcvRkkfYLOx{f)>*enfHzbel^#Yb6^SG?KVT7*6k=pmCEQl&D-#(~sO?A=fMVd(4luK_QJE^02m-*|-ltt4P^W)~tG57PA?}d(E28+9B?BM0m}v z;)f!aS9l%LoTZPMm;Z{;*0CE4jb9_cNg>zIi(bVCLf#}QSHZm`DU&K|EY>_6OkR7z zfPU$f((W2dyq{?~Uz_PYSpP^^M+8y&&h4g4H5Sj$gjSk0v*VDb8vc8?egrwMM$Q%C z84{lQ6&Qp3TRi_9YW7*ICTtyEFOgqg%R=h&eMLX@Kc}>OfBSZCO~Aiu^~=vJd1i?x zoV#{weE27|uNZJ6jMd}c43oBgZ`k^s8rg6^g|=>3V$zR986DbCBfmjo8wykPqpo8* zIT{L6_jxpb9i!pqhBkJyjMduu8x@mYOognC6%aq)SdroNYCePF0b+Y7gN`*8n5Jtq TO*xG<7Mm7}ODB&U^|pTjruc*r diff --git a/binding/c/test_util.c b/binding/c/test_util.c index 190382c..0d56c7f 100644 --- a/binding/c/test_util.c +++ b/binding/c/test_util.c @@ -68,8 +68,8 @@ void test_parse_ip() { }; int errcode; - bytes_ip_t ip_bytes[17] = {'\0'}; - string_ip_t ip_string[INET6_ADDRSTRLEN + 1] = {'\0'}; + bytes_ip_t ip_bytes[16] = {'\0'}; + string_ip_t ip_string[INET6_ADDRSTRLEN] = {'\0'}; // init the sock env (for windows) if ((errcode = xdb_init_winsock()) != 0) { diff --git a/binding/c/xdb_api.h b/binding/c/xdb_api.h index 244f1c5..5763e2e 100644 --- a/binding/c/xdb_api.h +++ b/binding/c/xdb_api.h @@ -46,9 +46,6 @@ #define xdb_ipv6_version_no 6 #define xdb_ipv4_bytes 4 #define xdb_ipv6_bytes 16 -#define XDB_IPV4 4 -#define XDB_IPv6 6 - // cache of vector_index_row × vector_index_rows × vector_index_size #define xdb_vector_index_length 524288 @@ -108,6 +105,26 @@ XDB_PUBLIC(int) xdb_ip_sub_compare(const bytes_ip_t *, size_t, const char *, int // --- END xdb utils +// --- ip version +#define XDB_IPv4 (xdb_version_ipv4()) +#define XDB_IPv6 (xdb_version_ipv6()) +typedef int (* ip_compare_fn_t) (const bytes_ip_t *, size_t, const char *, int); +struct xdb_ip_version_entry { + int id; // version id + char *name; // version name + int bytes; // ip bytes number + int segment_index_size; // segment index size in bytes + + // function to compare two ips + ip_compare_fn_t ip_compare; +}; +typedef struct xdb_ip_version_entry xdb_ip_version_t; + +XDB_PUBLIC(xdb_ip_version_t *) xdb_version_ipv4(); +XDB_PUBLIC(xdb_ip_version_t *) xdb_version_ipv6(); + +// --- END ip version + // --- xdb buffer functions @@ -170,6 +187,10 @@ XDB_PUBLIC(void) xdb_free_content(void *); // xdb searcher structure struct xdb_searcher_entry { + // ip version + xdb_ip_version_t *version; + + // xdb file handle FILE *handle; // header info @@ -188,18 +209,20 @@ struct xdb_searcher_entry { typedef struct xdb_searcher_entry xdb_searcher_t; // xdb searcher new api define -XDB_PUBLIC(int) xdb_new_with_file_only(xdb_searcher_t *, const char *); +XDB_PUBLIC(int) xdb_new_with_file_only(xdb_ip_version_t *, xdb_searcher_t *, const char *); -XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_searcher_t *, const char *, const xdb_vector_index_t *); +XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_ip_version_t *, xdb_searcher_t *, const char *, const xdb_vector_index_t *); -XDB_PUBLIC(int) xdb_new_with_buffer(xdb_searcher_t *, const xdb_content_t *); +XDB_PUBLIC(int) xdb_new_with_buffer(xdb_ip_version_t *, xdb_searcher_t *, const xdb_content_t *); XDB_PUBLIC(void) xdb_close(void *); // xdb searcher search api define XDB_PUBLIC(int) xdb_search_by_string(xdb_searcher_t *, const char *, char *, size_t); -XDB_PUBLIC(int) xdb_search(xdb_searcher_t *, unsigned int, char *, size_t); +XDB_PUBLIC(int) xdb_search(xdb_searcher_t *, const bytes_ip_t *, int, char *, size_t); + +XDB_PUBLIC(xdb_ip_version_t *) xdb_get_ip_version(xdb_searcher_t *); XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *); diff --git a/binding/c/xdb_searcher.c b/binding/c/xdb_searcher.c index b372e87..eff9075 100644 --- a/binding/c/xdb_searcher.c +++ b/binding/c/xdb_searcher.c @@ -11,9 +11,12 @@ // internal function prototype define XDB_PRIVATE(int) read(xdb_searcher_t *, long offset, char *, size_t length); -XDB_PRIVATE(int) xdb_new_base(xdb_searcher_t *xdb, const char *db_path, const xdb_vector_index_t *v_index, const xdb_content_t *c_buffer) { +XDB_PRIVATE(int) xdb_new_base(xdb_ip_version_t *version, xdb_searcher_t *xdb, const char *db_path, const xdb_vector_index_t *v_index, const xdb_content_t *c_buffer) { memset(xdb, 0x00, sizeof(xdb_searcher_t)); + // set the version + xdb->version = version; + // check the content buffer first if (c_buffer != NULL) { xdb->v_index = NULL; @@ -34,16 +37,16 @@ XDB_PRIVATE(int) xdb_new_base(xdb_searcher_t *xdb, const char *db_path, const xd } // xdb searcher new api define -XDB_PUBLIC(int) xdb_new_with_file_only(xdb_searcher_t *xdb, const char *db_path) { - return xdb_new_base(xdb, db_path, NULL, NULL); +XDB_PUBLIC(int) xdb_new_with_file_only(xdb_ip_version_t *version, xdb_searcher_t *xdb, const char *db_path) { + return xdb_new_base(version, xdb, db_path, NULL, NULL); } -XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_searcher_t *xdb, const char *db_path, const xdb_vector_index_t *v_index) { - return xdb_new_base(xdb, db_path, v_index, NULL); +XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_ip_version_t *version, xdb_searcher_t *xdb, const char *db_path, const xdb_vector_index_t *v_index) { + return xdb_new_base(version, xdb, db_path, v_index, NULL); } -XDB_PUBLIC(int) xdb_new_with_buffer(xdb_searcher_t *xdb, const xdb_content_t *c_buffer) { - return xdb_new_base(xdb, NULL, NULL, c_buffer); +XDB_PUBLIC(int) xdb_new_with_buffer(xdb_ip_version_t *version, xdb_searcher_t *xdb, const xdb_content_t *c_buffer) { + return xdb_new_base(version, xdb, NULL, NULL, c_buffer); } XDB_PUBLIC(void) xdb_close(void *ptr) { @@ -56,27 +59,38 @@ XDB_PUBLIC(void) xdb_close(void *ptr) { // --- xdb searcher search api define -XDB_PUBLIC(int) xdb_search_by_string(xdb_searcher_t *xdb, const char *str_ip, char *region_buffer, size_t length) { - unsigned int ip = 0; - int errcode = xdb_check_ip(str_ip, &ip); - if (errcode != 0) { - return 10 + errcode; +XDB_PUBLIC(int) xdb_search_by_string(xdb_searcher_t *xdb, const char *ip_string, char *region_buffer, size_t length) { + bytes_ip_t ip_bytes[16] = {'\0'}; + int versionNo = xdb_parse_ip(ip_string, ip_bytes, sizeof(ip_bytes)); + if (versionNo == -1) { + return 10; } else { - return xdb_search(xdb, ip, region_buffer, length); + return xdb_search(xdb, ip_bytes, versionNo, region_buffer, length); } } -XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_buffer, size_t length) { - int il0, il1, idx, err, l, h, m, data_len; +XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, const bytes_ip_t *ip_bytes, int byte_count, char *region_buffer, size_t length) { + int il0, il1, idx, err, data_len, bytes, d_bytes; + register int seg_index_size, l, h, m; unsigned int s_ptr, e_ptr, p, sip, eip, data_ptr; - char vector_buffer[xdb_vector_index_size], segment_buffer[xdb_segment_index_size]; + char vector_buffer[xdb_vector_index_size]; + char *segment_buffer = NULL; - // reset the io counter + // ip version check + if (byte_count != xdb->version->bytes) { + return -1; + } + + // some resets + err = 0; + data_len = 0; + bytes = byte_count; + d_bytes = byte_count << 1; xdb->io_count = 0; // locate the segment index block based on the vector index - il0 = ((int) (ip >> 24)) & 0xFF; - il1 = ((int) (ip >> 16)) & 0xFF; + il0 = (int) (ip_bytes[0]); + il1 = (int) (ip_bytes[1]); idx = il0 * xdb_vector_index_cols * xdb_vector_index_size + il1 * xdb_vector_index_size; if (xdb->v_index != NULL) { s_ptr = xdb_le_get_uint32(xdb->v_index->buffer, idx); @@ -96,53 +110,65 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu // printf("s_ptr=%u, e_ptr=%u\n", s_ptr, e_ptr); // binary search to get the final region info + seg_index_size = xdb->version->segment_index_size; + segment_buffer = xdb_malloc(seg_index_size); + if (segment_buffer == NULL) { + return -2; + } + data_len = 0, data_ptr = 0; - l = 0, h = ((int) (e_ptr - s_ptr)) / xdb_segment_index_size; + l = 0, h = ((int) (e_ptr - s_ptr)) / seg_index_size; while (l <= h) { m = (l + h) >> 1; - p = s_ptr + m * xdb_segment_index_size; + p = s_ptr + m * seg_index_size; // read the segment index item err = read(xdb, p, segment_buffer, sizeof(segment_buffer)); if (err != 0) { - return 20 + err; + err += 20; + goto done; } // decode the data fields as needed sip = xdb_le_get_uint32(segment_buffer, 0); - if (ip < sip) { + if (xdb_ip_sub_compare(ip_bytes, byte_count, segment_buffer, 0) < 0) { h = m - 1; + } else if (xdb_ip_sub_compare(ip_bytes, byte_count, segment_buffer, bytes) > 0) { + l = m + 1; } else { - eip = xdb_le_get_uint32(segment_buffer, 4); - if (ip > eip) { - l = m + 1; - } else { - data_len = xdb_le_get_uint16(segment_buffer, 8); - data_ptr = xdb_le_get_uint32(segment_buffer, 10); - break; - } + data_len = xdb_le_get_uint16(segment_buffer, d_bytes); + data_ptr = xdb_le_get_uint32(segment_buffer, d_bytes + 2); + break; } } // printf("data_len=%u, data_ptr=%u\n", data_len, data_ptr); if (data_len == 0) { - region_buffer[0] = '\0'; - return 0; + goto done; } // buffer length checking if (data_len >= (int) length) { - return 1; + err = 1; + goto done; } err = read(xdb, data_ptr, region_buffer, data_len); if (err != 0) { - return 30 + err; + err += 30; + goto done; + } + +done: + // checn and free the segment buffer + if (segment_buffer != NULL) { + xdb_free(segment_buffer); + segment_buffer = NULL; } // auto append a NULL-end region_buffer[data_len] = '\0'; - return 0; + return err; } XDB_PRIVATE(int) read(xdb_searcher_t *xdb, long offset, char *buffer, size_t length) { @@ -165,6 +191,10 @@ XDB_PRIVATE(int) read(xdb_searcher_t *xdb, long offset, char *buffer, size_t len return 0; } +XDB_PUBLIC(xdb_ip_version_t *) xdb_get_ip_version(xdb_searcher_t *xdb) { + return xdb->version; +} + XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *xdb) { return xdb->io_count; } diff --git a/binding/c/xdb_util.c b/binding/c/xdb_util.c index 0f48b42..343f25e 100644 --- a/binding/c/xdb_util.c +++ b/binding/c/xdb_util.c @@ -389,3 +389,23 @@ XDB_PUBLIC(void) xdb_free_content(void *ptr) { } // --- End + +// --- ip version +static xdb_ip_version_t _ip_version_list[] = { + // 14 = 4 + 4 + 2 + 4 + {xdb_ipv4_version_no, "IPv4", xdb_ipv4_bytes, 14, NULL}, + + // 38 = 16 + 16 + 2 + 4 + {xdb_ipv6_version_no, "IPv6", xdb_ipv6_bytes, 38, NULL}, + + // END + {0, NULL, 0, 0, NULL} +}; + +XDB_PUBLIC(xdb_ip_version_t *) xdb_version_ipv4() { + return &_ip_version_list[0]; +} + +XDB_PUBLIC(xdb_ip_version_t *) xdb_version_ipv6() { + return &_ip_version_list[1]; +} \ No newline at end of file