Example #1
0
        /// <summary>
        /// Relocates data internally in the most compact way possible.
        /// </summary>
        public void Compress(bool toReadonly)
        {
            long maxEdgeId;

            _graph.Compress(toReadonly, out maxEdgeId);
            _edgeData.Resize(maxEdgeId * _edgeDataSize);
        }
        /// <summary>
        /// Adds a new restriction.
        /// </summary>
        public void Add(params uint[] restriction)
        {
            if (restriction == null)
            {
                throw new ArgumentNullException("restriction");
            }
            if (restriction.Length == 0)
            {
                throw new ArgumentException("Restriction should contain one or more vertices.", "restriction");
            }

            if (restriction.Length > 1)
            {
                _hasComplexRestrictions = true;
            }

            while (_nextRestrictionPointer + (uint)restriction.Length + 1 >= _restrictions.Length)
            {
                _restrictions.Resize(_restrictions.Length + BLOCKSIZE);
            }

            // add the data.
            _restrictions[_nextRestrictionPointer] = (uint)restriction.Length;
            for (var i = 0; i < restriction.Length; i++)
            {
                _restrictions[_nextRestrictionPointer + i + 1] = restriction[i];
            }

            // add by pointer.
            this.AddByPointer(_nextRestrictionPointer);

            _nextRestrictionPointer = _nextRestrictionPointer + 1 + (uint)restriction.Length;
            _count++;
        }
Example #3
0
        /// <summary>
        /// Adds a new collection, it's assumed to be sorted.
        /// </summary>
        private uint AddCollection(int[] collection)
        {
            uint id;

            if (_collectionReverseIndex != null)
            {
                // check duplicates.
                if (_collectionReverseIndex.TryGetValue(collection, out id))
                { // collection already exists.
                    return(id + 2);
                }
            }

            id = (uint)_collectionIndex.Add(collection);
            if (_index != null)
            { // use next id.
                if (_nextId >= _index.Length)
                {
                    _index.Resize(_index.Length + 1024);
                }
                _index[_nextId] = id;
                id = _nextId;
                _nextId++;
            }
            if (_collectionReverseIndex != null)
            {
                _collectionReverseIndex.Add(collection, id);
            }
            return(id + 2);
        }
Example #4
0
 /// <summary>
 /// Relocates data internally in the most compact way possible.
 /// </summary>
 public void Compress()
 {
     _graph.Compress((originalId, newId) =>
     {
         _edgeData[newId] = _edgeData[originalId];
     });
     _edgeData.Resize(_graph.EdgeCount);
 }
Example #5
0
        /// <summary>
        /// Increase edge data size to fit at least the given edge.
        /// </summary>
        private void IncreaseSizeEdgeData(uint edgeId)
        {
            var size = _edgeData.Length;

            while (edgeId >= size)
            {
                size += BLOCK_SIZE;
            }
            _edgeData.Resize(size);
        }
Example #6
0
        /// <summary>
        /// Increases the memory allocation.
        /// </summary>
        private void IncreaseEdgeSize(long size)
        {
            var oldLength = _edges.Length;

            _edges.Resize(size);
            for (long idx = oldLength; idx < size; idx++)
            {
                _edges[idx] = Constants.NO_EDGE;
            }
        }
Example #7
0
 /// <summary>
 /// Relocates data internally in the most compact way possible.
 /// </summary>
 /// <param name="updateEdgeId">The edge id's may change. This action can be used to hook into every change.</param>
 public void Compress(Action <uint, uint> updateEdgeId)
 {
     _graph.Compress((originalId, newId) =>
     {
         updateEdgeId(originalId, newId);
         _shapes.Switch(originalId, newId);
     });
     _shapes.Resize(_graph.EdgeCount);
     _coordinates.Resize(_graph.VertexCapacity * 2);
 }
Example #8
0
        /// <summary>
        /// Increases the memory allocation.
        /// </summary>
        /// <param name="size"></param>
        private void SetVertexSize(long size)
        {
            if (_readonly)
            {
                throw new Exception("Graph is readonly.");
            }

            var oldLength = _vertices.Length;

            _vertices.Resize(size);
        }
Example #9
0
        /// <summary>
        /// Increases the memory allocation.
        /// </summary>
        private void IncreaseEdgeSize(long size)
        {
            if (_readonly)
            {
                throw new Exception("Graph is readonly.");
            }

            var oldLength = _edges.Length;

            _edges.Resize(size);
        }
