From 0e498e27f885d762031989eb3f70613f21da6795 Mon Sep 17 00:00:00 2001 From: dongyado Date: Wed, 22 Jun 2016 20:00:23 +0800 Subject: [PATCH 01/10] nodejs client init --- binding/nodejs/ip2region.js | 31 +++++++++++++++++++++++++++++++ binding/nodejs/package.json | 24 ++++++++++++++++++++++++ binding/nodejs/test.js | 10 ++++++++++ 3 files changed, 65 insertions(+) create mode 100644 binding/nodejs/ip2region.js create mode 100644 binding/nodejs/package.json create mode 100644 binding/nodejs/test.js diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js new file mode 100644 index 0000000..e909a1f --- /dev/null +++ b/binding/nodejs/ip2region.js @@ -0,0 +1,31 @@ +/** + * ip2region client for nodejs + * + * project: https://github.com/lionsoul2016/ip2region + * + * @author dongyado + * */ + +var ip2r = {}; +ip2r.db_file = null; + + +exports.setDbFile = function(path) +{ + ip2r.db_file = path; +} + +exports.getDbFile = function(path) +{ + return ip2r.db_file; +} + +exports.binarySearch = function(ip) +{ + return ip; +} + +exports.btreeSearch = function(ip) +{ + return ip; +} diff --git a/binding/nodejs/package.json b/binding/nodejs/package.json new file mode 100644 index 0000000..99068c1 --- /dev/null +++ b/binding/nodejs/package.json @@ -0,0 +1,24 @@ +{ + "name": "ip2region", + "version": "0.0.1", + "description": "ip database ", + "main": "ip2region.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/lionsoul2016/ip2region" + }, + "keywords": [ + "ip2region", + "ip", + "region" + ], + "author": "dongyado", + "license": "ISC", + "bugs": { + "url": "https://github.com/lionsoul2016/ip2region/issues" + }, + "homepage": "https://github.com/lionsoul2016/ip2region" +} diff --git a/binding/nodejs/test.js b/binding/nodejs/test.js new file mode 100644 index 0000000..38db36e --- /dev/null +++ b/binding/nodejs/test.js @@ -0,0 +1,10 @@ +/** + * test program + * */ + +var ip2r = require('./ip2region'); + +ip2r.setDbFile('./ip2region.db'); + +console.log(ip2r.getDbFile()); +console.log(ip2r.binarySearch("12321231")); From 2e31e924b5c64686cf8639ec75eea2d6a5f8457b Mon Sep 17 00:00:00 2001 From: dongyado Date: Tue, 28 Jun 2016 09:31:23 +0800 Subject: [PATCH 02/10] update ip2region.js --- binding/nodejs/ip2region.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index e909a1f..de3e9db 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -6,13 +6,16 @@ * @author dongyado * */ +var fs = require('fs'); var ip2r = {}; -ip2r.db_file = null; +ip2r.db_file = null; +ip2r.db_fd = null; exports.setDbFile = function(path) { ip2r.db_file = path; + ip2r.db_fd = fs.open(ip2r.db_file); } exports.getDbFile = function(path) From 0fb5af9067a86f84c74b1999fa425943925cf6b5 Mon Sep 17 00:00:00 2001 From: dongyado Date: Wed, 6 Jul 2016 00:29:19 +0800 Subject: [PATCH 03/10] update nodejs client --- binding/nodejs/ip2region.js | 74 ++++++++++++++++++++++++++----------- binding/nodejs/test.js | 8 ++-- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index de3e9db..4684f3e 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -6,29 +6,59 @@ * @author dongyado * */ -var fs = require('fs'); -var ip2r = {}; -ip2r.db_file = null; -ip2r.db_fd = null; - -exports.setDbFile = function(path) +function Ip2region(db_path) { - ip2r.db_file = path; - ip2r.db_fd = fs.open(ip2r.db_file); + var fs = require('fs'); + var ipbase = [16777216, 65536, 256, 1]; // for ip2long + var ip2r = {}; + ip2r.db_file_path = null; + ip2r.db_fd = null; + + // db file check + if (typeof(db_path) == "undefined" || fs.exists(db_path) ) { + throw("[ip2region] db file not exists : " + db_path); + } + + ip2r.db_file_path = db_path; + + try { + ip2r.db_fd = fs.openSync(ip2r.db_file_path, 'r'); + } catch(e) { + throw("[ip2region] Can not open ip2region.db file , path : " + ip2r.db_file_path); + } + + + this.binarySearch = function(ip) + { + var buffer = new Buffer(8); + fs.readSync(ip2r.db_fd, buffer, 0, 8, 0); + console.log(buffer[0]); + + + + return ip2long(ip); + } + + this.btreeSearch = function(ip) + { + return ip2long(ip); + } + + function ip2long(ip) + { + var val = 0; + ip.split('.').forEach(function(ele, i){ + val += ipbase[i] * ele; + }); + + return val; + } + + function getLong(buffer) + { + + } } -exports.getDbFile = function(path) -{ - return ip2r.db_file; -} - -exports.binarySearch = function(ip) -{ - return ip; -} - -exports.btreeSearch = function(ip) -{ - return ip; -} +module.exports = Ip2region; diff --git a/binding/nodejs/test.js b/binding/nodejs/test.js index 38db36e..7054c58 100644 --- a/binding/nodejs/test.js +++ b/binding/nodejs/test.js @@ -2,9 +2,7 @@ * test program * */ -var ip2r = require('./ip2region'); +var Ip2region = require('./ip2region'); +var ip2region = new Ip2region('../../data/ip2region.db'); -ip2r.setDbFile('./ip2region.db'); - -console.log(ip2r.getDbFile()); -console.log(ip2r.binarySearch("12321231")); +console.log(ip2region.binarySearch("114.114.114.114")); From 0dd1a53d005d515b5275a82c85c1e52e837c0ec1 Mon Sep 17 00:00:00 2001 From: dongyado Date: Wed, 6 Jul 2016 09:28:53 +0800 Subject: [PATCH 04/10] getLong finished for nodejs client --- binding/nodejs/ip2region.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index 4684f3e..de1ce42 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -33,9 +33,9 @@ function Ip2region(db_path) { var buffer = new Buffer(8); fs.readSync(ip2r.db_fd, buffer, 0, 8, 0); - console.log(buffer[0]); - + console.log(getLong(buffer, 0)); + console.log(getLong(buffer, 4)); return ip2long(ip); } @@ -55,9 +55,14 @@ function Ip2region(db_path) return val; } - function getLong(buffer) + function getLong(buffer, offset) { - + return ( + (buffer[offset] & 0x000000FF ) | + ((buffer[offset + 1] << 8) & 0x0000FF00) | + ((buffer[offset + 2] << 16) & 0x00FF0000) | + ((buffer[offset + 3] << 24) & 0xFF000000) + ); } } From 401e5bc79576555cf11fcb201b1f66ccf0c95fcf Mon Sep 17 00:00:00 2001 From: dongyado Date: Wed, 6 Jul 2016 11:27:58 +0800 Subject: [PATCH 05/10] nodejs client forward --- binding/nodejs/ip2region.js | 41 ++++++++++++++++++++++++++----------- binding/nodejs/test.js | 2 +- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index de1ce42..873b06f 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -11,40 +11,53 @@ function Ip2region(db_path) { var fs = require('fs'); var ipbase = [16777216, 65536, 256, 1]; // for ip2long - var ip2r = {}; - ip2r.db_file_path = null; - ip2r.db_fd = null; + var db_file_path = null; + var db_fd = null; // db file check if (typeof(db_path) == "undefined" || fs.exists(db_path) ) { throw("[ip2region] db file not exists : " + db_path); } - ip2r.db_file_path = db_path; + db_file_path = db_path; try { - ip2r.db_fd = fs.openSync(ip2r.db_file_path, 'r'); + db_fd = fs.openSync(db_file_path, 'r'); } catch(e) { - throw("[ip2region] Can not open ip2region.db file , path : " + ip2r.db_file_path); + throw("[ip2region] Can not open ip2region.db file , path : " + db_file_path); } + var totalBlocks = 0; + var firstIndexPtr = 0; + var lastIndexPtr = 0; + var superBlock = new Buffer(8); this.binarySearch = function(ip) { - var buffer = new Buffer(8); - fs.readSync(ip2r.db_fd, buffer, 0, 8, 0); + if (typeof(ip) == 'string') ip = ip2long(ip); - console.log(getLong(buffer, 0)); - console.log(getLong(buffer, 4)); + // init basic search environment + if (totalBlocks == 0) { + fs.readSync(ip2r.db_fd, superBlock, 0, 8, 0); + firstIndexPtr = getLong(superBlock, 0); + lastIndexPtr = getLong(superBlock, 4); + } + + // search return ip2long(ip); } + this.btreeSearch = function(ip) { return ip2long(ip); } + + /** + * convert ip to long (xxx.xxx.xxx.xxx to a integer) + * */ function ip2long(ip) { var val = 0; @@ -55,11 +68,15 @@ function Ip2region(db_path) return val; } + + /** + * get long value from buffer with specified offset + * */ function getLong(buffer, offset) { return ( - (buffer[offset] & 0x000000FF ) | - ((buffer[offset + 1] << 8) & 0x0000FF00) | + (buffer[offset] & 0x000000FF) | + ((buffer[offset + 1] << 8) & 0x0000FF00) | ((buffer[offset + 2] << 16) & 0x00FF0000) | ((buffer[offset + 3] << 24) & 0xFF000000) ); diff --git a/binding/nodejs/test.js b/binding/nodejs/test.js index 7054c58..46643cb 100644 --- a/binding/nodejs/test.js +++ b/binding/nodejs/test.js @@ -5,4 +5,4 @@ var Ip2region = require('./ip2region'); var ip2region = new Ip2region('../../data/ip2region.db'); -console.log(ip2region.binarySearch("114.114.114.114")); +console.log(ip2region.binarySearch("255.255.255.255")); From 63cd3fa085678dce2faf4c892db9b51051c548ce Mon Sep 17 00:00:00 2001 From: dongyado Date: Thu, 7 Jul 2016 00:08:45 +0800 Subject: [PATCH 06/10] nodejs client finish binary search --- binding/nodejs/ip2region.js | 196 ++++++++++++++++++++++++------------ binding/nodejs/test.js | 11 +- 2 files changed, 143 insertions(+), 64 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index 873b06f..10bf3e0 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -1,86 +1,158 @@ /** * ip2region client for nodejs * - * project: https://github.com/lionsoul2016/ip2region + * project: https://github.com/lionsoul2014/ip2region * * @author dongyado * */ +var fs = require('fs'); + +var ipbase = [16777216, 65536, 256, 1]; // for ip2long +var ip2region = {}; +ip2region.db_file_path = null; +ip2region.db_fd = null; + +var totalBlocks = 0; +var firstIndexPtr = 0; +var lastIndexPtr = 0; +var superBlock = new Buffer(8); + +var indexBlockLength = 12; +var totalHeaderLength = 4096; -function Ip2region(db_path) +/** + * binary search + * */ +ip2region.binarySearch = function(ip) { - var fs = require('fs'); - var ipbase = [16777216, 65536, 256, 1]; // for ip2long - var db_file_path = null; - var db_fd = null; + if( typeof(ip) == 'string' ) + ip = ip2long(ip); + + // search + var low = 0; + var mid = 0; + var high = totalBlocks; + var dataPos = 0; + var pos = 0; + var sip = 0; + var eip = 0; + var indexBuffer = new Buffer(12); + + // binary search + while( low <= high ) { + mid = ((low + high) >> 1); + pos = firstIndexPtr + mid * indexBlockLength; + fs.readSync(this.db_fd, indexBuffer, 0, indexBlockLength, pos); + sip = getLong(indexBuffer, 0); + + //console.log( ' sip : ' + sip + ' eip : ' + eip ); + if ( ip < sip) { + high = mid - 1; + } else { + eip = getLong(indexBuffer, 4); + if ( ip > eip ) { + low = mid + 1; + } else { + dataPos = getLong(indexBuffer, 8); + break; + } + } + } + + // read data + if (dataPos == 0) return null; + var dataLen = ((dataPos >> 24) & 0xFF); + var dataPos = (dataPos & 0x00FFFFFF); + var dataBuffer = new Buffer(dataLen); + + fs.readSync(this.db_fd, dataBuffer, 0, dataLen, dataPos); + + var city_id = getLong(dataBuffer, 0); + var data = dataBuffer.toString('utf8', 4, dataLen); + + //console.log(city_id); + //console.log(data); + + return { city: city_id, region: data }; +} + + +/** + * btree search + * */ +ip2region.btreeSearch = function(ip) +{ + return ip2long(ip); +} + + +/** + * convert ip to long (xxx.xxx.xxx.xxx to a integer) + * */ +function ip2long(ip) +{ + var val = 0; + ip.split('.').forEach(function(ele, i){ + val += ipbase[i] * ele; + }); + + return val; +} + + +/** + * get long value from buffer with specified offset + * */ +function getLong(buffer, offset) +{ + var val = ( + (buffer[offset] & 0x000000FF) | + ((buffer[offset + 1] << 8) & 0x0000FF00) | + ((buffer[offset + 2] << 16) & 0x00FF0000) | + ((buffer[offset + 3] << 24) & 0xFF000000) + ); + + // convert to unsigned int + if (val < 0) { + val = val >>> 0; + } + return val; +} + + +// api for create +exports.create = function(db_path) { // db file check if (typeof(db_path) == "undefined" || fs.exists(db_path) ) { throw("[ip2region] db file not exists : " + db_path); } - db_file_path = db_path; + ip2region.db_file_path = db_path; try { - db_fd = fs.openSync(db_file_path, 'r'); + ip2region.db_fd = fs.openSync(ip2region.db_file_path, 'r'); } catch(e) { - throw("[ip2region] Can not open ip2region.db file , path : " + db_file_path); + throw("[ip2region] Can not open ip2region.db file , path : " + + ip2region.db_file_path); } - var totalBlocks = 0; - var firstIndexPtr = 0; - var lastIndexPtr = 0; - var superBlock = new Buffer(8); - - this.binarySearch = function(ip) - { - if (typeof(ip) == 'string') ip = ip2long(ip); - - // init basic search environment - if (totalBlocks == 0) { - fs.readSync(ip2r.db_fd, superBlock, 0, 8, 0); - firstIndexPtr = getLong(superBlock, 0); - lastIndexPtr = getLong(superBlock, 4); - } - - // search - - return ip2long(ip); + // init basic search environment + if (totalBlocks == 0) { + fs.readSync(ip2region.db_fd, superBlock, 0, 8, 0); + firstIndexPtr = getLong(superBlock, 0); + lastIndexPtr = getLong(superBlock, 4); + totalBlocks = (lastIndexPtr - firstIndexPtr) + / indexBlockLength + 1; } - - this.btreeSearch = function(ip) - { - return ip2long(ip); - } - - - /** - * convert ip to long (xxx.xxx.xxx.xxx to a integer) - * */ - function ip2long(ip) - { - var val = 0; - ip.split('.').forEach(function(ele, i){ - val += ipbase[i] * ele; - }); - - return val; - } - - - /** - * get long value from buffer with specified offset - * */ - function getLong(buffer, offset) - { - return ( - (buffer[offset] & 0x000000FF) | - ((buffer[offset + 1] << 8) & 0x0000FF00) | - ((buffer[offset + 2] << 16) & 0x00FF0000) | - ((buffer[offset + 3] << 24) & 0xFF000000) - ); - } + return ip2region; } -module.exports = Ip2region; + +// api for destroy +exports.destroy = function(ip2rObj){ + ip2rObj.db_file_path = null; + fs.closeSync(ip2rObj.db_fd); +} diff --git a/binding/nodejs/test.js b/binding/nodejs/test.js index 46643cb..59ef0c9 100644 --- a/binding/nodejs/test.js +++ b/binding/nodejs/test.js @@ -3,6 +3,13 @@ * */ var Ip2region = require('./ip2region'); -var ip2region = new Ip2region('../../data/ip2region.db'); +//var ip2region = new Ip2region(); -console.log(ip2region.binarySearch("255.255.255.255")); +// 1. create a ip2region object +var ipObj = Ip2region.create('../../data/ip2region.db'); + +// 2. use +console.log(ipObj.binarySearch("120.24.78.68")); + +// 3. destroy +Ip2region.destroy(ipObj); From a2e3bdb13e95e66d5963d05dc883fe8eafb04a99 Mon Sep 17 00:00:00 2001 From: dongyado Date: Thu, 7 Jul 2016 09:21:38 +0800 Subject: [PATCH 07/10] update btree search --- binding/nodejs/ip2region.js | 103 ++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 4 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index 10bf3e0..6789965 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -26,10 +26,6 @@ var totalHeaderLength = 4096; * */ ip2region.binarySearch = function(ip) { - if( typeof(ip) == 'string' ) - ip = ip2long(ip); - - // search var low = 0; var mid = 0; var high = totalBlocks; @@ -39,6 +35,8 @@ ip2region.binarySearch = function(ip) var eip = 0; var indexBuffer = new Buffer(12); + if( typeof(ip) == 'string' ) ip = ip2long(ip); + // binary search while( low <= high ) { mid = ((low + high) >> 1); @@ -78,11 +76,108 @@ ip2region.binarySearch = function(ip) } +var headerSip = null; +var headerPtr = 0; +var headerLen = 0; + + /** * btree search * */ ip2region.btreeSearch = function(ip) { + var indexBlockBuffer = new Buffer(indexBlockLength); + var headerIndexBuffer = new Buffer(totalHeaderLength); + if( typeof(ip) == 'string' ) ip = ip2long($ip); + + var i = 0; + // header index handler + if (headerSip == null) { + fs.readSync(ip2region.db_fd, headerIndexBuffer, 0, totalHeaderLength,8); + headerSip = []; + headerPtr = []; + + var startIp = 0; + var dataPtr = 0; + for ( i = 0; i < totalHeaderLength; i += 8) { + startIp = getLong(headerIndexBuffer, $i); + dataPtr = getLong(headerIndexBuffer, $i + 4); + if ( dataPtr == 0) break; + + headerSip.array_push(startIp); + headerPtr.array_push(dataPtr); + headerLen++; // header index size count + } + } + + // first search (in header index) + var low = 0; + var mid = 0; + var high = headerLen; + var sptr = 0; + var eptr = 0; + + while(low <= high) { + mid = ((low + hign) >> 1); + + if (ip == headerIndex[mid]) { + if ( m > 0) { + sptr = headerPtr[mid - 1]; + eptr = headerPtr[mid]; + } else { + sptr = headerPtr[mid]; + eptr = headerPtr[mid + 1]; + } + break; + } + + if ( ip < headerSip[mid]) { + if (mid == 0) { + sptr = headerPtr[mid]; + eptr = headerPtr[mid + 1]; + break; + } else if ( ip > headerPtr[mid - 1]) { + sptr = headerPtr[mid - 1]; + eptr = headerPtr[mid]; + break; + } + low = mid - 1; + } else { + if ( mid = headerLen - 1) { + sptr = headerPtr[mid - 1]; + eptr = headerPtr[mid]; + break; + } else if ( ip <= headerSip[mid + 1]) { + sptr = headerPtr[mid]; + eptr = headerPtr[mid + 1]; + break; + } + low = mid + 1; + } + } + + // match nothing + if (sptr == 0) return null; + + + // second search (in index) + var blockLen = eptr - sptr; + var blockBuffer = new Buffer(blockLen); + fs.readSync(ip2region.db_fd, blockBuffer, 0, blockLen + indexBlockLength, sptr); + + low = 0; + high = blockLen / indexBlockLength; + + var p = 0; + + var sip = 0; + var eip = 0; + while(low <= high) { + mid = ((low + high) >> 1); + p = mid * indexBlockLength; + + } + return ip2long(ip); } From 3fd756300e97a1ec409345c8c4d7a030f9b50d72 Mon Sep 17 00:00:00 2001 From: dongyado Date: Thu, 7 Jul 2016 10:48:22 +0800 Subject: [PATCH 08/10] nodejs btree search ready for test --- binding/nodejs/ip2region.js | 66 ++++++++++++++++++++++++++----------- binding/nodejs/test.js | 4 +-- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index 6789965..05fbc79 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -88,24 +88,24 @@ ip2region.btreeSearch = function(ip) { var indexBlockBuffer = new Buffer(indexBlockLength); var headerIndexBuffer = new Buffer(totalHeaderLength); - if( typeof(ip) == 'string' ) ip = ip2long($ip); + if( typeof(ip) == 'string' ) ip = ip2long(ip); var i = 0; // header index handler if (headerSip == null) { - fs.readSync(ip2region.db_fd, headerIndexBuffer, 0, totalHeaderLength,8); - headerSip = []; - headerPtr = []; + fs.readSync(this.db_fd, headerIndexBuffer, 0, totalHeaderLength, 8); + headerSip = new Array(); + headerPtr = new Array(); var startIp = 0; var dataPtr = 0; for ( i = 0; i < totalHeaderLength; i += 8) { - startIp = getLong(headerIndexBuffer, $i); - dataPtr = getLong(headerIndexBuffer, $i + 4); + startIp = getLong(headerIndexBuffer, i); + dataPtr = getLong(headerIndexBuffer, i + 4); if ( dataPtr == 0) break; - headerSip.array_push(startIp); - headerPtr.array_push(dataPtr); + headerSip.push(startIp); + headerPtr.push(dataPtr); headerLen++; // header index size count } } @@ -118,9 +118,9 @@ ip2region.btreeSearch = function(ip) var eptr = 0; while(low <= high) { - mid = ((low + hign) >> 1); + mid = ((low + high) >> 1); - if (ip == headerIndex[mid]) { + if (ip == headerSip[mid]) { if ( m > 0) { sptr = headerPtr[mid - 1]; eptr = headerPtr[mid]; @@ -136,14 +136,14 @@ ip2region.btreeSearch = function(ip) sptr = headerPtr[mid]; eptr = headerPtr[mid + 1]; break; - } else if ( ip > headerPtr[mid - 1]) { + } else if ( ip > headerSip[mid - 1]) { sptr = headerPtr[mid - 1]; eptr = headerPtr[mid]; break; } - low = mid - 1; + high = mid - 1; } else { - if ( mid = headerLen - 1) { + if ( mid == headerLen - 1) { sptr = headerPtr[mid - 1]; eptr = headerPtr[mid]; break; @@ -159,26 +159,52 @@ ip2region.btreeSearch = function(ip) // match nothing if (sptr == 0) return null; - // second search (in index) - var blockLen = eptr - sptr; - var blockBuffer = new Buffer(blockLen); - fs.readSync(ip2region.db_fd, blockBuffer, 0, blockLen + indexBlockLength, sptr); + var blockLen = eptr - sptr; + var blockBuffer = new Buffer(blockLen + indexBlockLength); + fs.readSync(this.db_fd, blockBuffer, 0, blockLen + indexBlockLength, sptr); low = 0; high = blockLen / indexBlockLength; var p = 0; - var sip = 0; var eip = 0; + var dataPtr = 0; + while(low <= high) { mid = ((low + high) >> 1); p = mid * indexBlockLength; - + sip = getLong(blockBuffer, p); + + if (ip < sip) { + high = mid - 1; + } else { + eip = getLong(blockBuffer, p + 4); + if (ip > eip) { + low = mid + 1; + } else { + dataPtr = getLong(blockBuffer, p + 8); + break; + } + } } - return ip2long(ip); + // read data + if (dataPtr == 0) return null; + var dataLen = ((dataPtr >> 24) & 0xFF); + var dataPtr = (dataPtr & 0x00FFFFFF); + var dataBuffer = new Buffer(dataLen); + + fs.readSync(this.db_fd, dataBuffer, 0, dataLen, dataPtr); + + var city_id = getLong(dataBuffer, 0); + var data = dataBuffer.toString('utf8', 4, dataLen); + + //console.log(city_id); + //console.log(data); + + return { city: city_id, region: data }; } diff --git a/binding/nodejs/test.js b/binding/nodejs/test.js index 59ef0c9..dcf1b2d 100644 --- a/binding/nodejs/test.js +++ b/binding/nodejs/test.js @@ -3,13 +3,13 @@ * */ var Ip2region = require('./ip2region'); -//var ip2region = new Ip2region(); // 1. create a ip2region object var ipObj = Ip2region.create('../../data/ip2region.db'); // 2. use -console.log(ipObj.binarySearch("120.24.78.68")); +//console.log(ipObj.binarySearch("120.24.78.68")); +console.log(ipObj.btreeSearch("120.24.78.68")); // 3. destroy Ip2region.destroy(ipObj); From 3246dc2df22fe973bc75b2b46172845bfcf36f9c Mon Sep 17 00:00:00 2001 From: dongyado Date: Sat, 16 Jul 2016 15:42:45 +0800 Subject: [PATCH 09/10] update search method name for nodejs client --- binding/nodejs/ip2region.js | 18 ++++++++---------- binding/nodejs/test.js | 4 ++-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/binding/nodejs/ip2region.js b/binding/nodejs/ip2region.js index 05fbc79..3bfbac9 100644 --- a/binding/nodejs/ip2region.js +++ b/binding/nodejs/ip2region.js @@ -22,9 +22,9 @@ var totalHeaderLength = 4096; /** - * binary search + * binary search synchronized * */ -ip2region.binarySearch = function(ip) +ip2region.binarySearchSync = function(ip) { var low = 0; var mid = 0; @@ -82,9 +82,9 @@ var headerLen = 0; /** - * btree search + * btree search synchronized * */ -ip2region.btreeSearch = function(ip) +ip2region.btreeSearchSync = function(ip) { var indexBlockBuffer = new Buffer(indexBlockLength); var headerIndexBuffer = new Buffer(totalHeaderLength); @@ -242,10 +242,8 @@ function getLong(buffer, offset) } -// api for create -exports.create = function(db_path) { - - // db file check +exports.create = function(db_path) +{ if (typeof(db_path) == "undefined" || fs.exists(db_path) ) { throw("[ip2region] db file not exists : " + db_path); } @@ -272,8 +270,8 @@ exports.create = function(db_path) { } -// api for destroy -exports.destroy = function(ip2rObj){ +exports.destroy = function(ip2rObj) +{ ip2rObj.db_file_path = null; fs.closeSync(ip2rObj.db_fd); } diff --git a/binding/nodejs/test.js b/binding/nodejs/test.js index dcf1b2d..ec43d0b 100644 --- a/binding/nodejs/test.js +++ b/binding/nodejs/test.js @@ -8,8 +8,8 @@ var Ip2region = require('./ip2region'); var ipObj = Ip2region.create('../../data/ip2region.db'); // 2. use -//console.log(ipObj.binarySearch("120.24.78.68")); -console.log(ipObj.btreeSearch("120.24.78.68")); +//console.log(ipObj.binarySearchSync("120.24.78.68")); +console.log(ipObj.btreeSearchSync("120.24.78.68")); // 3. destroy Ip2region.destroy(ipObj); From 09797dfb5b09ade1ba7d163b185b3680b363b0d8 Mon Sep 17 00:00:00 2001 From: dongyado Date: Sun, 31 Jul 2016 20:46:44 +0800 Subject: [PATCH 10/10] nodejs client ready --- README.md | 2 +- binding/nodejs/README.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 binding/nodejs/README.md diff --git a/README.md b/README.md index e7155d6..a0d5e30 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ ip2region - 最自由的ip地址查询库,ip到地区的映射库,提供Bina **4. 多查询客户端的支持,0.0x毫秒级别的查询** -已经集成的客户端有:java, php, c, python,php扩展(支持linux, php5, php7版本已支持)。 +已经集成的客户端有:java, php, c, python,nodejs,php扩展(支持linux, php5, php7版本已支持)。 提供了两种查询算法,响应时间如下: 客户端/binary算法/b-tree算法/Memory算法: diff --git a/binding/nodejs/README.md b/binding/nodejs/README.md new file mode 100644 index 0000000..4d09712 --- /dev/null +++ b/binding/nodejs/README.md @@ -0,0 +1,3 @@ +# nodejs 客户端 + +现已实现同步查询,异步查询未实现,用法参考 test.js