Skip to content

Commit b3b3185

Browse files
committed
- remove useless heap usage & few tiny optimizations
- update bench info
1 parent eb3ecfc commit b3b3185

File tree

5 files changed

+39
-136
lines changed

5 files changed

+39
-136
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "geoip2"
3-
version = "0.1.7"
3+
version = "0.1.8"
44
authors = ["IncSW <dev@incsw.in>"]
55
description = "Library for reading MaxMind DB format used by GeoIP2 and GeoLite2"
66
readme = "README.md"

README.md

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
[![Downloads](https://img.shields.io/crates/d/geoip2.svg)](https://crates.io/crates/geoip2)
1010

1111
[![crates.io](https://img.shields.io/crates/v/geoip2?label=latest)](https://crates.io/crates/geoip2)
12-
[![Documentation](https://docs.rs/geoip2/badge.svg?version=0.1.7)](https://docs.rs/geoip2/0.1.7)
13-
[![Dependency Status](https://deps.rs/crate/geoip2/0.1.7/status.svg)](https://deps.rs/crate/geoip2/0.1.7)
12+
[![Documentation](https://docs.rs/geoip2/badge.svg?version=0.1.8)](https://docs.rs/geoip2/0.1.8)
13+
[![Dependency Status](https://deps.rs/crate/geoip2/0.1.8/status.svg)](https://deps.rs/crate/geoip2/0.1.8)
1414

1515

1616
</div>
@@ -19,7 +19,7 @@
1919

2020
```toml
2121
[dependencies]
22-
geoip2 = "0.1.7"
22+
geoip2 = "0.1.8"
2323
```
2424

2525
See [examples/lookup.rs](examples/lookup.rs) for a basic example.
@@ -33,30 +33,35 @@ Place `GeoIP2-Country.mmdb` and `GeoIP2-City.mmdb` in the `testdata` folder, the
3333
cargo bench
3434
```
3535

36-
Tested on paid DB on cargo 1.56.0-nightly, Intel i7-7700, Debian 9.1.
36+
Tested on paid DB on cargo 1.95.0-nightly, Ryzen 5 3600, Ubuntu 20.04.3 LTS.
3737

3838
### [IncSW/geoip2-rs](https://github.com/IncSW/geoip2-rs)
3939
`default`
4040
```
41-
city 2,175 ns/iter (+/- 124)
42-
country 1,123 ns/iter (+/- 111)
41+
city 1,782.38 ns/iter (+/- 28.49)
42+
country 908.45 ns/iter (+/- 7.62)
4343
```
4444
`unsafe-str`
4545
```
46-
city 1,113 ns/iter (+/- 76)
47-
country 524 ns/iter (+/- 31)
46+
city 999.06 ns/iter (+/- 8.87)
47+
country 467.06 ns/iter (+/- 5.79)
4848
```
4949

50-
### [oschwald/maxminddb-rust](https://github.com/oschwald/maxminddb-rust).
50+
### [oschwald/maxminddb-rust](https://github.com/oschwald/maxminddb-rust) 0.27.2.
5151
`default`
5252
```
53-
city 4,224 ns/iter (+/- 153)
54-
country 2,270 ns/iter (+/- 158)
53+
city 1,915.71 ns/iter (+/- 29.17)
54+
country 993.89 ns/iter (+/- 47.24)
55+
```
56+
`simdutf8`
57+
```
58+
city 1,870.60 ns/iter (+/- 32.75)
59+
country 960.99 ns/iter (+/- 22.91)
5560
```
5661
`unsafe-str-decode`
5762
```
58-
city 3,266 ns/iter (+/- 191)
59-
country 1,802 ns/iter (+/- 75)
63+
city 1,708.32 ns/iter (+/- 27.23)
64+
country 875.96 ns/iter (+/- 44.86)
6065
```
6166

6267
## License

src/decoder.rs

Lines changed: 6 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub(crate) fn read_bytes<'a>(
3131
Ok(bytes)
3232
}
3333

34-
#[inline]
3534
pub(crate) fn read_control(buffer: &[u8], offset: &mut usize) -> Result<(u8, usize), Error> {
3635
let control_byte = buffer[*offset];
3736
*offset += 1;
@@ -236,116 +235,14 @@ pub(crate) fn read_array<'a>(buffer: &'a [u8], offset: &mut usize) -> Result<Vec
236235
}
237236

238237
pub(crate) fn bytes_to_usize(buffer: &[u8]) -> usize {
239-
match buffer.len() {
240-
1 => buffer[0] as usize,
241-
2 => (buffer[0] as usize) << 8 | (buffer[1] as usize),
242-
3 => ((buffer[0] as usize) << 8 | (buffer[1] as usize)) << 8 | (buffer[2] as usize),
243-
4 => {
244-
(((buffer[0] as usize) << 8 | (buffer[1] as usize)) << 8 | (buffer[2] as usize)) << 8
245-
| (buffer[3] as usize)
246-
}
247-
5 => {
248-
((((buffer[0] as usize) << 8 | (buffer[1] as usize)) << 8 | (buffer[2] as usize)) << 8
249-
| (buffer[3] as usize))
250-
<< 8
251-
| (buffer[4] as usize)
252-
}
253-
6 => {
254-
(((((buffer[0] as usize) << 8 | (buffer[1] as usize)) << 8 | (buffer[2] as usize))
255-
<< 8
256-
| (buffer[3] as usize))
257-
<< 8
258-
| (buffer[4] as usize))
259-
<< 8
260-
| (buffer[5] as usize)
261-
}
262-
7 => {
263-
((((((buffer[0] as usize) << 8 | (buffer[1] as usize)) << 8 | (buffer[2] as usize))
264-
<< 8
265-
| (buffer[3] as usize))
266-
<< 8
267-
| (buffer[4] as usize))
268-
<< 8
269-
| (buffer[5] as usize))
270-
<< 8
271-
| (buffer[6] as usize)
272-
}
273-
8 => {
274-
(((((((buffer[0] as usize) << 8 | (buffer[1] as usize)) << 8 | (buffer[2] as usize))
275-
<< 8
276-
| (buffer[3] as usize))
277-
<< 8
278-
| (buffer[4] as usize))
279-
<< 8
280-
| (buffer[5] as usize))
281-
<< 8
282-
| (buffer[6] as usize))
283-
<< 8
284-
| (buffer[7] as usize)
285-
}
286-
_ => 0,
238+
if buffer.len() > 8 {
239+
return 0;
287240
}
241+
buffer
242+
.iter()
243+
.fold(0usize, |acc, &b| (acc << 8) | (b as usize))
288244
}
289245

290246
fn bytes_to_usize_with_prefix(prefix: usize, buffer: &[u8]) -> usize {
291-
match buffer.len() {
292-
0 => prefix,
293-
1 => prefix << 8 | (buffer[0] as usize),
294-
2 => (prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize),
295-
3 => {
296-
((prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize)) << 8
297-
| (buffer[2] as usize)
298-
}
299-
4 => {
300-
(((prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize)) << 8
301-
| (buffer[2] as usize))
302-
<< 8
303-
| (buffer[3] as usize)
304-
}
305-
5 => {
306-
((((prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize)) << 8
307-
| (buffer[2] as usize))
308-
<< 8
309-
| (buffer[3] as usize))
310-
<< 8
311-
| (buffer[4] as usize)
312-
}
313-
6 => {
314-
(((((prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize)) << 8
315-
| (buffer[2] as usize))
316-
<< 8
317-
| (buffer[3] as usize))
318-
<< 8
319-
| (buffer[4] as usize))
320-
<< 8
321-
| (buffer[5] as usize)
322-
}
323-
7 => {
324-
((((((prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize)) << 8
325-
| (buffer[2] as usize))
326-
<< 8
327-
| (buffer[3] as usize))
328-
<< 8
329-
| (buffer[4] as usize))
330-
<< 8
331-
| (buffer[5] as usize))
332-
<< 8
333-
| (buffer[6] as usize)
334-
}
335-
8 => {
336-
(((((((prefix << 8 | (buffer[0] as usize)) << 8 | (buffer[1] as usize)) << 8
337-
| (buffer[2] as usize))
338-
<< 8
339-
| (buffer[3] as usize))
340-
<< 8
341-
| (buffer[4] as usize))
342-
<< 8
343-
| (buffer[5] as usize))
344-
<< 8
345-
| (buffer[6] as usize))
346-
<< 8
347-
| (buffer[7] as usize)
348-
}
349-
_ => 0,
350-
}
247+
(prefix << (buffer.len() * 8)) | bytes_to_usize(buffer)
351248
}

src/reader.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,13 @@ impl<'a, T> Reader<'a, T> {
6161
Ok(reader)
6262
}
6363

64-
fn find_address_in_tree(&self, ip: &[u8]) -> Result<usize, Error> {
65-
let bit_count = ip.len() * 8;
66-
let mut node: usize = if bit_count == 128 {
67-
0
68-
} else {
69-
self.ip_v4_start
70-
};
64+
fn find_address_in_tree<const N: usize>(
65+
&self,
66+
ip: &[u8; N],
67+
mut node: usize,
68+
) -> Result<usize, Error> {
7169
let node_count = self.metadata.node_count as usize;
72-
for i in 0..bit_count {
70+
for i in 0..(N * 8) {
7371
if node >= node_count {
7472
break;
7573
}
@@ -135,16 +133,19 @@ impl<'a, T> Reader<'a, T> {
135133
}
136134

137135
fn lookup_pointer(&self, address: IpAddr) -> Result<usize, Error> {
138-
let ip_bytes = match address {
139-
IpAddr::V4(ip) => ip.octets().to_vec(),
136+
let pointer = match address {
137+
IpAddr::V4(ip) => {
138+
let octets = ip.octets();
139+
self.find_address_in_tree(&octets, self.ip_v4_start)?
140+
}
140141
IpAddr::V6(ip) => {
141142
if self.metadata.ip_version == 4 {
142143
return Err(Error::IPv4Only);
143144
}
144-
ip.octets().to_vec()
145+
let octets = ip.octets();
146+
self.find_address_in_tree(&octets, 0)?
145147
}
146148
};
147-
let pointer = self.find_address_in_tree(&ip_bytes)?;
148149
if pointer == 0 {
149150
return Err(Error::NotFound);
150151
}

tests/dbip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ mod tests {
6060
let result = reader
6161
.lookup(IpAddr::from_str("66.30.184.198").unwrap())
6262
.unwrap();
63-
assert_eq!(result.autonomous_system_number, Some(7015));
63+
assert_eq!(result.autonomous_system_number, Some(7922));
6464
assert_eq!(
6565
result.autonomous_system_organization,
6666
Some("Comcast Cable Communications, LLC")

0 commit comments

Comments
 (0)