Example #10
0
        /// <summary>
        /// Adds a pointer for the given vertex.
        /// </summary>
        private void AddPointer(uint vertex, uint pointer)
        {
            var hash        = CalculateHash(vertex);
            var hashPointer = _hashes[hash];

            if (hashPointer == NO_DATA)
            { // add at the end.
                _hashes[hash] = _nextIndexPointer;
                while (_index.Length <= _nextIndexPointer + 1)
                {
                    _index.Resize(_index.Length + BLOCKSIZE);
                }
                _index[_nextIndexPointer]     = 1;
                _index[_nextIndexPointer + 1] = pointer;
                _nextIndexPointer            += 2;
            }
            else
            { // add to the existing structure.
                var size = _index[hashPointer];

                // check if pointer is not already there.
                for (var i = 0; i < size; i++)
                {
                    if (_index[hashPointer + i + 1] == pointer)
                    { // pointer is already there.
                        return;
                    }
                }

                // add the pointer.
                if ((size & (size - 1)) == 0)
                { // a power of two, copy to the end.
                    var newSpace = size * 2;
                    while (_index.Length <= _nextIndexPointer + newSpace + 1)
                    {
                        _index.Resize(_index.Length + BLOCKSIZE);
                    }
                    _index[_nextIndexPointer] = size;
                    for (var i = 0; i < size; i++)
                    {
                        _index[_nextIndexPointer + 1 + i] = _index[hashPointer + 1 + i];
                    }
                    hashPointer        = _nextIndexPointer;
                    _hashes[hash]      = hashPointer;
                    _nextIndexPointer += newSpace + 1;
                }
                _index[hashPointer + 1 + size] = pointer;
                size++;
                _index[hashPointer] = size;
            }
        }
Example #11
0
        /// <summary>
        /// Adds a stop with associated meta-data.
        /// </summary>
        public void AddStop(uint vertex, IAttributeCollection meta)
        {
            var stopsMetaId = _stopsMeta.Add(meta);

            if (_stopsPointer + 2 >= _stops.Length)
            {
                _stops.Resize(_stops.Length + 100);
            }

            _stops[_stopsPointer + 0] = vertex;
            _stops[_stopsPointer + 1] = stopsMetaId;

            _stopsPointer += 2;
        }
Example #12
0
        /// <summary>
        /// Adds a node id to the index.
        /// </summary>
        public void AddId(long id)
        {
            int int1, int2;

            long2doubleInt(id, out int1, out int2);

            if (_idx + 2 >= _index.Length)
            {
                _index.Resize(_index.Length + (1024 * 1024));
            }
            _index[_idx + 0] = int1;
            _index[_idx + 1] = int2;
            _idx            += 2;
        }
        /// <summary>
        /// Increases the size of the vector-array.
        /// </summary>
        private void IncreaseVertexSize(long size)
        {
            if (_readonly)
            {
                throw new Exception("Graph is readonly.");
            }

            var oldLength = _vertices.Length;

            _vertices.Resize(size);
            for (var i = oldLength; i < _vertices.Length; i++)
            {
                _vertices[i] = NO_EDGE;
            }
        }
Example #14
0
        private uint _nextConnectionId;  // holds the maximum connection id.

        /// <summary>
        /// Adds a connection.
        /// </summary>
        public uint Add(uint stop1, uint stop2, uint tripId, uint departureTime, uint arrivalTime)
        {
            if (arrivalTime <= departureTime)
            {
                throw new ArgumentException("Departure time must be smaller than arrival time.");
            }
            var duration = arrivalTime - departureTime;

            if (duration > CONNECTION_MAX_DURATION)
            {
                throw new ArgumentException(string.Format("A connection with a duration > {0}s cannot be stored.", CONNECTION_MAX_DURATION));
            }

            var id = _nextConnectionId;

            _nextConnectionId++;

            var size = _connections.Length;

            while ((id * CONNECTION_SIZE + CONNECTION_SIZE) > size)
            {
                size += CONNECTIONS_BLOCK_SIZE;
            }
            if (size != _connections.Length)
            {
                _connections.Resize(size);
            }

            _connections[id * CONNECTION_SIZE + 0] = stop1;
            _connections[id * CONNECTION_SIZE + 1] = stop2;
            _connections[id * CONNECTION_SIZE + 2] = tripId;
            _connections[id * CONNECTION_SIZE + 3] = ConnectionsDb.Encode(departureTime, duration);

            return(id);
        }
