Class: Ip2region::XdbSearcher
- Inherits:
-
Object
- Object
- Ip2region::XdbSearcher
- Includes:
- Singleton
- Defined in:
- lib/ip2region/xdb_searcher.rb
Constant Summary collapse
- HeaderInfoLength =
xdb默认参数
256- VectorIndexRows =
256- VectorIndexCols =
256- VectorIndexSize =
8- SegmentIndexSize =
14
Instance Attribute Summary collapse
-
#content_buff ⇒ Object
Returns the value of attribute content_buff.
-
#f ⇒ Object
Returns the value of attribute f.
-
#vector_index ⇒ Object
Returns the value of attribute vector_index.
Class Method Summary collapse
Instance Method Summary collapse
- #get_int2(b, offset) ⇒ Object
- #get_long(b, offset) ⇒ Object
- #init_database(dbfile, vi, cb) ⇒ Object
-
#initialize ⇒ XdbSearcher
constructor
A new instance of XdbSearcher.
- #ip_to_long(ip) ⇒ Object
- #read_buffer(offset, length) ⇒ Object
- #search(ip) ⇒ Object
- #search_by_ip_long(ip) ⇒ Object
Constructor Details
#initialize ⇒ XdbSearcher
26 27 28 |
# File 'lib/ip2region/xdb_searcher.rb', line 26 def initialize() init_database(@@xdb_path, nil, nil) end |
Instance Attribute Details
#content_buff ⇒ Object
Returns the value of attribute content_buff.
16 17 18 |
# File 'lib/ip2region/xdb_searcher.rb', line 16 def content_buff @content_buff end |
#f ⇒ Object
Returns the value of attribute f.
16 17 18 |
# File 'lib/ip2region/xdb_searcher.rb', line 16 def f @f end |
#vector_index ⇒ Object
Returns the value of attribute vector_index.
16 17 18 |
# File 'lib/ip2region/xdb_searcher.rb', line 16 def vector_index @vector_index end |
Class Method Details
.xdb_path ⇒ Object
22 23 24 |
# File 'lib/ip2region/xdb_searcher.rb', line 22 def self.xdb_path @@xdb_path end |
.xdb_path=(path) ⇒ Object
18 19 20 |
# File 'lib/ip2region/xdb_searcher.rb', line 18 def self.xdb_path= (path) @@xdb_path = path end |
Instance Method Details
#get_int2(b, offset) ⇒ Object
66 67 68 |
# File 'lib/ip2region/xdb_searcher.rb', line 66 def get_int2(b, offset) (b[offset].ord & 0x000000FF) | (b[offset + 1].ord & 0x0000FF00) end |
#get_long(b, offset) ⇒ Object
60 61 62 63 64 |
# File 'lib/ip2region/xdb_searcher.rb', line 60 def get_long(b, offset) return 0 if b[offset, 4].length != 4 b[offset, 4].unpack("I")[0] end |
#init_database(dbfile, vi, cb) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ip2region/xdb_searcher.rb', line 30 def init_database(dbfile, vi, cb) begin if cb @f = nil @vector_index = nil @content_buff= cb else @f = File.open(dbfile, "rb") @vector_index = vi end rescue IOError => e puts "[Error]: #{e}" exit end end |
#ip_to_long(ip) ⇒ Object
56 57 58 |
# File 'lib/ip2region/xdb_searcher.rb', line 56 def ip_to_long(ip) IPAddr.new(ip).to_i end |
#read_buffer(offset, length) ⇒ Object
70 71 72 73 74 75 76 77 78 |
# File 'lib/ip2region/xdb_searcher.rb', line 70 def read_buffer(offset, length) buffer = nil if self.content_buff != nil buffer = self.content_buff[offset, length] else f.seek(offset) buffer = f.read(length) end end |
#search(ip) ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/ip2region/xdb_searcher.rb', line 46 def search(ip) if ip.is_a?(String) ip = ip_to_long(ip).to_i unless ip =~ /\A\d+\z/ return search_by_ip_long(ip) else return search_by_ip_long(ip) end end |
#search_by_ip_long(ip) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/ip2region/xdb_searcher.rb', line 80 def search_by_ip_long(ip) #locate the segment index block based on the vector index s_ptr = e_ptr = 0 il0 = (ip >> 24) & 0xFF il1 = (ip >> 16) & 0xFF idx = il0 * VectorIndexCols * VectorIndexSize + il1 * VectorIndexSize if self.vector_index != nil s_ptr = self.get_long(self.vector_index, idx) e_ptr = self.get_long(self.vector_index, idx + 4) elsif self.content_buff != nil s_ptr = self.get_long(self.content_buff,HeaderInfoLength + idx) e_ptr = self.get_long(self.content_buff, HeaderInfoLength + idx + 4) else f.seek(HeaderInfoLength + idx) buffer_ptr = f.read(8) s_ptr = self.get_long(buffer_ptr, 0) e_ptr = self.get_long(buffer_ptr, 4) end data_len = data_ptr = -1 l = 0 h = (e_ptr - s_ptr) / SegmentIndexSize while l <= h m = (l + h) >> 1 p = s_ptr + m * SegmentIndexSize # read the segment index buffer_sip = self.read_buffer(p, SegmentIndexSize) sip = self.get_long(buffer_sip, 0) if ip < sip h = m-1 else eip = self.get_long(buffer_sip, 4) if ip > eip l = m + 1 else data_len = self.get_int2(buffer_sip, 8) data_ptr = self.get_long(buffer_sip, 10) break end end end if data_ptr == -1 return nil end buffer_string = self.read_buffer(data_ptr, data_len) # to utf8 buffer_string.force_encoding("UTF-8") end |