public GeobaseEngineCombined(string fileName)
        {
            var stopwatchAll = Stopwatch.StartNew();

            // init sizes
            HeaderLengh    = Extentions.GetBytesLength(typeof(GeobaseHeaderDirrect));
            RangesLengh    = Extentions.GetBytesLength(typeof(GeobaseIpRangeDirrect));
            LocationLengh  = Extentions.GetBytesLength(typeof(GeobaseLocationDirrect));
            CityIndexLengh = Extentions.GetBytesLength(typeof(GeobaseCityIndexDirrect));

            CityOffsetInLocation = Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "Country")
                                   + Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "Region")
                                   + Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "Postal");

            LocationCityBytesLenght = Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "City");

            // init data
            Bytes = File.ReadAllBytes(fileName);

            Header = ByteHelper.BytesToStruct <GeobaseHeaderMarshal>(ByteHelper.GetBytes(Bytes, 0, HeaderLengh));
            var cityIndexesOffsets = ByteHelper.BytesToStruct <GeobaseLocationCityIndexesCombined>(ByteHelper.GetBytes(Bytes, (int)CitiesFromTo.Item1, (int)(CitiesFromTo.Item2 - CitiesFromTo.Item1)));

            _cityIndexPrepared = new int[Records];
            for (int i = 0; i < Records; i++)
            {
                _cityIndexPrepared[i] = (int)(cityIndexesOffsets.CityIndexes[i].LocationOffset / LocationLengh);
            }

            stopwatchAll.Stop();

            Debug.WriteLine("GeobaseEngineCombined, DB loading time: " + stopwatchAll.Elapsed.TotalMilliseconds + " ms");
        }
Esempio n. 2
0
        public GeobaseEngineDirrect(string fileName)
        {
            var stopwatchAll = Stopwatch.StartNew();

            // init sizes
            HeaderLengh    = Extentions.GetBytesLength(typeof(GeobaseHeaderDirrect));
            RangesLengh    = Extentions.GetBytesLength(typeof(GeobaseIpRangeDirrect));
            LocationLengh  = Extentions.GetBytesLength(typeof(GeobaseLocationDirrect));
            CityIndexLengh = Extentions.GetBytesLength(typeof(GeobaseCityIndexDirrect));

            CityOffsetInLocation = Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "Country")
                                   + Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "Region")
                                   + Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "Postal");

            LocationCityBytesLenght = Extentions.GetBytesLength(typeof(GeobaseLocationDirrect), "City");

            // init data
            Bytes = File.ReadAllBytes(fileName);

            int offset = 0;

            Header = new GeobaseHeaderDirrect
            {
                Version         = ByteHelper.GetInt(Bytes, ref offset, true),
                Name            = ByteHelper.GetString(Bytes, 32, ref offset, true),
                Timestamp       = ByteHelper.GetULong(Bytes, ref offset, true),
                Records         = ByteHelper.GetInt(Bytes, ref offset, true),
                OffsetRanges    = ByteHelper.GetUInt(Bytes, ref offset, true),
                OffsetCities    = ByteHelper.GetUInt(Bytes, ref offset, true),
                OffsetLocations = ByteHelper.GetUInt(Bytes, ref offset, true)
            };

            stopwatchAll.Stop();

            Debug.WriteLine("GeobaseEngineDirrect, DB loading time: " + stopwatchAll.Elapsed.TotalMilliseconds + " ms");
        }
        public GeobaseEngineMarshal(string fileName)
        {
            var stopwatchAll = Stopwatch.StartNew();

            HeaderLengh    = Extentions.GetBytesLength(typeof(GeobaseHeaderMarshal));
            RangesLengh    = Extentions.GetBytesLength(typeof(GeobaseIpRangeMarshal));
            LocationLengh  = Extentions.GetBytesLength(typeof(GeobaseLocationMarshal));
            CityIndexLengh = Extentions.GetBytesLength(typeof(GeobaseCityIndexMarshal));

            Bytes = File.ReadAllBytes(fileName);

            //_data = ByteHelper.BytesToStruct<GeobaseDataMarshal>(Bytes); // old approach (slow, but simple)

            #region parrallel loading
            _data = new GeobaseDataMarshal();

            _data.Header = ByteHelper.BytesToStruct <GeobaseHeaderMarshal>(ByteHelper.GetBytes(Bytes, 0, HeaderLengh));

            var locationPartsCount = 50;
            var locationParts      = new ConcurrentBag <GeobaseLocationsPart>();
            var locationTasks      = new Task[locationPartsCount + 2];

            if (Records % locationPartsCount != 0)
            {
                throw new Exception("Wrong locationPartsCount");
            }
            var locationPartSize      = Records / locationPartsCount;
            var locationPartSizeBytes = LocationLengh * locationPartSize;
            for (var i = 0; i < locationPartsCount; i++)
            {
                var i1 = i;
                locationTasks[i] =
                    Task.Factory.StartNew(
                        () =>
                {
                    locationParts.Add(new GeobaseLocationsPart
                    {
                        Locations = ByteHelper.BytesToStruct <GeobaseLocationsMarshal>(
                            ByteHelper.GetBytes(Bytes
                                                , (int)_data.Header.OffsetLocations + locationPartSizeBytes * i1
                                                , locationPartSizeBytes)).Locations
                        ,
                        PartNumber = i1
                    });
                })
                ;
            }

            locationTasks[locationPartsCount] = Task.Factory.StartNew(
                () => { _data.IpRanges = ByteHelper.BytesToStruct <GeobaseIpRangesMarshal>(ByteHelper.GetBytes(Bytes, (int)_data.Header.OffsetRanges, Records * RangesLengh)).IpRanges; });

            locationTasks[locationPartsCount + 1] = Task.Factory.StartNew(
                () => { _data.CityIndexes = ByteHelper.BytesToStruct <GeobaseCityIndexesMarshal>(ByteHelper.GetBytes(Bytes, (int)_data.Header.OffsetCities, Records * CityIndexLengh)).CityIndexes; });

            Task.WaitAll(locationTasks);

            _data.Locations = new GeobaseLocationMarshal[Records];
            var j = 0;
            foreach (var locationPart in locationParts.OrderBy(x => x.PartNumber))
            {
                Array.Copy(locationPart.Locations, 0, _data.Locations, j * locationPartSize, locationPartSize);
                j++;
            }

            #endregion

            _cityIndexPrepared = new int[Records];
            for (int i = 0; i < Records; i++)
            {
                _cityIndexPrepared[i] = (int)(_data.CityIndexes[i].LocationOffset / LocationLengh);
            }
            stopwatchAll.Stop();
            Debug.WriteLine("GeobaseEngineMarshal, DB loading time: " + stopwatchAll.Elapsed.TotalMilliseconds + " ms");
        }