Example #15
0
        /// <summary>
        /// Increases the size of the vertex-array.
        /// </summary>
        private void IncreaseVertexSize(long min)
        {
            var newSize = (long)(System.Math.Floor((double)min / BLOCKSIZE) + 1) * (long)BLOCKSIZE;

            if (newSize < _vertices.Length)
            { // no need to increase, already big enough.
                return;
            }
            var oldLength = _vertices.Length;

            _vertices.Resize(newSize);
            for (long idx = oldLength; idx < newSize; idx++)
            {
                _vertices[idx] = Constants.NO_VERTEX;
            }
        }
Example #16
0
        /// <summary>
        /// Adds a new schedule.
        /// </summary>
        public uint Add()
        {
            var id = _nextPointer;

            _nextPointer++;

            var size = _data.Length;

            if (id >= size)
            {
                _data.Resize(size + BLOCK_SIZE);
            }

            _data[id] = 0;

            return(id);
        }
Example #17
0
 /// <summary>
 /// Relocates data internally in the most compact way possible.
 /// </summary>
 /// <param name="updateEdgeId">The edge id's may change. This action can be used to hook into every change.</param>
 public void Compress(Action <uint, uint> updateEdgeId)
 {
     _graph.Compress((originalId, newId) =>
     {
         updateEdgeId(originalId, newId);
         _shapes.Switch(originalId, newId);
     });
     _shapes.Resize(_graph.EdgeCount);
     if (_coordinates.Length > _graph.VertexCapacity * 2)
     {
         _coordinates.Resize(_graph.VertexCapacity * 2);
     }
     if (_elevation != null && _elevation.Length > _graph.VertexCapacity)
     {
         _elevation?.Resize(_graph.VertexCapacity);
     }
 }
        /// <summary>
        /// Sets a vertex id for the given vertex.
        /// </summary>
        public void Set(long id, uint vertex)
        {
            var idx = TryGetIndex(id);

            if ((idx * 2) + 1 >= _data.Length)
            {
                var start = _data.Length;
                _data.Resize((idx * 2) + 1 + 1024);
                for (var i = start; i < ((idx * 2) + 1 + 1024); i++)
                {
                    _data[i] = int.MaxValue;
                }
            }

            _data[(idx * 2) + 0] = unchecked ((int)vertex);
            _data[(idx * 2) + 1] = int.MinValue;
        }
Example #19
0
        /// <summary>
        /// Resizes this array.
        /// </summary>
        public sealed override void Resize(long size)
        {
            if (!this.CanResize)
            {
                throw new InvalidOperationException("Cannot resize a fixed-sized array.");
            }

            _index.Resize(size);
        }
Example #20
0
        /// <summary>
        /// Sets the coordinates for the given id.
        /// </summary>
        private void Set(long id, ShapeBase shape)
        {
            if (id < 0 || id >= _index.Length)
            {
                throw new IndexOutOfRangeException();
            }

            if (shape == null)
            { // reset.
                _index[id] = 0;
                return;
            }

            long pointer;
            int  size;

            GetPointerAndSize(id, out pointer, out size);
            if (pointer < 0 || shape.Count < size)
            { // add the coordinates at the end.
                SetPointerAndSize(id, _nextPointer, shape.Count);
                while (_nextPointer + (2 * (shape.Count + 1)) >= _coordinates.Length)
                { // increase the size of the coordinates.
                    _coordinates.Resize(_coordinates.Length + 1024);
                }

                for (var i = 0; i < shape.Count; i++)
                {
                    var coordinate = shape[i];
                    _coordinates[_nextPointer + (i * 2)]     = coordinate.Latitude;
                    _coordinates[_nextPointer + (i * 2) + 1] = coordinate.Longitude;
                }
                _nextPointer += (2 * shape.Count);
            }
            else
            { // update coordinates in-place.
                SetPointerAndSize(id, pointer, shape.Count);
                for (var i = 0; i < shape.Count; i++)
                {
                    var coordinate = shape[i];
                    _coordinates[pointer + (i * 2)]     = coordinate.Latitude;
                    _coordinates[pointer + (i * 2) + 1] = coordinate.Longitude;
                }
            }
        }
