Permalink
Browse files

major bugfix, performance improvements

  • Loading branch information...
1 parent 48c4dcd commit 75468e181286d93f771a9a313d43549b530c87c2 @runk committed Apr 1, 2013
Showing with 38 additions and 28 deletions.
  1. +3 −3 README.md
  2. +3 −0 lib/dyn_buffer.js
  3. +14 −21 lib/lookup_service.js
  4. +2 −2 package.json
  5. +16 −2 test/lookup_service_test.js
View
@@ -2,7 +2,7 @@
node-maxmind
========
-IP geo lookup using Maxmind databases, written in pure javascript.
+IP geo lookup using Maxmind databases, written in pure javascript with no dependencies.
## GEO databases
@@ -60,8 +60,8 @@ Caching could significantly increase performance, refer to this camparison which
laptop:
- default: 18,000 lookups / second
-- `indexCache`: 60,000 lookups / second
-- `memodyCache`: 100,000 lookups / second
+- `indexCache`: 80,000 lookups / second
+- `memodyCache`: 130,000 lookups / second
## Tests
View
@@ -12,6 +12,9 @@ DynBuffer.prototype.toString = function(encoding, start, end) {
DynBuffer.prototype.readUInt8 = function(start) {
return this.source.readUInt8(this.offset + start);
};
+DynBuffer.prototype.pointer = function(start) {
+ return this.offset + start;
+};
DynBuffer.prototype.at = function(start) {
return this.source[this.offset + start];
};
View
@@ -1,6 +1,5 @@
-var bignum = require('bignum'),
- Buff = require('./buff'),
+var Buff = require('./buff'),
DatabaseInfo = require('./database_info'),
Country = require('./country'),
Location = require('./location'),
@@ -350,41 +349,35 @@ module.exports.seekCountry = function(ipAddress) {
x1 = cache[1];
} else {
+ // read from memory
if ((dboptions & GEOIP_MEMORY_CACHE) != 0) {
- //read from memory
- dbbuffer.copy(buf, 0, 2 * recordLength * offset, (2 * recordLength * offset) + (2 * MAX_RECORD_LENGTH));
+ buf = new DynBuffer(dbbuffer, 2 * recordLength * offset, 2 * MAX_RECORD_LENGTH);
+ // read from index cache
} else if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
- //read from index cache
- index_cache.copy(buf, 0, 2 * recordLength * offset, (2 * recordLength * offset) + (2 * MAX_RECORD_LENGTH));
+ buf = new DynBuffer(index_cache, 2 * recordLength * offset, 2 * MAX_RECORD_LENGTH);
+ // read from disk
} else {
- //read from disk
- try {
- file.seek(2 * recordLength * offset);
- file.readFully(buf);
- } catch (e) {
- console.log("IO Exception");
- }
+ buf = new DynBuffer(new Buffer(2 * MAX_RECORD_LENGTH), 0, 2 * MAX_RECORD_LENGTH);
+ file.seek(2 * recordLength * offset);
+ file.readFully(buf.source);
}
- x0 = 0;
- x1 = 0;
+ x0 = 0, x1 = 0;
+
for (var j = 0; j<recordLength; j++) {
- y = buf[0*recordLength+j];
- // y = dbbuffer[(2 * recordLength * offset) + (0*recordLength+j)]
+ y = buf.at(0*recordLength+j);
x0 += (y << (j * 8));
- y = buf[1*recordLength+j];
- // y = dbbuffer[(2 * recordLength * offset) + (1*recordLength+j)]
+ y = buf.at(1*recordLength+j);
x1 += (y << (j * 8));
}
}
// unfortunately we cannot perform bitwise operations
// on integers lager than max 2^32
- if ((ipAddress & (1 << depth)) > 0) {
- // if (bignum(ipAddress).and(bignum(1).shiftLeft(depth)).toNumber() > 0) {
+ if (Math.abs(ipAddress & (1 << depth)) > 0) {
if (x1 >= databaseSegment) {
last_netmask = 32 - depth;
return x1;
View
@@ -1,12 +1,12 @@
{
"name": "maxmind",
- "version": "0.1.0",
+ "version": "0.1.1",
"homepage": "https://github.com/runk/node-maxmind",
"description": "IP lookup using Maxmind databases",
"keywords": ["maxmind", "geo", "geobase", "geo lookup", "ip base", "geocode", "timezone"],
"author": "Shirokov Dmitry <deadrunk@gmail.com>",
"dependencies": {
- "bignum": "0.5.4"
+
},
"repository": {
"type":"git",
@@ -74,6 +74,10 @@ describe('lib/lookup_service', function() {
var c = ls.getCountry('210.250.100.200');
assert.equal(c.getName(), 'Japan');
assert.equal(c.getCode(), 'JP');
+
+ var c = ls.getCountry('1.2.1.1');
+ assert.equal(c.getName(), 'China');
+ assert.equal(c.getCode(), 'CN');
});
it('should return unknown country by unknown ip', function() {
@@ -127,8 +131,18 @@ describe('lib/lookup_service', function() {
assert.equal(l.area_code, 0);
});
-
- // #<struct GeoIP::City request="195.68.137.18", ip="195.68.137.18", country_code2="RU", country_code3="RUS", country_name="Russian Federation", continent_code="AS", region_name="47", city_name="Marfino", postal_code="", latitude=55.70269999999999, longitude=37.38319999999999, dma_code=nil, area_code=nil, timezone="Europe/Moscow">
+ it('should return location by ip (3)', function() {
+ var l = ls.getLocation('2.2.3.29');
+ assert.equal(l.countryCode, 'FR');
+ assert.equal(l.countryName, 'France');
+ assert.equal(l.region, 'A2');
+ assert.equal(l.city, 'Rennes');
+ assert.equal(l.latitude, 48.111999999999995);
+ assert.equal(l.longitude, -1.6742999999999881);
+ assert.equal(l.metro_code, 0);
+ assert.equal(l.dma_code, 0);
+ assert.equal(l.area_code, 0);
+ });
});
});

0 comments on commit 75468e1

Please sign in to comment.