{"action":"created","comment":{"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments/54819689","id":54819689,"diff_hunk":"@@ -0,0 +1,79 @@\n+//\n+//  CBLMultipartBuffer.m\n+//  CouchbaseLite\n+//\n+//  Created by Robert Payne on 1/03/16.\n+//  Copyright © 2016 Couchbase, Inc. All rights reserved.\n+//\n+\n+#import \"CBLMultipartBuffer.h\"\n+\n+@interface CBLMultipartBuffer() {\n+    NSMutableData *_data;\n+    NSUInteger _offset;\n+}\n+\n+@end\n+@implementation CBLMultipartBuffer\n+\n+@synthesize compactionLength=_compactionLength;\n+\n+#pragma mark - Initialization\n+\n+- (instancetype)init {\n+    if((self = [super init])) {\n+        _data = [NSMutableData dataWithCapacity:1024];\n+        _offset = 0;\n+        _compactionLength = 4096;\n+    }\n+    return self;\n+}\n+\n+#pragma mark - Actions\n+\n+- (BOOL)advance:(NSUInteger)amount {\n+    if (_offset + amount >= _data.length) {\n+        Warn(@\"Preventing unsafe buffer overflow\", nil);","path":"Source/CBLMultipartBuffer.m","position":36,"original_position":36,"commit_id":"0d0cbabe0a90839a4e906899d06559e59957976b","original_commit_id":"0d0cbabe0a90839a4e906899d06559e59957976b","user":{"login":"snej","id":43241,"avatar_url":"https://avatars.githubusercontent.com/u/43241?v=3","gravatar_id":"","url":"https://api.github.com/users/snej","html_url":"https://github.com/snej","followers_url":"https://api.github.com/users/snej/followers","following_url":"https://api.github.com/users/snej/following{/other_user}","gists_url":"https://api.github.com/users/snej/gists{/gist_id}","starred_url":"https://api.github.com/users/snej/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snej/subscriptions","organizations_url":"https://api.github.com/users/snej/orgs","repos_url":"https://api.github.com/users/snej/repos","events_url":"https://api.github.com/users/snej/events{/privacy}","received_events_url":"https://api.github.com/users/snej/received_events","type":"User","site_admin":false},"body":"The `nil` parameter isn't needed.","created_at":"2016-03-03T00:46:45Z","updated_at":"2016-03-03T00:46:45Z","html_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1149#discussion_r54819689","pull_request_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149","_links":{"self":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments/54819689"},"html":{"href":"https://github.com/couchbase/couchbase-lite-ios/pull/1149#discussion_r54819689"},"pull_request":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149"}}},"pull_request":{"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149","id":61077415,"html_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1149","diff_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1149.diff","patch_url":"https://github.com/couchbase/couchbase-lite-ios/pull/1149.patch","issue_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1149","number":1149,"state":"open","locked":false,"title":"Improve multipart reading performance using a cyclic buffer","user":{"login":"robertjpayne","id":214288,"avatar_url":"https://avatars.githubusercontent.com/u/214288?v=3","gravatar_id":"","url":"https://api.github.com/users/robertjpayne","html_url":"https://github.com/robertjpayne","followers_url":"https://api.github.com/users/robertjpayne/followers","following_url":"https://api.github.com/users/robertjpayne/following{/other_user}","gists_url":"https://api.github.com/users/robertjpayne/gists{/gist_id}","starred_url":"https://api.github.com/users/robertjpayne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robertjpayne/subscriptions","organizations_url":"https://api.github.com/users/robertjpayne/orgs","repos_url":"https://api.github.com/users/robertjpayne/repos","events_url":"https://api.github.com/users/robertjpayne/events{/privacy}","received_events_url":"https://api.github.com/users/robertjpayne/received_events","type":"User","site_admin":false},"body":"The CBLMultipartReader is somewhat slow parsing on older devices. This is almost entirely caused by the `[CBLMultipartReader deleteUpThrough:]` API, mostly because this particular NSMutableData API is very slow though even a realloc here wouldn't be that great.\r\n\r\nThis slowness is easily observable on an older device ( iPhone 4S in my case ) with instruments time profiler.\r\n\r\nThis PR addresses this by bringing in a more cyclic style buffer that appends data and maintains a offset/bytes pointer and finally compacts itself once it's past a certain amount of data.\r\n\r\nThis change makes most of the memory operations inside the `CBLMutlipartReader` negligible.","created_at":"2016-02-29T13:28:23Z","updated_at":"2016-03-03T00:46:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8adc5eb93435bee24818556b8e3a77e635fd072a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149/commits","review_comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149/comments","review_comment_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments{/number}","comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1149/comments","statuses_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/0d0cbabe0a90839a4e906899d06559e59957976b","head":{"label":"robertjpayne:feature/multipart-buffer","ref":"feature/multipart-buffer","sha":"0d0cbabe0a90839a4e906899d06559e59957976b","user":{"login":"robertjpayne","id":214288,"avatar_url":"https://avatars.githubusercontent.com/u/214288?v=3","gravatar_id":"","url":"https://api.github.com/users/robertjpayne","html_url":"https://github.com/robertjpayne","followers_url":"https://api.github.com/users/robertjpayne/followers","following_url":"https://api.github.com/users/robertjpayne/following{/other_user}","gists_url":"https://api.github.com/users/robertjpayne/gists{/gist_id}","starred_url":"https://api.github.com/users/robertjpayne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robertjpayne/subscriptions","organizations_url":"https://api.github.com/users/robertjpayne/orgs","repos_url":"https://api.github.com/users/robertjpayne/repos","events_url":"https://api.github.com/users/robertjpayne/events{/privacy}","received_events_url":"https://api.github.com/users/robertjpayne/received_events","type":"User","site_admin":false},"repo":{"id":52791052,"name":"couchbase-lite-ios","full_name":"robertjpayne/couchbase-lite-ios","owner":{"login":"robertjpayne","id":214288,"avatar_url":"https://avatars.githubusercontent.com/u/214288?v=3","gravatar_id":"","url":"https://api.github.com/users/robertjpayne","html_url":"https://github.com/robertjpayne","followers_url":"https://api.github.com/users/robertjpayne/followers","following_url":"https://api.github.com/users/robertjpayne/following{/other_user}","gists_url":"https://api.github.com/users/robertjpayne/gists{/gist_id}","starred_url":"https://api.github.com/users/robertjpayne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robertjpayne/subscriptions","organizations_url":"https://api.github.com/users/robertjpayne/orgs","repos_url":"https://api.github.com/users/robertjpayne/repos","events_url":"https://api.github.com/users/robertjpayne/events{/privacy}","received_events_url":"https://api.github.com/users/robertjpayne/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/robertjpayne/couchbase-lite-ios","description":"Lightweight, embedded, syncable NoSQL database engine for iOS (and Mac!) apps.","fork":true,"url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios","forks_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/forks","keys_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/keys{/key_id}","collaborators_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/teams","hooks_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/hooks","issue_events_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/issues/events{/number}","events_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/events","assignees_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/assignees{/user}","branches_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/branches{/branch}","tags_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/tags","blobs_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/git/refs{/sha}","trees_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/git/trees{/sha}","statuses_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/statuses/{sha}","languages_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/languages","stargazers_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/stargazers","contributors_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/contributors","subscribers_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/subscribers","subscription_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/subscription","commits_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/commits{/sha}","git_commits_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/git/commits{/sha}","comments_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/comments{/number}","issue_comment_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/issues/comments{/number}","contents_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/contents/{+path}","compare_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/compare/{base}...{head}","merges_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/merges","archive_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/downloads","issues_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/issues{/number}","pulls_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/pulls{/number}","milestones_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/milestones{/number}","notifications_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/labels{/name}","releases_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/releases{/id}","deployments_url":"https://api.github.com/repos/robertjpayne/couchbase-lite-ios/deployments","created_at":"2016-02-29T12:58:00Z","updated_at":"2016-02-29T12:58:02Z","pushed_at":"2016-03-02T22:41:36Z","git_url":"git://github.com/robertjpayne/couchbase-lite-ios.git","ssh_url":"git@github.com:robertjpayne/couchbase-lite-ios.git","clone_url":"https://github.com/robertjpayne/couchbase-lite-ios.git","svn_url":"https://github.com/robertjpayne/couchbase-lite-ios","homepage":"","size":56673,"stargazers_count":0,"watchers_count":0,"language":"Objective-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":"couchbase:dev","ref":"dev","sha":"2f8d24026da25e6148ec112e47352d8a9da1663e","user":{"login":"couchbase","id":605755,"avatar_url":"https://avatars.githubusercontent.com/u/605755?v=3","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"repo":{"id":7948548,"name":"couchbase-lite-ios","full_name":"couchbase/couchbase-lite-ios","owner":{"login":"couchbase","id":605755,"avatar_url":"https://avatars.githubusercontent.com/u/605755?v=3","gravatar_id":"","url":"https://api.github.com/users/couchbase","html_url":"https://github.com/couchbase","followers_url":"https://api.github.com/users/couchbase/followers","following_url":"https://api.github.com/users/couchbase/following{/other_user}","gists_url":"https://api.github.com/users/couchbase/gists{/gist_id}","starred_url":"https://api.github.com/users/couchbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/couchbase/subscriptions","organizations_url":"https://api.github.com/users/couchbase/orgs","repos_url":"https://api.github.com/users/couchbase/repos","events_url":"https://api.github.com/users/couchbase/events{/privacy}","received_events_url":"https://api.github.com/users/couchbase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/couchbase/couchbase-lite-ios","description":"Lightweight, embedded, syncable NoSQL database engine for iOS (and Mac!) apps.","fork":false,"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios","forks_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/forks","keys_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/keys{/key_id}","collaborators_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/teams","hooks_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/hooks","issue_events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/events{/number}","events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/events","assignees_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/assignees{/user}","branches_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/branches{/branch}","tags_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/tags","blobs_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/refs{/sha}","trees_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/trees{/sha}","statuses_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/{sha}","languages_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/languages","stargazers_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/stargazers","contributors_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/contributors","subscribers_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/subscribers","subscription_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/subscription","commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/commits{/sha}","git_commits_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/git/commits{/sha}","comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/comments{/number}","issue_comment_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/comments{/number}","contents_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/contents/{+path}","compare_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/compare/{base}...{head}","merges_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/merges","archive_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/downloads","issues_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues{/number}","pulls_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls{/number}","milestones_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/milestones{/number}","notifications_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/labels{/name}","releases_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/releases{/id}","deployments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/deployments","created_at":"2013-02-01T00:09:26Z","updated_at":"2016-03-02T18:34:13Z","pushed_at":"2016-03-02T22:41:36Z","git_url":"git://github.com/couchbase/couchbase-lite-ios.git","ssh_url":"git@github.com:couchbase/couchbase-lite-ios.git","clone_url":"https://github.com/couchbase/couchbase-lite-ios.git","svn_url":"https://github.com/couchbase/couchbase-lite-ios","homepage":"","size":59556,"stargazers_count":976,"watchers_count":976,"language":"Objective-C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":189,"mirror_url":null,"open_issues_count":76,"forks":189,"open_issues":76,"watchers":976,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149"},"html":{"href":"https://github.com/couchbase/couchbase-lite-ios/pull/1149"},"issue":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1149"},"comments":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1149/comments"},"review_comments":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149/comments"},"review_comment":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/pulls/1149/commits"},"statuses":{"href":"https://api.github.com/repos/couchbase/couchbase-lite-ios/statuses/0d0cbabe0a90839a4e906899d06559e59957976b"}}}}