Example #21
0
        /// <summary>
        /// Trims the internal data structures of this graph.
        /// </summary>
        public void Trim(out long maxEdgeId)
        {
            // remove all vertices without edges at the end.
            var maxVertexId = uint.MinValue;

            for (uint i = 0; i < _vertices.Length; i++)
            {
                var pointer = _vertices[i];
                if (pointer == NO_EDGE)
                {
                    continue;
                }
                while (_edges[pointer] == NO_EDGE)
                {
                    pointer++;
                }
                do
                {
                    var vertex = _edges[pointer];
                    if (maxVertexId < vertex)
                    { // also take into account the largest vertex pointing down.
                        maxVertexId = vertex;
                    }
                    pointer = MoveNextEdge(pointer);
                } while (pointer != NO_EDGE);
                if (maxVertexId < i)
                { // also take into account the largest vertex pointing down.
                    maxVertexId = i;
                }
            }
            _vertices.Resize(maxVertexId + 1);

            // resize edges.
            var edgesLength = _nextEdgePointer;

            if (edgesLength == 0)
            { // keep minimum room for one edge.
                edgesLength = (uint)_fixedEdgeDataSize;
            }
            _edges.Resize(edgesLength);

            // store the max edge id.
            maxEdgeId = _edges.Length;
        }
        private (uint vertexPointer, int capacity) IncreaseCapacityForTile(uint localTileId, uint pointer)
        {
            // copy current data, we assume current capacity is at max.
            var tilePointer = (long)localTileId * TileSizeInIndex;

            // get current capacity and double it.
            var capacityInBits = _tiles[tilePointer + 4];

            _tiles[tilePointer + 4] = (byte)(capacityInBits + 1);
            var capacity = 1 << capacityInBits;

            // get the current pointer and update it.
            var newVertexPointer = _vertexPointer;

            _vertexPointer += (uint)(capacity * 2);
            var pointerBytes = BitConverter.GetBytes(newVertexPointer);

            for (var b = 0; b < 4; b++)
            {
                _tiles[tilePointer + b] = pointerBytes[b];
            }

            // make sure edge pointers array and vertex coordinates arrays are the proper sizes.
            var length = _edgePointers.Length;

            while (_vertexPointer + capacity >= length)
            {
                length += 1024;
            }

            if (length != _edgePointers.Length)
            {
                var sizeBefore = _edgePointers.Length;
                _edgePointers.Resize(length);
                for (var p = sizeBefore; p < _edgePointers.Length; p++)
                {
                    _edgePointers[p] = GraphConstants.NoVertex;
                }

                sizeBefore = _vertices.Length;
                _vertices.Resize(length * CoordinateSizeInBytes);
                for (var p = sizeBefore; p < _vertices.Length; p++)
                {
                    _vertices[p] = byte.MaxValue;
                }
            }

            // copy all the data over.
            for (uint p = 0; p < capacity; p++)
            {
                _edgePointers[newVertexPointer + p] = _edgePointers[pointer + p];
                CopyEncodedVertex(pointer + p, newVertexPointer + p);
            }

            return(newVertexPointer, capacity * 2);
        }
Example #23
0
        /// <summary>
        /// Pushes a new element.
        /// </summary>
        public void Push(T element)
        {
            if (_pointer >= _data.Length - 1)
            {
                _data.Resize(_data.Length + 1024);
            }

            _pointer++;
            _data[_pointer] = element;
        }
Example #24
0
        /// <summary>
        /// Sorts and converts the index.
        /// </summary>
        public void SortAndConvertIndex()
        {
            _index.Resize(_idx);

            Itinero.Logging.Logger.Log("NodeIndex", Logging.TraceEventType.Information, "Sorting node id's...");
            QuickSort.Sort((i) =>
            {
                var int1 = _index[i * 2 + 0];
                var int2 = _index[i * 2 + 1];
                return(doubleInt2long(int1, int2));
            },
                           (i, j) =>
            {
                var int1          = _index[i * 2 + 0];
                var int2          = _index[i * 2 + 1];
                _index[i * 2 + 0] = _index[j * 2 + 0];
                _index[i * 2 + 1] = _index[j * 2 + 1];
                _index[j * 2 + 0] = int1;
                _index[j * 2 + 1] = int2;
            }, 0, (_index.Length / 2) - 1);

            for (long i = 0; i < _index.Length / 2; i++)
            {
                var int1 = _index[i * 2 + 0];
                var int2 = _index[i * 2 + 1];
                var id   = doubleInt2long(int1, int2);

                if (id == 30976106)
                {
                    System.Diagnostics.Debug.WriteLine(string.Empty);
                }

                if (id >= (long)int.MaxValue * (long)(_overflows.Count + 1))
                { // nodes are overflowing again.
                    _overflows.Add(i);
                }

                _index[i] = (int)(id - ((long)int.MaxValue * (long)_overflows.Count));
            }
            _index.Resize(_index.Length / 2);
            _idx = _index.Length;
        }
