{"action":"created","comment":{"url":"https://api.github.com/repos/cvmfs/cvmfs/pulls/comments/54734551","id":54734551,"diff_hunk":"@@ -0,0 +1,489 @@\n+/**\n+ * This file is part of the CernVM File System.\n+ */\n+\n+#define __STDC_FORMAT_MACROS\n+\n+#include \"cvmfs_config.h\"\n+#include \"sqlitemem.h\"\n+\n+#include <cassert>\n+#include <cstddef>\n+#include <cstring>\n+#include <new>\n+\n+#include \"smalloc.h\"\n+#include \"util_concurrency.h\"\n+\n+using namespace std;  // NOLINT\n+\n+namespace sqlite {\n+\n+uint32_t MemoryManager::MallocArena::GetSize(void *ptr) const {\n+  assert(Contains(ptr));\n+\n+  ReservedBlockCtl *block_ctl = reinterpret_cast<ReservedBlockCtl *>(\n+    reinterpret_cast<char *>(ptr) - sizeof(ReservedBlockCtl));\n+  int32_t size = -(block_ctl->size);\n+  assert(size > 1);\n+  return size - sizeof(ReservedBlockCtl) - 1;\n+}\n+\n+/**\n+ * Creates a free block at the place of the reserved block ptr points into.\n+ * The free block might need to be merged with adjacent lower and/or upper\n+ * blocks.  In these cases, the corresponding blocks are removed from the list\n+ * of available blocks.  Every allocated block has a predecessor and a\n+ * successor in the arena.  The newly created free block is added to the end of\n+ * the list of available blocks.\n+ */\n+void MemoryManager::MallocArena::Free(void *ptr) {\n+  assert(Contains(ptr));\n+\n+  no_reserved_--;\n+\n+  ReservedBlockCtl *block_ctl = reinterpret_cast<ReservedBlockCtl *>(\n+    reinterpret_cast<char *>(ptr) - sizeof(ReservedBlockCtl));\n+  char prior_tag = *(reinterpret_cast<char *>(block_ctl) - 1);\n+  assert((prior_tag == kTagAvail) || (prior_tag == kTagReserved));\n+  assert(block_ctl->size <= 0);\n+\n+  int32_t new_size = -(block_ctl->size);\n+  assert(new_size > 0);\n+  AvailBlockCtl *new_avail = reinterpret_cast<AvailBlockCtl *>(block_ctl);\n+\n+  if (prior_tag == kTagAvail) {\n+    // Merge with block before and remove the block from the list\n+    int32_t prior_size = reinterpret_cast<AvailBlockTag *>(\n+      reinterpret_cast<char *>(block_ctl) - sizeof(AvailBlockTag))->size;\n+    assert(prior_size > 0);\n+    new_size += prior_size;\n+    new_avail = reinterpret_cast<AvailBlockCtl *>(\n+      reinterpret_cast<char *>(block_ctl) - prior_size);\n+    AvailBlockCtl *next = new_avail->GetNextPtr(arena_);\n+    AvailBlockCtl *prev = new_avail->GetPrevPtr(arena_);\n+    prev->link_next = new_avail->link_next;\n+    next->link_prev = new_avail->link_prev;\n+    if (rover_ == new_avail)\n+      rover_ = head_avail_;\n+  }\n+\n+  int32_t succ_size = *reinterpret_cast<int32_t *>(\n+    reinterpret_cast<char *>(new_avail) + new_size);\n+  if (succ_size >= 0) {\n+    // Merge with succeeding block and remove the block from the list\n+    AvailBlockCtl *succ_avail = reinterpret_cast<AvailBlockCtl *>(\n+      reinterpret_cast<char *>(new_avail) + new_size);\n+    AvailBlockCtl *next = succ_avail->GetNextPtr(arena_);\n+    AvailBlockCtl *prev = succ_avail->GetPrevPtr(arena_);\n+    prev->link_next = succ_avail->link_next;\n+    next->link_prev = succ_avail->link_prev;\n+    new_size += succ_size;\n+    if (rover_ == succ_avail)\n+      rover_ = head_avail_;\n+  }\n+\n+  // Insert new free block at the end of the list\n+  AvailBlockCtl *next = head_avail_;\n+  AvailBlockCtl *prev = head_avail_->GetPrevPtr(arena_);\n+  next->link_prev = new_avail->ConvertToLink(arena_);\n+  prev->link_next = new_avail->ConvertToLink(arena_);\n+  new_avail->link_next = head_avail_->ConvertToLink(arena_);\n+  new_avail->link_prev = prev->ConvertToLink(arena_);\n+\n+  // Set new free block's boundaries\n+  new_avail->size = new_size;\n+  void *upper_tag =\n+    reinterpret_cast<char *>(new_avail) + new_size - sizeof(AvailBlockTag);\n+  new (upper_tag) AvailBlockTag(new_size);\n+}\n+\n+\n+/**\n+ * Walks the list of available blocks starting from rover and allocates the\n+ * first available spot that's large enough.  Puts the reserved block at the end\n+ * of the available one and, if necessary, removes the available one from the\n+ * list of free blocks.\n+ */\n+void *MemoryManager::MallocArena::Malloc(const uint32_t size) {\n+  assert(size > 0);\n+\n+  // Control word first, block type tag last\n+  int32_t total_size = sizeof(ReservedBlockCtl) + size + 1;\n+  if (total_size < kMinBlockSize)\n+    total_size = kMinBlockSize;\n+\n+  bool wrapped = false;\n+  // Generally: p = LINK(q)\n+  AvailBlockCtl *q = rover_;\n+  AvailBlockCtl *p;\n+  do {\n+    p = q->GetNextPtr(arena_);\n+    if (p->size >= total_size)\n+      break;\n+    if (p == head_avail_) {\n+      if (wrapped)\n+        return NULL;\n+      wrapped = true;\n+    }\n+    q = p;\n+  } while (true);\n+\n+  // As of here: we found a sufficiently large free block at p following q\n+  no_reserved_++;\n+\n+  int32_t remaining_size = p->size - total_size;\n+  // Avoid creation of very small blocks\n+  if (remaining_size < kMinBlockSize) {\n+    total_size += remaining_size;\n+    remaining_size = 0;\n+  }\n+\n+  // Update the list of available blocks\n+  if (remaining_size == 0) {\n+    // Remove free block p from the list of available blocks\n+    q->link_next = p->link_next;\n+    q->GetNextPtr(arena_)->link_prev = q->ConvertToLink(arena_);\n+  } else {\n+    p->size = remaining_size;\n+    void *upper_tag =\n+      reinterpret_cast<char *>(p) + remaining_size - sizeof(AvailBlockTag);\n+    new (upper_tag) AvailBlockTag(remaining_size);\n+  }\n+  rover_ = q->GetNextPtr(arena_);\n+\n+  // Place the new allocation, which also sets the block type tag at the end\n+  char *new_block = reinterpret_cast<char *>(p) + remaining_size;\n+  new (new_block) ReservedBlockCtl(total_size);\n+  return new_block + sizeof(ReservedBlockCtl);\n+}\n+\n+\n+/**\n+ * The arena starts with a pointer to this followed by the AvailBlockCtl of\n+ * head_avail_, followed by a reserved tag to prevent it from being merged,\n+ * followed by a free block spanning the arena until the end tag.  The end tag\n+ * is a single negative int, which mimics another reserved block.\n+ */\n+MemoryManager::MallocArena::MallocArena()\n+  : arena_(reinterpret_cast<char *>(sxmmap_align(kArenaSize)))\n+  , head_avail_(reinterpret_cast<AvailBlockCtl *>(arena_ + sizeof(void *)))\n+  , rover_(head_avail_)\n+  , no_reserved_(0)\n+{\n+  int32_t usable_size = kArenaSize -\n+    (sizeof(void *) + sizeof(AvailBlockCtl) + 1 + sizeof(int32_t));\n+  *reinterpret_cast<MallocArena **>(arena_) = this;\n+  AvailBlockCtl *free_block =\n+    new (arena_ + sizeof(void *) + sizeof(AvailBlockCtl) + 1) AvailBlockCtl();\n+  free_block->size = usable_size;\n+  free_block->link_next = free_block->link_prev =\n+    head_avail_->ConvertToLink(arena_);\n+\n+  head_avail_->size = 0;\n+  head_avail_->link_next = head_avail_->link_prev =\n+    free_block->ConvertToLink(arena_);\n+\n+  // Prevent succeeding blocks from merging\n+  *(reinterpret_cast<char *>(free_block) - 1) = kTagReserved;\n+  // Final tag: reserved block marker\n+  *reinterpret_cast<int32_t *>(arena_ + kArenaSize - sizeof(int32_t)) = -1;","path":"cvmfs/sqlitemem.cc","position":190,"original_position":190,"commit_id":"33c7ee9a12d6ef21f9f5ac73e05f84a4bdab34a7","original_commit_id":"968ff5dcd22465db654fdf14d6ce3b81e318e962","user":{"login":"reneme","id":1562139,"avatar_url":"https://avatars.githubusercontent.com/u/1562139?v=3","gravatar_id":"","url":"https://api.github.com/users/reneme","html_url":"https://github.com/reneme","followers_url":"https://api.github.com/users/reneme/followers","following_url":"https://api.github.com/users/reneme/following{/other_user}","gists_url":"https://api.github.com/users/reneme/gists{/gist_id}","starred_url":"https://api.github.com/users/reneme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reneme/subscriptions","organizations_url":"https://api.github.com/users/reneme/orgs","repos_url":"https://api.github.com/users/reneme/repos","events_url":"https://api.github.com/users/reneme/events{/privacy}","received_events_url":"https://api.github.com/users/reneme/received_events","type":"User","site_admin":false},"body":"shouldn't that be `... = kTagReserved`?\r\n\r\nAh! No... it is again exploiting the fact that `ReservedBlockCtl` stores its `size < 0`. ","created_at":"2016-03-02T15:04:47Z","updated_at":"2016-03-02T15:04:47Z","html_url":"https://github.com/cvmfs/cvmfs/pull/1524#discussion_r54734551","pull_request_url":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524","_links":{"self":{"href":"https://api.github.com/repos/cvmfs/cvmfs/pulls/comments/54734551"},"html":{"href":"https://github.com/cvmfs/cvmfs/pull/1524#discussion_r54734551"},"pull_request":{"href":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524"}}},"pull_request":{"url":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524","id":61382290,"html_url":"https://github.com/cvmfs/cvmfs/pull/1524","diff_url":"https://github.com/cvmfs/cvmfs/pull/1524.diff","patch_url":"https://github.com/cvmfs/cvmfs/pull/1524.patch","issue_url":"https://api.github.com/repos/cvmfs/cvmfs/issues/1524","number":1524,"state":"open","locked":false,"title":"Fixes and improvements in the memory management","user":{"login":"jblomer","id":1557360,"avatar_url":"https://avatars.githubusercontent.com/u/1557360?v=3","gravatar_id":"","url":"https://api.github.com/users/jblomer","html_url":"https://github.com/jblomer","followers_url":"https://api.github.com/users/jblomer/followers","following_url":"https://api.github.com/users/jblomer/following{/other_user}","gists_url":"https://api.github.com/users/jblomer/gists{/gist_id}","starred_url":"https://api.github.com/users/jblomer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jblomer/subscriptions","organizations_url":"https://api.github.com/users/jblomer/orgs","repos_url":"https://api.github.com/users/jblomer/repos","events_url":"https://api.github.com/users/jblomer/events{/privacy}","received_events_url":"https://api.github.com/users/jblomer/received_events","type":"User","site_admin":false},"body":"- Fixes a few small memory leaks during reload of the libcvmfs_fuse library\r\n- Update sqlite library\r\n- Add a dedicated memory manager for sqlite.  This ensures that sqlite's memory needs don't interfere with other mallocs and significantly reduces memory fragmentation\r\n- Revert too pessimistic setting of fuse page cache\r\n- Remove a few unused fields from `DirectoryEntry`\r\n- Remove unused lookup of directory entries by inode\r\n- Avoid unloading the libcvmfs_fuse library under valgrind for better debugging (symbol resolution)\r\n- Add per-database memory statistics to `cvmfs_talk internal affairs`\r\n- Add `cvmfs_talk detach nested` to emulate what happens when a new root catalog comes in","created_at":"2016-03-02T10:51:55Z","updated_at":"2016-03-02T15:04:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a165dd7492f45de71ff5428ecbb332cca0d7883d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524/commits","review_comments_url":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524/comments","review_comment_url":"https://api.github.com/repos/cvmfs/cvmfs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cvmfs/cvmfs/issues/1524/comments","statuses_url":"https://api.github.com/repos/cvmfs/cvmfs/statuses/33c7ee9a12d6ef21f9f5ac73e05f84a4bdab34a7","head":{"label":"cvmfs:fix-mem","ref":"fix-mem","sha":"33c7ee9a12d6ef21f9f5ac73e05f84a4bdab34a7","user":{"login":"cvmfs","id":1560859,"avatar_url":"https://avatars.githubusercontent.com/u/1560859?v=3","gravatar_id":"","url":"https://api.github.com/users/cvmfs","html_url":"https://github.com/cvmfs","followers_url":"https://api.github.com/users/cvmfs/followers","following_url":"https://api.github.com/users/cvmfs/following{/other_user}","gists_url":"https://api.github.com/users/cvmfs/gists{/gist_id}","starred_url":"https://api.github.com/users/cvmfs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cvmfs/subscriptions","organizations_url":"https://api.github.com/users/cvmfs/orgs","repos_url":"https://api.github.com/users/cvmfs/repos","events_url":"https://api.github.com/users/cvmfs/events{/privacy}","received_events_url":"https://api.github.com/users/cvmfs/received_events","type":"Organization","site_admin":false},"repo":{"id":3784908,"name":"cvmfs","full_name":"cvmfs/cvmfs","owner":{"login":"cvmfs","id":1560859,"avatar_url":"https://avatars.githubusercontent.com/u/1560859?v=3","gravatar_id":"","url":"https://api.github.com/users/cvmfs","html_url":"https://github.com/cvmfs","followers_url":"https://api.github.com/users/cvmfs/followers","following_url":"https://api.github.com/users/cvmfs/following{/other_user}","gists_url":"https://api.github.com/users/cvmfs/gists{/gist_id}","starred_url":"https://api.github.com/users/cvmfs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cvmfs/subscriptions","organizations_url":"https://api.github.com/users/cvmfs/orgs","repos_url":"https://api.github.com/users/cvmfs/repos","events_url":"https://api.github.com/users/cvmfs/events{/privacy}","received_events_url":"https://api.github.com/users/cvmfs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cvmfs/cvmfs","description":"The CernVM File System","fork":false,"url":"https://api.github.com/repos/cvmfs/cvmfs","forks_url":"https://api.github.com/repos/cvmfs/cvmfs/forks","keys_url":"https://api.github.com/repos/cvmfs/cvmfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cvmfs/cvmfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cvmfs/cvmfs/teams","hooks_url":"https://api.github.com/repos/cvmfs/cvmfs/hooks","issue_events_url":"https://api.github.com/repos/cvmfs/cvmfs/issues/events{/number}","events_url":"https://api.github.com/repos/cvmfs/cvmfs/events","assignees_url":"https://api.github.com/repos/cvmfs/cvmfs/assignees{/user}","branches_url":"https://api.github.com/repos/cvmfs/cvmfs/branches{/branch}","tags_url":"https://api.github.com/repos/cvmfs/cvmfs/tags","blobs_url":"https://api.github.com/repos/cvmfs/cvmfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cvmfs/cvmfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cvmfs/cvmfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/cvmfs/cvmfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cvmfs/cvmfs/statuses/{sha}","languages_url":"https://api.github.com/repos/cvmfs/cvmfs/languages","stargazers_url":"https://api.github.com/repos/cvmfs/cvmfs/stargazers","contributors_url":"https://api.github.com/repos/cvmfs/cvmfs/contributors","subscribers_url":"https://api.github.com/repos/cvmfs/cvmfs/subscribers","subscription_url":"https://api.github.com/repos/cvmfs/cvmfs/subscription","commits_url":"https://api.github.com/repos/cvmfs/cvmfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/cvmfs/cvmfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/cvmfs/cvmfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/cvmfs/cvmfs/issues/comments{/number}","contents_url":"https://api.github.com/repos/cvmfs/cvmfs/contents/{+path}","compare_url":"https://api.github.com/repos/cvmfs/cvmfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cvmfs/cvmfs/merges","archive_url":"https://api.github.com/repos/cvmfs/cvmfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cvmfs/cvmfs/downloads","issues_url":"https://api.github.com/repos/cvmfs/cvmfs/issues{/number}","pulls_url":"https://api.github.com/repos/cvmfs/cvmfs/pulls{/number}","milestones_url":"https://api.github.com/repos/cvmfs/cvmfs/milestones{/number}","notifications_url":"https://api.github.com/repos/cvmfs/cvmfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cvmfs/cvmfs/labels{/name}","releases_url":"https://api.github.com/repos/cvmfs/cvmfs/releases{/id}","deployments_url":"https://api.github.com/repos/cvmfs/cvmfs/deployments","created_at":"2012-03-21T09:10:41Z","updated_at":"2016-01-07T01:22:11Z","pushed_at":"2016-03-02T13:24:49Z","git_url":"git://github.com/cvmfs/cvmfs.git","ssh_url":"git@github.com:cvmfs/cvmfs.git","clone_url":"https://github.com/cvmfs/cvmfs.git","svn_url":"https://github.com/cvmfs/cvmfs","homepage":"http://cernvm.cern.ch/portal/filesystem","size":103782,"stargazers_count":40,"watchers_count":40,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":44,"mirror_url":null,"open_issues_count":10,"forks":44,"open_issues":10,"watchers":40,"default_branch":"devel"}},"base":{"label":"cvmfs:devel","ref":"devel","sha":"59a71243a9b1989924c3e246fdc279c7c4c4ab50","user":{"login":"cvmfs","id":1560859,"avatar_url":"https://avatars.githubusercontent.com/u/1560859?v=3","gravatar_id":"","url":"https://api.github.com/users/cvmfs","html_url":"https://github.com/cvmfs","followers_url":"https://api.github.com/users/cvmfs/followers","following_url":"https://api.github.com/users/cvmfs/following{/other_user}","gists_url":"https://api.github.com/users/cvmfs/gists{/gist_id}","starred_url":"https://api.github.com/users/cvmfs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cvmfs/subscriptions","organizations_url":"https://api.github.com/users/cvmfs/orgs","repos_url":"https://api.github.com/users/cvmfs/repos","events_url":"https://api.github.com/users/cvmfs/events{/privacy}","received_events_url":"https://api.github.com/users/cvmfs/received_events","type":"Organization","site_admin":false},"repo":{"id":3784908,"name":"cvmfs","full_name":"cvmfs/cvmfs","owner":{"login":"cvmfs","id":1560859,"avatar_url":"https://avatars.githubusercontent.com/u/1560859?v=3","gravatar_id":"","url":"https://api.github.com/users/cvmfs","html_url":"https://github.com/cvmfs","followers_url":"https://api.github.com/users/cvmfs/followers","following_url":"https://api.github.com/users/cvmfs/following{/other_user}","gists_url":"https://api.github.com/users/cvmfs/gists{/gist_id}","starred_url":"https://api.github.com/users/cvmfs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cvmfs/subscriptions","organizations_url":"https://api.github.com/users/cvmfs/orgs","repos_url":"https://api.github.com/users/cvmfs/repos","events_url":"https://api.github.com/users/cvmfs/events{/privacy}","received_events_url":"https://api.github.com/users/cvmfs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cvmfs/cvmfs","description":"The CernVM File System","fork":false,"url":"https://api.github.com/repos/cvmfs/cvmfs","forks_url":"https://api.github.com/repos/cvmfs/cvmfs/forks","keys_url":"https://api.github.com/repos/cvmfs/cvmfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cvmfs/cvmfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cvmfs/cvmfs/teams","hooks_url":"https://api.github.com/repos/cvmfs/cvmfs/hooks","issue_events_url":"https://api.github.com/repos/cvmfs/cvmfs/issues/events{/number}","events_url":"https://api.github.com/repos/cvmfs/cvmfs/events","assignees_url":"https://api.github.com/repos/cvmfs/cvmfs/assignees{/user}","branches_url":"https://api.github.com/repos/cvmfs/cvmfs/branches{/branch}","tags_url":"https://api.github.com/repos/cvmfs/cvmfs/tags","blobs_url":"https://api.github.com/repos/cvmfs/cvmfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cvmfs/cvmfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cvmfs/cvmfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/cvmfs/cvmfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cvmfs/cvmfs/statuses/{sha}","languages_url":"https://api.github.com/repos/cvmfs/cvmfs/languages","stargazers_url":"https://api.github.com/repos/cvmfs/cvmfs/stargazers","contributors_url":"https://api.github.com/repos/cvmfs/cvmfs/contributors","subscribers_url":"https://api.github.com/repos/cvmfs/cvmfs/subscribers","subscription_url":"https://api.github.com/repos/cvmfs/cvmfs/subscription","commits_url":"https://api.github.com/repos/cvmfs/cvmfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/cvmfs/cvmfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/cvmfs/cvmfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/cvmfs/cvmfs/issues/comments{/number}","contents_url":"https://api.github.com/repos/cvmfs/cvmfs/contents/{+path}","compare_url":"https://api.github.com/repos/cvmfs/cvmfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cvmfs/cvmfs/merges","archive_url":"https://api.github.com/repos/cvmfs/cvmfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cvmfs/cvmfs/downloads","issues_url":"https://api.github.com/repos/cvmfs/cvmfs/issues{/number}","pulls_url":"https://api.github.com/repos/cvmfs/cvmfs/pulls{/number}","milestones_url":"https://api.github.com/repos/cvmfs/cvmfs/milestones{/number}","notifications_url":"https://api.github.com/repos/cvmfs/cvmfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cvmfs/cvmfs/labels{/name}","releases_url":"https://api.github.com/repos/cvmfs/cvmfs/releases{/id}","deployments_url":"https://api.github.com/repos/cvmfs/cvmfs/deployments","created_at":"2012-03-21T09:10:41Z","updated_at":"2016-01-07T01:22:11Z","pushed_at":"2016-03-02T13:24:49Z","git_url":"git://github.com/cvmfs/cvmfs.git","ssh_url":"git@github.com:cvmfs/cvmfs.git","clone_url":"https://github.com/cvmfs/cvmfs.git","svn_url":"https://github.com/cvmfs/cvmfs","homepage":"http://cernvm.cern.ch/portal/filesystem","size":103782,"stargazers_count":40,"watchers_count":40,"language":"C","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":44,"mirror_url":null,"open_issues_count":10,"forks":44,"open_issues":10,"watchers":40,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524"},"html":{"href":"https://github.com/cvmfs/cvmfs/pull/1524"},"issue":{"href":"https://api.github.com/repos/cvmfs/cvmfs/issues/1524"},"comments":{"href":"https://api.github.com/repos/cvmfs/cvmfs/issues/1524/comments"},"review_comments":{"href":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524/comments"},"review_comment":{"href":"https://api.github.com/repos/cvmfs/cvmfs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cvmfs/cvmfs/pulls/1524/commits"},"statuses":{"href":"https://api.github.com/repos/cvmfs/cvmfs/statuses/33c7ee9a12d6ef21f9f5ac73e05f84a4bdab34a7"}}}}