{"action":"created","comment":{"url":"https://api.github.com/repos/BlueBrain/Brion/pulls/comments/54582666","id":54582666,"diff_hunk":"@@ -0,0 +1,453 @@\n+Redesign of the SpikeReport and Spikes container\n+============\n+\n+The current design of the SpikeReport has several flaws that need to be\n+addressed:\n+* It doesn't allow partial loading for file based reports.\n+* It exposes too many details of the stream case which can probably be hidden.\n+* The container class is a std::multimap while it could simply be a sorted array\n+  because no insertion is needed.\n+This specification proposes a new API to address these defficiencies as well\n+as include new requirements that need to be fulfilled.\n+\n+## Requirements\n+\n+* Provide a container for spikes which is sorted by timestamp, storage\n+  efficient, and random accessible at the <sup>n</sup>th position in amortized\n+  constant time. This is basically a std::vector, but it will be read only\n+  access.\n+\n+* Allow partial data loading for file access.\n+\n+* Allow the selection of a subset of the cells present in the data source to be\n+  reported. In stream-based reports this information should be made available\n+  to the sender to allow filtering at the source. In the ZeroEQ implementation,\n+  the same channel needed for communicating the desired target could be used\n+  for the handshaking required to ensure that the first spikes are not missed.\n+\n+* As few stream related details as possible should leak. This means that\n+  it should be easy to write client code that works the same for both file\n+  based and stream based reports without special conditions for stream based\n+  reports.\n+\n+* For stream reports the user will be able to:\n+ * Retrieve all the data until the end of stream in a simple loop without doing\n+   any active wait (blocking calls are allowed).\n+ * Know if the end of stream has been reached.\n+ * Get all the data received so far without locking.\n+ * Get information about the latest timestamp reached by the source in the\n+   sender side even when there are no spikes at all (currently if the spike\n+   report is completely empty it's not possible to make any progress until the\n+   producer reaches the end of the report).\n+\n+* When data for a time interval is requested, the time intervals are always\n+  closed on the left and open on the right.\n+\n+## API\n+\n+The classes presented below are not thread-safe except for const access.\n+\n+### Spikes container\n+\n+    Spikes\n+    {\n+    public:\n+        Spikes();\n+        ~Spikes();\n+        /*\n+         * Provided to allow Boost.Python to use return by value policies.\n+         * Constant complexity.\n+         */\n+        Spikes( const Spikes& rhs );\n+        /*\n+         * Provided to allow Boost.Python to use return by value policies.\n+         * Constant complexity.\n+         */\n+        Spikes& operator=( const Spikes& rhs );\n+\n+        class const_iterator; // implementation defined\n+\n+        const_iterator begin() const;\n+        const_iterator end() const;\n+        bool empty() const;\n+        size_t size() const;\n+        /* Get the spike at the nth position. No range check is performed */\n+        const std::pair< float, uint32_t >& operator[]( size_t index ) const;\n+\n+        /*\n+         * Get the start of the time window in milliseconds.\n+         *\n+         * UNDEFINED_TIMESTAMP if the container cannot be referred to any time\n+         * window and it is empty. Otherwise, a time smaller or equal than the\n+         * smallest spike time in the container.\n+         *\n+         * @see SpikesReport::getSpikes.\n+         */\n+        float getStartTime() const;\n+\n+        /*\n+         * Get the end of the time window in milliseconds.\n+         *\n+         * UNDEFINED_TIMESTAMP if the container cannot be referred to any time\n+         * window and it is empty. Otherwise, a time greater than the highest\n+         * spike time in the container.\n+         */\n+        float getEndTime() const;\n+    }\n+\n+\n+With this API, it's relatively easy to provide a Boost.Python wrapping of the\n+container inside a numpy array.\n+\n+### SpikeReport\n+\n+    SpikeReport : public boost::noncopyable\n+    {\n+    public:\n+        SpikeReport( const URI& uri, int mode );\n+\n+        /*\n+         * Open a report in read mode with a subset selections.\n+         *\n+         * @param uri\n+         * @param subset The set of gids to be reported.\n+         */\n+        SpikeReport( const URI& uri, uint32_ts subset );\n+\n+        ~SpikeReport();\n+\n+        const URI& getURI();\n+\n+        /*\n+         * Return a container with all the spikes contained in a time interval.\n+         *\n+         * @param startTime a value smaller than endTime or UNDEFINED_TIMESTAMP.\n+         *\n+         *        - If UNDEFINED_TIMESTAMP, the left edge of the interval will\n+         *          be considered -infinity. Spikes::getStartTime in the output\n+         *          will return the smallest spike time inside the container if\n+         *          not empty, otherwise it will return UNDEFINED_TIMESTAMP.\n+         *\n+         *        - For any other value, this is the smallest timestamp to be\n+         *          reported and the output Spikes container will return this\n+         *          time from Spikes::getStartTime.\n+         *\n+         * @param endTime a value greater than startTime or UNDEFINED_TIMESTAMP.\n+         *\n+         *        - If UNDEFINED_TIMESTAMP, this function will return all\n+         *          the spikes available with timestamp >= startTime.\n+         *          In file based reports, this is all the data from startTime\n+         *          until the end.\n+         *          In stream based reports:\n+         *          - If startTime is UNDEFINED_TIMESTAMP this call will return\n+         *            all the available data without blocking at all. If there\n+         *            are no data the output container will be empty and the\n+         *            both Spikes::getEndTime and Spikes::getStartTime will\n+         *            return UNDEFINED_TIMESTAMP.\n+         *          - For any other value, the call will block until an event\n+         *            with t > startTime arrives, the stream is closed or the\n+         *            timeout goes off, whatever happens first.\n+         *\n+         *        - For any other value, return all the spikes in the time\n+         *          interval [t, t') where t = startTime and t' > t.\n+         *          This will be the value returned by Spikes::getEndTime() on\n+         *          the result.\n+         *\n+         * In stream based reports calling this function will update the report\n+         * end time.\n+         *\n+         * In the case the timeout goes off this function will always return a\n+         * consistent slice of the spike report. This means that the output\n+         * container will not include any spikes with timestamp t unless all the\n+         * possible spikes with the same timestamp are also inside the\n+         * container.\n+         *\n+         * The implementation will try it's best to not duplicate the data\n+         * requested if it was already loaded by a previous call, but no\n+         * guarantees are made. The recommended way of accessing the data is to\n+         * always make the startTime match the endTime of a previous call.\n+         *\n+         * @throws std::runtime_eror is the report was opened in write mode.\n+         */\n+        Spikes getSpikes( float startTime, float endTime,\n+                          const uint32_t timeout = LB_TIMEOUT_INDEFINITE );\n+\n+        /*\n+         * For reports open in write mode, write the given spikes to the output.\n+         *\n+         * @throws std::runtime_eror if the report was opened in read mode.\n+         * @throws std::runtime_eror when writing to a stream if the spikes are\n+         *         not sorted or any timestamp is <= to the highest timestamp\n+         *         written by previous calls. This is required to enforce the\n+         *         post-conditions of getSpikes in the receiving end.\n+         */\n+        void writeSpikes( const const std::vector< float, uint32_t >& spikes );\n+\n+        /* Overload of the method above provided for convenience */\n+        void writeSpikes( const Spikes& spikes );\n+\n+        /*\n+         * Return the start time of the report if known, UNDEFINED_TIMESTAMP\n+         * otherwise.\n+         *\n+         * In file based reports it's the time of the first spike or undefined\n+         * if the report is empty.\n+         * In stream based reports it's always 0.\n+         */\n+        float getStartTime() const;\n+\n+        /*\n+         * Return the end time of the report if known, UNDEFINED_TIMESTAMP\n+         * otherwise.\n+         *\n+         * In file based reports the end time is the timestamp of the last spike\n+         * plus an epsilon, or undefined if the report is empty or it cannot be\n+         * be decided without loading the whole data.\n+         * In stream based reports it's always undefined until the report is\n+         * closed. When the report is closed it will be the latest timestamp\n+         * reported by the sender or the time of the last spike + epsilon,\n+         * whichever is larger; or 0 if no information was received.\n+         *\n+         * To guarantee const-correctness the value returned by this function\n+         * can only change when getSpikes is called.\n+         */\n+        float getEndTime() const;\n+\n+        /*\n+         * Closes the report.\n+         *\n+         * Only meaningful for stream based reports.\n+         * For reports opened in write mode it finishes the reporting. For\n+         * reports opened in read mode it disconnects from the source, any call\n+         * waiting in getSpikes will be unblocked and getEndTime will return the\n+         * last known timestamp.\n+         *\n+         * This function is thread-safe with getSpikes as it ensures that any\n+         * thread waiting there with an infinite timeout will eventually return.\n+         *\n+         * Implicitly called by the destructor, (but calling the destructor and\n+         * getSpikes at the same time is not safe!). Calling any other function\n+         * after the report has been closed has undefined behavior.\n+         */\n+        void close();\n+\n+        /*\n+         * Clears all internal caching.\n+         *\n+         * Any Spikes container returned by this class will remain valid as\n+         * expected.\n+         *\n+         * The implementation is allowed to retain as much memory as needed\n+         * until all pre-existing Spikes containers are destroyed to guarantee\n+         * this.\n+         */\n+        void clear();\n+    }\n+\n+\n+## Examples\n+\n+### Copying a spike report from one URL to another\n+\n+    SpikeReport source( \"url1\", brion::MODE_READ )\n+    SpikeReport destination( \"url2\", brion::MODE_WRITE )\n+\n+    float last = 0;\n+    // In file based reports this will iterates just once.\n+    while( source.getEndTime() == brion::UNDEFINED_TIMESTAMP )\n+    {\n+        const Spikes spikes =\n+            source.getSpikes( last, brion::UNDEFINED_TIMESTAMP );\n+        last = spikes.getEndTime();\n+        destitation.write( spikes );\n+    }\n+\n+\n+### Copying a spike report from one URL to another reading a maximum time window\n+\n+    SpikeReport source( \"url1\", brion::MODE_READ )\n+    SpikeReport destination( \"url2\", brion::MODE_WRITE )\n+\n+    float current = source.getStartTime();\n+    float width = 10;\n+    // If we have an empty file report, current == UNDEFINED_TIMESTAMP, and then\n+    // the loop is not entered.\n+    for( ; current + width < source.getEndTime( ); current += width )\n+    {\n+        const Spikes spikes = source.getSpikes( current, current + width );\n+        last = spikes.getEndTime();\n+        destintation.write( spikes );\n+    }\n+    // Reading the last slice. This is guaranteed to return immediately in\n+    // stream sources because the EOS has been reached.\n+    destintation.write( source.getSpikes( current, report.getEndTime( )));\n+\n+\n+## Implementation\n+\n+TODO\n+\n+brain::SpikeReport\n+\n+Where does the pluging interface go? brion or brain.\n+\n+brion::SpikeFile?\n+brion::SpikeStream?\n+\n+## Issues\n+\n+\n+### 1: Why do we need a Spikes container\n+\n+_Resolved: No_\n+\n+There are arguments against and in favour of it.\n+\n+Against:\n+* It adds unnecessary complexity to the implementation.","path":"doc/feature/spikeReport.md","position":307,"original_position":307,"commit_id":"4de670f2193d4730682a14e4552dec3bbd3d9cf3","original_commit_id":"4de670f2193d4730682a14e4552dec3bbd3d9cf3","user":{"login":"bilgili","id":1157568,"avatar_url":"https://avatars.githubusercontent.com/u/1157568?v=3","gravatar_id":"","url":"https://api.github.com/users/bilgili","html_url":"https://github.com/bilgili","followers_url":"https://api.github.com/users/bilgili/followers","following_url":"https://api.github.com/users/bilgili/following{/other_user}","gists_url":"https://api.github.com/users/bilgili/gists{/gist_id}","starred_url":"https://api.github.com/users/bilgili/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bilgili/subscriptions","organizations_url":"https://api.github.com/users/bilgili/orgs","repos_url":"https://api.github.com/users/bilgili/repos","events_url":"https://api.github.com/users/bilgili/events{/privacy}","received_events_url":"https://api.github.com/users/bilgili/received_events","type":"User","site_admin":false},"body":"Dont forget Mike : @mgeplf :)","created_at":"2016-03-01T15:28:53Z","updated_at":"2016-03-01T15:28:53Z","html_url":"https://github.com/BlueBrain/Brion/pull/44#discussion_r54582666","pull_request_url":"https://api.github.com/repos/BlueBrain/Brion/pulls/44","_links":{"self":{"href":"https://api.github.com/repos/BlueBrain/Brion/pulls/comments/54582666"},"html":{"href":"https://github.com/BlueBrain/Brion/pull/44#discussion_r54582666"},"pull_request":{"href":"https://api.github.com/repos/BlueBrain/Brion/pulls/44"}}},"pull_request":{"url":"https://api.github.com/repos/BlueBrain/Brion/pulls/44","id":61100297,"html_url":"https://github.com/BlueBrain/Brion/pull/44","diff_url":"https://github.com/BlueBrain/Brion/pull/44.diff","patch_url":"https://github.com/BlueBrain/Brion/pull/44.patch","issue_url":"https://api.github.com/repos/BlueBrain/Brion/issues/44","number":44,"state":"open","locked":false,"title":"Specification document for a new SpikeReport API.","user":{"login":"hernando","id":791427,"avatar_url":"https://avatars.githubusercontent.com/u/791427?v=3","gravatar_id":"","url":"https://api.github.com/users/hernando","html_url":"https://github.com/hernando","followers_url":"https://api.github.com/users/hernando/followers","following_url":"https://api.github.com/users/hernando/following{/other_user}","gists_url":"https://api.github.com/users/hernando/gists{/gist_id}","starred_url":"https://api.github.com/users/hernando/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hernando/subscriptions","organizations_url":"https://api.github.com/users/hernando/orgs","repos_url":"https://api.github.com/users/hernando/repos","events_url":"https://api.github.com/users/hernando/events{/privacy}","received_events_url":"https://api.github.com/users/hernando/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-02-29T16:05:29Z","updated_at":"2016-03-01T15:28:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4dbf9a6ca1b6c1cddb66d7e9de765d76d884fcb3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/BlueBrain/Brion/pulls/44/commits","review_comments_url":"https://api.github.com/repos/BlueBrain/Brion/pulls/44/comments","review_comment_url":"https://api.github.com/repos/BlueBrain/Brion/pulls/comments{/number}","comments_url":"https://api.github.com/repos/BlueBrain/Brion/issues/44/comments","statuses_url":"https://api.github.com/repos/BlueBrain/Brion/statuses/4de670f2193d4730682a14e4552dec3bbd3d9cf3","head":{"label":"hernando:spike_report","ref":"spike_report","sha":"4de670f2193d4730682a14e4552dec3bbd3d9cf3","user":{"login":"hernando","id":791427,"avatar_url":"https://avatars.githubusercontent.com/u/791427?v=3","gravatar_id":"","url":"https://api.github.com/users/hernando","html_url":"https://github.com/hernando","followers_url":"https://api.github.com/users/hernando/followers","following_url":"https://api.github.com/users/hernando/following{/other_user}","gists_url":"https://api.github.com/users/hernando/gists{/gist_id}","starred_url":"https://api.github.com/users/hernando/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hernando/subscriptions","organizations_url":"https://api.github.com/users/hernando/orgs","repos_url":"https://api.github.com/users/hernando/repos","events_url":"https://api.github.com/users/hernando/events{/privacy}","received_events_url":"https://api.github.com/users/hernando/received_events","type":"User","site_admin":false},"repo":{"id":36439822,"name":"Brion","full_name":"hernando/Brion","owner":{"login":"hernando","id":791427,"avatar_url":"https://avatars.githubusercontent.com/u/791427?v=3","gravatar_id":"","url":"https://api.github.com/users/hernando","html_url":"https://github.com/hernando","followers_url":"https://api.github.com/users/hernando/followers","following_url":"https://api.github.com/users/hernando/following{/other_user}","gists_url":"https://api.github.com/users/hernando/gists{/gist_id}","starred_url":"https://api.github.com/users/hernando/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hernando/subscriptions","organizations_url":"https://api.github.com/users/hernando/orgs","repos_url":"https://api.github.com/users/hernando/repos","events_url":"https://api.github.com/users/hernando/events{/privacy}","received_events_url":"https://api.github.com/users/hernando/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/hernando/Brion","description":"Blue Brain C++ File IO Library","fork":true,"url":"https://api.github.com/repos/hernando/Brion","forks_url":"https://api.github.com/repos/hernando/Brion/forks","keys_url":"https://api.github.com/repos/hernando/Brion/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hernando/Brion/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hernando/Brion/teams","hooks_url":"https://api.github.com/repos/hernando/Brion/hooks","issue_events_url":"https://api.github.com/repos/hernando/Brion/issues/events{/number}","events_url":"https://api.github.com/repos/hernando/Brion/events","assignees_url":"https://api.github.com/repos/hernando/Brion/assignees{/user}","branches_url":"https://api.github.com/repos/hernando/Brion/branches{/branch}","tags_url":"https://api.github.com/repos/hernando/Brion/tags","blobs_url":"https://api.github.com/repos/hernando/Brion/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hernando/Brion/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hernando/Brion/git/refs{/sha}","trees_url":"https://api.github.com/repos/hernando/Brion/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hernando/Brion/statuses/{sha}","languages_url":"https://api.github.com/repos/hernando/Brion/languages","stargazers_url":"https://api.github.com/repos/hernando/Brion/stargazers","contributors_url":"https://api.github.com/repos/hernando/Brion/contributors","subscribers_url":"https://api.github.com/repos/hernando/Brion/subscribers","subscription_url":"https://api.github.com/repos/hernando/Brion/subscription","commits_url":"https://api.github.com/repos/hernando/Brion/commits{/sha}","git_commits_url":"https://api.github.com/repos/hernando/Brion/git/commits{/sha}","comments_url":"https://api.github.com/repos/hernando/Brion/comments{/number}","issue_comment_url":"https://api.github.com/repos/hernando/Brion/issues/comments{/number}","contents_url":"https://api.github.com/repos/hernando/Brion/contents/{+path}","compare_url":"https://api.github.com/repos/hernando/Brion/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hernando/Brion/merges","archive_url":"https://api.github.com/repos/hernando/Brion/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hernando/Brion/downloads","issues_url":"https://api.github.com/repos/hernando/Brion/issues{/number}","pulls_url":"https://api.github.com/repos/hernando/Brion/pulls{/number}","milestones_url":"https://api.github.com/repos/hernando/Brion/milestones{/number}","notifications_url":"https://api.github.com/repos/hernando/Brion/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hernando/Brion/labels{/name}","releases_url":"https://api.github.com/repos/hernando/Brion/releases{/id}","deployments_url":"https://api.github.com/repos/hernando/Brion/deployments","created_at":"2015-05-28T13:23:07Z","updated_at":"2016-01-18T16:00:14Z","pushed_at":"2016-03-01T15:20:08Z","git_url":"git://github.com/hernando/Brion.git","ssh_url":"git@github.com:hernando/Brion.git","clone_url":"https://github.com/hernando/Brion.git","svn_url":"https://github.com/hernando/Brion","homepage":"http://bluebrain.github.io/","size":348,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"BlueBrain:master","ref":"master","sha":"f936a450d6bdd56355f2752d9038fcc39ebb7943","user":{"login":"BlueBrain","id":1479142,"avatar_url":"https://avatars.githubusercontent.com/u/1479142?v=3","gravatar_id":"","url":"https://api.github.com/users/BlueBrain","html_url":"https://github.com/BlueBrain","followers_url":"https://api.github.com/users/BlueBrain/followers","following_url":"https://api.github.com/users/BlueBrain/following{/other_user}","gists_url":"https://api.github.com/users/BlueBrain/gists{/gist_id}","starred_url":"https://api.github.com/users/BlueBrain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BlueBrain/subscriptions","organizations_url":"https://api.github.com/users/BlueBrain/orgs","repos_url":"https://api.github.com/users/BlueBrain/repos","events_url":"https://api.github.com/users/BlueBrain/events{/privacy}","received_events_url":"https://api.github.com/users/BlueBrain/received_events","type":"Organization","site_admin":false},"repo":{"id":35547993,"name":"Brion","full_name":"BlueBrain/Brion","owner":{"login":"BlueBrain","id":1479142,"avatar_url":"https://avatars.githubusercontent.com/u/1479142?v=3","gravatar_id":"","url":"https://api.github.com/users/BlueBrain","html_url":"https://github.com/BlueBrain","followers_url":"https://api.github.com/users/BlueBrain/followers","following_url":"https://api.github.com/users/BlueBrain/following{/other_user}","gists_url":"https://api.github.com/users/BlueBrain/gists{/gist_id}","starred_url":"https://api.github.com/users/BlueBrain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BlueBrain/subscriptions","organizations_url":"https://api.github.com/users/BlueBrain/orgs","repos_url":"https://api.github.com/users/BlueBrain/repos","events_url":"https://api.github.com/users/BlueBrain/events{/privacy}","received_events_url":"https://api.github.com/users/BlueBrain/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/BlueBrain/Brion","description":"Blue Brain C++ File IO Library","fork":false,"url":"https://api.github.com/repos/BlueBrain/Brion","forks_url":"https://api.github.com/repos/BlueBrain/Brion/forks","keys_url":"https://api.github.com/repos/BlueBrain/Brion/keys{/key_id}","collaborators_url":"https://api.github.com/repos/BlueBrain/Brion/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/BlueBrain/Brion/teams","hooks_url":"https://api.github.com/repos/BlueBrain/Brion/hooks","issue_events_url":"https://api.github.com/repos/BlueBrain/Brion/issues/events{/number}","events_url":"https://api.github.com/repos/BlueBrain/Brion/events","assignees_url":"https://api.github.com/repos/BlueBrain/Brion/assignees{/user}","branches_url":"https://api.github.com/repos/BlueBrain/Brion/branches{/branch}","tags_url":"https://api.github.com/repos/BlueBrain/Brion/tags","blobs_url":"https://api.github.com/repos/BlueBrain/Brion/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/BlueBrain/Brion/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/BlueBrain/Brion/git/refs{/sha}","trees_url":"https://api.github.com/repos/BlueBrain/Brion/git/trees{/sha}","statuses_url":"https://api.github.com/repos/BlueBrain/Brion/statuses/{sha}","languages_url":"https://api.github.com/repos/BlueBrain/Brion/languages","stargazers_url":"https://api.github.com/repos/BlueBrain/Brion/stargazers","contributors_url":"https://api.github.com/repos/BlueBrain/Brion/contributors","subscribers_url":"https://api.github.com/repos/BlueBrain/Brion/subscribers","subscription_url":"https://api.github.com/repos/BlueBrain/Brion/subscription","commits_url":"https://api.github.com/repos/BlueBrain/Brion/commits{/sha}","git_commits_url":"https://api.github.com/repos/BlueBrain/Brion/git/commits{/sha}","comments_url":"https://api.github.com/repos/BlueBrain/Brion/comments{/number}","issue_comment_url":"https://api.github.com/repos/BlueBrain/Brion/issues/comments{/number}","contents_url":"https://api.github.com/repos/BlueBrain/Brion/contents/{+path}","compare_url":"https://api.github.com/repos/BlueBrain/Brion/compare/{base}...{head}","merges_url":"https://api.github.com/repos/BlueBrain/Brion/merges","archive_url":"https://api.github.com/repos/BlueBrain/Brion/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/BlueBrain/Brion/downloads","issues_url":"https://api.github.com/repos/BlueBrain/Brion/issues{/number}","pulls_url":"https://api.github.com/repos/BlueBrain/Brion/pulls{/number}","milestones_url":"https://api.github.com/repos/BlueBrain/Brion/milestones{/number}","notifications_url":"https://api.github.com/repos/BlueBrain/Brion/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/BlueBrain/Brion/labels{/name}","releases_url":"https://api.github.com/repos/BlueBrain/Brion/releases{/id}","deployments_url":"https://api.github.com/repos/BlueBrain/Brion/deployments","created_at":"2015-05-13T12:33:49Z","updated_at":"2016-01-13T08:52:11Z","pushed_at":"2016-03-01T15:20:09Z","git_url":"git://github.com/BlueBrain/Brion.git","ssh_url":"git@github.com:BlueBrain/Brion.git","clone_url":"https://github.com/BlueBrain/Brion.git","svn_url":"https://github.com/BlueBrain/Brion","homepage":"http://bluebrain.github.io/","size":372,"stargazers_count":3,"watchers_count":3,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":2,"forks":9,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/BlueBrain/Brion/pulls/44"},"html":{"href":"https://github.com/BlueBrain/Brion/pull/44"},"issue":{"href":"https://api.github.com/repos/BlueBrain/Brion/issues/44"},"comments":{"href":"https://api.github.com/repos/BlueBrain/Brion/issues/44/comments"},"review_comments":{"href":"https://api.github.com/repos/BlueBrain/Brion/pulls/44/comments"},"review_comment":{"href":"https://api.github.com/repos/BlueBrain/Brion/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/BlueBrain/Brion/pulls/44/commits"},"statuses":{"href":"https://api.github.com/repos/BlueBrain/Brion/statuses/4de670f2193d4730682a14e4552dec3bbd3d9cf3"}}}}