Example #25
0
        /// <summary>
        /// Resizes the internal data structures to their smallest size possible.
        /// </summary>
        public void Trim()
        {
            _graph.Trim();

            _coordinates.Resize(_graph.VertexCount * 2);
            if (_elevation != null)
            {
                _elevation.Resize(_graph.VertexCount);
            }
            _shapes.Resize(_graph.EdgeCount);
        }
Example #26
0
        /// <summary>
        /// Adds the given vertex.
        /// </summary>
        public void AddVertex(uint vertex, float latitude, float longitude)
        {
            _graph.AddVertex(vertex);

            if (vertex * 2 + 1 >= _coordinates.Length)
            { // increase coordinates length.
                var newBlocks = 1;
                while (vertex * 2 + 1 >= _coordinates.Length + (newBlocks * BLOCKSIZE * 2))
                { // increase more.
                    newBlocks++;
                }

                var oldLength = _coordinates.Length;
                _coordinates.Resize(_coordinates.Length + (newBlocks * BLOCKSIZE * 2));
                for (var i = oldLength; i < _coordinates.Length; i++)
                {
                    _coordinates[i] = NO_COORDINATE;
                }
            }
            _coordinates[vertex * 2]     = latitude;
            _coordinates[vertex * 2 + 1] = longitude;
        }
Example #27
0
        /// <summary>
        /// Resizes the internal array for a future count.
        /// </summary>
        private void ResizeFor(int count)
        {
            var current = _data.Length;

            while (count > current)
            {
                current += _block;
            }
            if (current != _data.Length)
            { // resize if needed.
                _data.Resize(current);
            }
        }
Example #28
0
        /// <summary>
        /// Adds a new shortcut.
        /// </summary>
        public uint Add(uint[] vertices, IAttributeCollection meta)
        {
            var shortcutMetaId = _shortcutsMeta.Add(meta);

            while (_shortcutsPointer + vertices.Length + 1 >= _shortcuts.Length)
            {
                _shortcuts.Resize(_shortcuts.Length + 100);
            }

            var size = (uint)vertices.Length + 2;

            _shortcuts[_shortcutsPointer + 0] = size;
            _shortcuts[_shortcutsPointer + 1] = shortcutMetaId;
            for (uint i = 0; i < vertices.Length; i++)
            {
                _shortcuts[_shortcutsPointer + 2 + i] = vertices[i];
            }

            var id = _shortcutsPointer;

            _shortcutsPointer += size;
            return(id);
        }
Example #29
0
        /// <summary>
        /// Optimizes this index once it's fully loaded.
        /// </summary>
        public void Optimize()
        {
            // sort array.
            Itinero.Algorithms.Sorting.QuickSort.Sort(i =>
            {
                return(_data[i * 2]);
            }, (i, j) =>
            {
                var t1           = _data[i * 2 + 0];
                var t2           = _data[i * 2 + 1];
                _data[i * 2 + 0] = _data[j * 2 + 0];
                _data[i * 2 + 1] = _data[j * 2 + 1];
                _data[j * 2 + 0] = t1;
                _data[j * 2 + 1] = t2;
            },
                                                      0, (_pointer / 2) - 1);

            // remove reverse index.
            _reverseIndex = null;

            // reduce array size to exact data size.
            _data.Resize(_pointer);
        }
Example #30
0
        /// <summary>
        /// Trims the internal data structures of this graph.
        /// </summary>
        public void Trim(out long maxEdgeId)
        {
            // remove all vertices without edges at the end.
            var maxVertexId = uint.MinValue;

            for (uint i = 0; i < _vertices.Length / VERTEX_SIZE; i++)
            {
                var pointer = _vertices[i * VERTEX_SIZE + FIRST_EDGE] * _edgeSize;
                var count   = _vertices[i * VERTEX_SIZE + EDGE_COUNT];
                for (var e = pointer; e < pointer + (count * _edgeSize); e += _edgeSize)
                {
                    var vertex = _edges[e];
                    if (maxVertexId < vertex)
                    {
                        maxVertexId = vertex;
                    }
                }
                if (count > 0 && maxVertexId < i)
                { // also take into account the largest vertex pointing down.
                    maxVertexId = i;
                }
            }
            _vertices.Resize((maxVertexId + 1) * VERTEX_SIZE);

            // resize edges.
            var edgesLength = _nextEdgePointer;

            if (edgesLength == 0)
            { // keep minimum room for one edge.
                edgesLength = _edgeSize;
            }
            _edges.Resize(edgesLength);

            // store the max edge id.
            maxEdgeId = _edges.Length / _edgeSize;
        }