/// <summary> /// Возвращает идентификатор местоположения по ip-адресу /// </summary> /// <param name="ip">IP-адрес</param> /// <param name="locationIndex">Идентификатор местоположения</param> /// <returns>true, если местоположение найдено. Иначе false</returns> internal bool GetLocationIndexByIp(uint ip, out uint locationIndex) { int index = Array.BinarySearch(_holder.IpTable, 0, _ipTableSize, new IpRecord { ip_from = ip }, IpRecordComparer.Instance); locationIndex = 0; bool locationFound = false; if (index >= 0) { if (index < _ipTableSize) { locationIndex = _holder.IpTable[index].location_index; locationFound = true; } } else if (index < 0) { index = ~index; if (index > 0 && index <= _ipTableSize) { IpRecord ipRange = _holder.IpTable[index - 1]; if (ipRange.ip_from <= ip && ipRange.ip_to >= ip) { locationIndex = ipRange.location_index; locationFound = true; } } } return(locationFound); }
/// <summary> /// Таблица IP-адресов содержит коллизию, начиная с записи №99038 (по счёту с 0). /// Данный метод вычисляет последний корректный интервал IP-адресов в данной структуре. /// В качестве варианта можно вводить это значение в виде настройки /// </summary> private void CheckIpTable() { uint prevValue = 0; for (int i = 0; i < RecordCount; i++) { IpRecord ipRec = _holder.IpTable[i]; uint curValue = ipRec.ip_from; if (ipRec.ip_from < prevValue || ipRec.ip_to < ipRec.ip_from) { _ipTableSize = i; return; } prevValue = ipRec.ip_from; } _ipTableSize = RecordCount; }
/// <summary> /// Диагностический метод /// </summary> internal static unsafe void WriteDbFiles(DataHolder holder, int ipTableSize) { using (StreamWriter sw = new StreamWriter("ip.txt", false, Encoding.UTF8)) { for (int i = 0; i < ipTableSize; i++) { IpRecord rec = holder.IpTable[i]; LocationRecord lrec = holder.GetLocationRecordById((int)rec.location_index); string str = Utils.ConvertUintToIp(rec.ip_from).PadRight(20) + Utils.ConvertUintToIp(rec.ip_to).PadRight(20) + new string(lrec.city).PadRight(24); sw.WriteLine(str); } } using (StreamWriter sw = new StreamWriter("location.txt", false, Encoding.UTF8)) { for (int i = 0; i < holder.RecordCount; i++) { LocationRecord rec = holder.GetLocationRecordByNameIndex(i); string city = new string(rec.city); string country = new string(rec.country); string region = new string(rec.region); string postal = new string(rec.postal); string organization = new string(rec.organization); if (city.Length > 23 || country.Length > 7 || region.Length > 11 || postal.Length > 23 || organization.Length > 31) { throw new Exception(); } string str = city.PadRight(24) + country.PadRight(8) + region.PadRight(12) + postal.PadRight(12) + organization.PadRight(32) + rec.latitude.ToString().PadRight(20) + rec.longitude.ToString().PadRight(20); sw.WriteLine(str); } } }