{"action":"created","comment":{"url":"https://api.github.com/repos/facebook/zstd/pulls/comments/150951653","pull_request_review_id":76581057,"id":150951653,"diff_hunk":"@@ -423,237 +424,241 @@ size_t ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,\n     const BYTE* const base = ctx->base;\n     const BYTE* const prefixStart = base + ctx->dictLimit;\n \n-    const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;\n-    const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;\n-    const U32 mls = ctx->appliedParams.cParams.searchLength;\n-    const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;\n+    U32 const maxSearches = 1U << ctx->appliedParams.cParams.searchLog;\n+    U32 const sufficient_len = MIN(ctx->appliedParams.cParams.targetLength, ZSTD_OPT_NUM -1);\n+    U32 const mls = ctx->appliedParams.cParams.searchLength;\n+    U32 const minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;\n \n-    ZSTD_optimal_t* opt = optStatePtr->priceTable;\n-    ZSTD_match_t* matches = optStatePtr->matchTable;\n-    const BYTE* inr;\n-    U32 offset, rep[ZSTD_REP_NUM];\n+    ZSTD_optimal_t* const opt = optStatePtr->priceTable;\n+    ZSTD_match_t* const matches = optStatePtr->matchTable;\n+    U32 rep[ZSTD_REP_NUM];\n \n     /* init */\n     ctx->nextToUpdate3 = ctx->nextToUpdate;\n     ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize);\n     ip += (ip==prefixStart);\n-    { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=seqStorePtr->rep[i]; }\n+    { int i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=seqStorePtr->rep[i]; }\n \n     /* Match Loop */\n     while (ip < ilimit) {\n-        U32 cur, match_num, last_pos, litlen, price;\n-        U32 u, mlen, best_mlen, best_off, litLength;\n+        U32 cur, last_pos = 0;\n+        U32 best_mlen, best_off;\n+        U32 const initLL = (U32)(ip - anchor);\n         memset(opt, 0, sizeof(ZSTD_optimal_t));\n-        last_pos = 0;\n-        litlen = (U32)(ip - anchor);\n \n         /* check repCode */\n-        {   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);\n-            for (i=(ip == anchor); i<last_i; i++) {\n-                const S32 repCur = (i==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : rep[i];\n-                if ( (repCur > 0) && (repCur < (S32)(ip-prefixStart))\n-                    && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repCur, minMatch))) {\n-                    mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;\n-                    if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {\n-                        best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;\n-                        goto _storeSequence;\n+        {   U32 const ll0 = !initLL;\n+            U32 const lastR = ZSTD_REP_CHECK + ll0;\n+            U32 repCode;\n+            for (repCode = ll0; repCode < lastR; repCode++) {\n+                S32 const repOffset = (repCode==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : rep[repCode];\n+                if ( (repOffset > 0)\n+                  && (repOffset < (S32)(ip-prefixStart))  /* within current mem segment */\n+                  && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {\n+                    U32 repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iend) + minMatch;\n+                    if (repLen > sufficient_len) {\n+                        /* large repMatch => immediate encoding */\n+                        best_mlen = repLen; best_off = repCode; cur = 0; last_pos = 1;\n+                        goto _shortestPath;\n                     }\n-                    best_off = i - (ip == anchor);\n                     do {\n-                        price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);\n-                        if (mlen > last_pos || price < opt[mlen].price)\n-                            SET_PRICE(mlen, mlen, i, litlen, price);   /* note : macro modifies last_pos */\n-                        mlen--;\n-                    } while (mlen >= minMatch);\n+                        U32 const repPrice = ZSTD_getPrice(optStatePtr, initLL, anchor, repCode - ll0, repLen, ultra);\n+                        if (repLen > last_pos || repPrice < opt[repLen].price)\n+                            SET_PRICE(repLen, repLen, repCode, initLL, repPrice);   /* note : macro modifies last_pos */\n+                        repLen--;\n+                    } while (repLen >= minMatch);\n         }   }   }\n \n-        match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);\n+        {   U32 const nb_matches = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);\n \n-        if (!last_pos && !match_num) { ip++; continue; }\n+            if (!last_pos /*no repCode*/ && !nb_matches /*no match*/) { ip++; continue; }\n \n-        if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {\n-            best_mlen = matches[match_num-1].len;\n-            best_off = matches[match_num-1].off;\n-            cur = 0;\n-            last_pos = 1;\n-            goto _storeSequence;\n-        }\n+            if (nb_matches && (matches[nb_matches-1].len > sufficient_len)) {\n+                /* large match => immediate encoding */\n+                best_mlen = matches[nb_matches-1].len;\n+                best_off = matches[nb_matches-1].off;\n+                cur = 0;\n+                last_pos = 1;\n+                goto _shortestPath;\n+            }\n \n-        /* set prices using matches at position = 0 */\n-        best_mlen = (last_pos) ? last_pos : minMatch;\n-        for (u = 0; u < match_num; u++) {\n-            mlen = (u>0) ? matches[u-1].len+1 : best_mlen;\n-            best_mlen = matches[u].len;\n-            while (mlen <= best_mlen) {\n-                price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);\n-                if (mlen > last_pos || price < opt[mlen].price)\n-                    SET_PRICE(mlen, mlen, matches[u].off, litlen, price);   /* note : macro modifies last_pos */\n-                mlen++;\n-        }   }\n+            /* set prices for first matches from position == 0 */\n+            {   U32 matchNb;\n+                U32 pos = last_pos /*some repCode (assumed cheaper)*/ ? last_pos : minMatch;\n+                for (matchNb = 0; matchNb < nb_matches; matchNb++) {\n+                    U32 const end = matches[matchNb].len;\n+                    while (pos <= end) {\n+                        U32 const matchPrice = ZSTD_getPrice(optStatePtr, initLL, anchor, matches[matchNb].off-1, pos, ultra);\n+                        if (pos > last_pos || matchPrice < opt[pos].price)\n+                            SET_PRICE(pos, pos, matches[matchNb].off, initLL, matchPrice);   /* note : macro modifies last_pos */\n+                        pos++;\n+        }   }   }   }\n \n         if (last_pos < minMatch) { ip++; continue; }\n \n         /* initialize opt[0] */\n         { U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }\n         opt[0].mlen = 1;\n-        opt[0].litlen = litlen;\n+        opt[0].litlen = initLL;\n \n-         /* check further positions */\n+        /* check further positions */\n         for (cur = 1; cur <= last_pos; cur++) {\n-           inr = ip + cur;\n+            const BYTE* const inr = ip + cur;\n+            assert(cur < ZSTD_OPT_NUM);\n \n-           if (opt[cur-1].mlen == 1) {\n-                litlen = opt[cur-1].litlen + 1;\n+            /* Fix current position with one literal if cheaper */\n+            {   U32 const litlen = (opt[cur-1].mlen == 1) ? opt[cur-1].litlen + 1 : 1;\n+                U32 price;\n                 if (cur > litlen) {\n                     price = opt[cur - litlen].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-litlen);\n-                } else\n+                } else {\n                     price = ZSTD_getLiteralPrice(optStatePtr, litlen, anchor);\n-           } else {\n-                litlen = 1;\n-                price = opt[cur - 1].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-1);\n-           }\n-\n-           if (cur > last_pos || price <= opt[cur].price)\n-                SET_PRICE(cur, 1, 0, litlen, price);\n+                }\n+                if (cur > last_pos || price <= opt[cur].price)\n+                    SET_PRICE(cur, 1, 0, litlen, price);  /* note : macro modifies last_pos */\n+            }\n \n-           if (cur == last_pos) break;\n+            if (cur == last_pos) break;\n \n-           if (inr > ilimit)  /* last match must start at a minimum distance of 8 from oend */\n-               continue;\n-\n-           mlen = opt[cur].mlen;\n-           if (opt[cur].off > ZSTD_REP_MOVE_OPT) {\n-                opt[cur].rep[2] = opt[cur-mlen].rep[1];\n-                opt[cur].rep[1] = opt[cur-mlen].rep[0];\n-                opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;\n-           } else {\n-                opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];\n-                opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];\n-                /* If opt[cur].off == ZSTD_REP_MOVE_OPT, then mlen != 1.\n-                 * offset ZSTD_REP_MOVE_OPT is used for the special case\n-                 * litLength == 0, where offset 0 means something special.\n-                 * mlen == 1 means the previous byte was stored as a literal,\n-                 * so they are mutually exclusive.\n-                 */\n-                assert(!(opt[cur].off == ZSTD_REP_MOVE_OPT && mlen == 1));\n-                opt[cur].rep[0] = (opt[cur].off == ZSTD_REP_MOVE_OPT) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);\n-           }\n+            /* last match must start at a minimum distance of 8 from oend */\n+            if (inr > ilimit) continue;\n+\n+            /* update repcodes */\n+            {   U32 const mlen = opt[cur].mlen;\n+                if (opt[cur].off > ZSTD_REP_MOVE_OPT) {\n+                    opt[cur].rep[2] = opt[cur-mlen].rep[1];\n+                    opt[cur].rep[1] = opt[cur-mlen].rep[0];\n+                    opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;\n+                } else {\n+                    opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];\n+                    opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];\n+                    /* If opt[cur].off == ZSTD_REP_MOVE_OPT, then mlen != 1.\n+                     * offset ZSTD_REP_MOVE_OPT is used for the special case\n+                     * litLength == 0, where offset 0 means something special.\n+                     * mlen == 1 means the previous byte was stored as a literal,\n+                     * so they are mutually exclusive.\n+                     */\n+                    assert(!(opt[cur].off == ZSTD_REP_MOVE_OPT && mlen == 1));\n+                    opt[cur].rep[0] = (opt[cur].off == ZSTD_REP_MOVE_OPT) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);\n+            }   }\n \n             best_mlen = minMatch;\n-            {   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);\n-                for (i=(opt[cur].mlen != 1); i<last_i; i++) {  /* check rep */\n-                    const S32 repCur = (i==ZSTD_REP_MOVE_OPT) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i];\n-                    if ( (repCur > 0) && (repCur < (S32)(inr-prefixStart))\n-                       && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) {\n-                       mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;\n-\n-                       if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {\n-                            best_mlen = mlen; best_off = i; last_pos = cur + 1;\n-                            goto _storeSequence;\n-                       }\n+            {   U32 const ll0 = (opt[cur].mlen != 1);\n+                U32 const lastR = ZSTD_REP_CHECK + ll0;\n+                U32 repCode4;  /* universal referential */\n+                for (repCode4=ll0; repCode4<lastR; repCode4++) {  /* check rep */\n+                    const S32 repCur = (repCode4==ZSTD_REP_MOVE_OPT) ? (opt[cur].rep[0] - 1) : opt[cur].rep[repCode4];\n+                    if ( (repCur > 0) && (repCur < (S32)(inr-prefixStart))  /* within current mem segment */\n+                      && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) {\n+                        U32 matchLength = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;\n+                        U32 const repCode3 = repCode4 - ll0;  /* contextual referential, depends on ll0 */\n+                        assert(repCode3 < 3);\n+\n+                        if (matchLength > sufficient_len || cur + matchLength >= ZSTD_OPT_NUM) {\n+                            best_mlen = matchLength;\n+                            best_off = repCode4;\n+                            last_pos = cur + 1;\n+                            goto _shortestPath;\n+                        }\n \n-                       best_off = i - (opt[cur].mlen != 1);\n-                       if (mlen > best_mlen) best_mlen = mlen;\n+                        if (matchLength > best_mlen) best_mlen = matchLength;\n \n-                       do {\n-                           if (opt[cur].mlen == 1) {\n-                                litlen = opt[cur].litlen;\n-                                if (cur > litlen) {\n-                                    price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);\n-                                } else\n-                                    price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);\n+                        do {\n+                            U32 const litlen = ll0 ? 0 : opt[cur].litlen;\n+                            U32 price;\n+                            if (cur > litlen) {\n+                                price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, inr-litlen, repCode3, matchLength, ultra);\n                             } else {\n-                                litlen = 0;\n-                                price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);\n+                                price = ZSTD_getPrice(optStatePtr, litlen, anchor, repCode3, matchLength, ultra);\n                             }\n \n-                            if (cur + mlen > last_pos || price <= opt[cur + mlen].price)\n-                                SET_PRICE(cur + mlen, mlen, i, litlen, price);\n-                            mlen--;\n-                        } while (mlen >= minMatch);\n+                            if (cur + matchLength > last_pos || price <= opt[cur + matchLength].price)\n+                                SET_PRICE(cur + matchLength, matchLength, repCode4, litlen, price);  /* note : macro modifies last_pos */\n+                            matchLength--;\n+                        } while (matchLength >= minMatch);\n             }   }   }\n \n-            match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);\n+            {   U32 const nb_matches = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen /*largest repLength*/);   /* search for matches larger than repcodes */\n+                U32 matchNb;\n \n-            if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {\n-                best_mlen = matches[match_num-1].len;\n-                best_off = matches[match_num-1].off;\n-                last_pos = cur + 1;\n-                goto _storeSequence;\n-            }\n+                if (nb_matches > 0 && (matches[nb_matches-1].len > sufficient_len || cur + matches[nb_matches-1].len >= ZSTD_OPT_NUM)) {\n+                    best_mlen = matches[nb_matches-1].len;\n+                    best_off = matches[nb_matches-1].off;\n+                    last_pos = cur + 1;\n+                    goto _shortestPath;\n+                }\n \n-            /* set prices using matches at position = cur */\n-            for (u = 0; u < match_num; u++) {\n-                mlen = (u>0) ? matches[u-1].len+1 : best_mlen;\n-                best_mlen = matches[u].len;\n+                /* set prices using matches at position = cur */\n+                for (matchNb = 0; matchNb < nb_matches; matchNb++) {\n+                    U32 mlen = (matchNb>0) ? matches[matchNb-1].len+1 : best_mlen;","path":"lib/compress/zstd_opt.c","position":532,"original_position":532,"commit_id":"72c0f4574cfef1d5d5f35fc7277ee353793956ab","original_commit_id":"72c0f4574cfef1d5d5f35fc7277ee353793956ab","user":{"login":"Cyan4973","id":750081,"avatar_url":"https://avatars0.githubusercontent.com/u/750081?v=4","gravatar_id":"","url":"https://api.github.com/users/Cyan4973","html_url":"https://github.com/Cyan4973","followers_url":"https://api.github.com/users/Cyan4973/followers","following_url":"https://api.github.com/users/Cyan4973/following{/other_user}","gists_url":"https://api.github.com/users/Cyan4973/gists{/gist_id}","starred_url":"https://api.github.com/users/Cyan4973/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cyan4973/subscriptions","organizations_url":"https://api.github.com/users/Cyan4973/orgs","repos_url":"https://api.github.com/users/Cyan4973/repos","events_url":"https://api.github.com/users/Cyan4973/events{/privacy}","received_events_url":"https://api.github.com/users/Cyan4973/received_events","type":"User","site_admin":false},"body":"Good point.\r\nI prefer `mlen`, but I had to juggle a bit with variable names during transition (initially, `mlen` was a function-level variable, used in several places for different unrelated usages).\r\nI'll ensure consistency of these names.","created_at":"2017-11-14T20:19:47Z","updated_at":"2017-11-14T20:19:47Z","html_url":"https://github.com/facebook/zstd/pull/912#discussion_r150951653","pull_request_url":"https://api.github.com/repos/facebook/zstd/pulls/912","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/facebook/zstd/pulls/comments/150951653"},"html":{"href":"https://github.com/facebook/zstd/pull/912#discussion_r150951653"},"pull_request":{"href":"https://api.github.com/repos/facebook/zstd/pulls/912"}},"in_reply_to_id":150718155},"pull_request":{"url":"https://api.github.com/repos/facebook/zstd/pulls/912","id":151964107,"html_url":"https://github.com/facebook/zstd/pull/912","diff_url":"https://github.com/facebook/zstd/pull/912.diff","patch_url":"https://github.com/facebook/zstd/pull/912.patch","issue_url":"https://api.github.com/repos/facebook/zstd/issues/912","number":912,"state":"open","locked":false,"title":"Optimal parser refactoring","user":{"login":"Cyan4973","id":750081,"avatar_url":"https://avatars0.githubusercontent.com/u/750081?v=4","gravatar_id":"","url":"https://api.github.com/users/Cyan4973","html_url":"https://github.com/Cyan4973","followers_url":"https://api.github.com/users/Cyan4973/followers","following_url":"https://api.github.com/users/Cyan4973/following{/other_user}","gists_url":"https://api.github.com/users/Cyan4973/gists{/gist_id}","starred_url":"https://api.github.com/users/Cyan4973/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cyan4973/subscriptions","organizations_url":"https://api.github.com/users/Cyan4973/orgs","repos_url":"https://api.github.com/users/Cyan4973/repos","events_url":"https://api.github.com/users/Cyan4973/events{/privacy}","received_events_url":"https://api.github.com/users/Cyan4973/received_events","type":"User","site_admin":false},"body":"This patch doesn't change functionality nor performance.\r\nIts objective is mostly to rewrite the optimal parser in a way which makes it easier to understand and modify. \"Aggressive scoping\" is the most relevant rule applied in this patch.\r\n\r\nOn the noticeable changes : \r\n- `zstd_compress.h` becomes `zstd_compress_internal.h`, to emphasise that its definitions are strictly internal, meant to be used solely by `/lib/compress` modules.\r\n- Many definitions were moved from `zstd_internal.h` into `zstd_compress_internal.h`. `zstd_internal.h` is reserved for definitions that need to be shared across `/lib` sub-directories, namely `/compress`, `/decompress` and `/dictBuilder`.\r\n\r\nThe next important change will be the modification of `zstd_opt`'s match finder to transparently manage rep codes, so that it's possible to have a single parser for both single-segment and double-segments memory configuration.","created_at":"2017-11-10T17:36:01Z","updated_at":"2017-11-14T20:19:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3c2193a4f0a480d0fad83a1ab0cc17b870db054f","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/facebook/zstd/pulls/912/commits","review_comments_url":"https://api.github.com/repos/facebook/zstd/pulls/912/comments","review_comment_url":"https://api.github.com/repos/facebook/zstd/pulls/comments{/number}","comments_url":"https://api.github.com/repos/facebook/zstd/issues/912/comments","statuses_url":"https://api.github.com/repos/facebook/zstd/statuses/72c0f4574cfef1d5d5f35fc7277ee353793956ab","head":{"label":"facebook:opt","ref":"opt","sha":"72c0f4574cfef1d5d5f35fc7277ee353793956ab","user":{"login":"facebook","id":69631,"avatar_url":"https://avatars3.githubusercontent.com/u/69631?v=4","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"repo":{"id":29759715,"name":"zstd","full_name":"facebook/zstd","owner":{"login":"facebook","id":69631,"avatar_url":"https://avatars3.githubusercontent.com/u/69631?v=4","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/facebook/zstd","description":"Zstandard - Fast real-time compression algorithm","fork":false,"url":"https://api.github.com/repos/facebook/zstd","forks_url":"https://api.github.com/repos/facebook/zstd/forks","keys_url":"https://api.github.com/repos/facebook/zstd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/facebook/zstd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/facebook/zstd/teams","hooks_url":"https://api.github.com/repos/facebook/zstd/hooks","issue_events_url":"https://api.github.com/repos/facebook/zstd/issues/events{/number}","events_url":"https://api.github.com/repos/facebook/zstd/events","assignees_url":"https://api.github.com/repos/facebook/zstd/assignees{/user}","branches_url":"https://api.github.com/repos/facebook/zstd/branches{/branch}","tags_url":"https://api.github.com/repos/facebook/zstd/tags","blobs_url":"https://api.github.com/repos/facebook/zstd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/facebook/zstd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/facebook/zstd/git/refs{/sha}","trees_url":"https://api.github.com/repos/facebook/zstd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/facebook/zstd/statuses/{sha}","languages_url":"https://api.github.com/repos/facebook/zstd/languages","stargazers_url":"https://api.github.com/repos/facebook/zstd/stargazers","contributors_url":"https://api.github.com/repos/facebook/zstd/contributors","subscribers_url":"https://api.github.com/repos/facebook/zstd/subscribers","subscription_url":"https://api.github.com/repos/facebook/zstd/subscription","commits_url":"https://api.github.com/repos/facebook/zstd/commits{/sha}","git_commits_url":"https://api.github.com/repos/facebook/zstd/git/commits{/sha}","comments_url":"https://api.github.com/repos/facebook/zstd/comments{/number}","issue_comment_url":"https://api.github.com/repos/facebook/zstd/issues/comments{/number}","contents_url":"https://api.github.com/repos/facebook/zstd/contents/{+path}","compare_url":"https://api.github.com/repos/facebook/zstd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/facebook/zstd/merges","archive_url":"https://api.github.com/repos/facebook/zstd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/facebook/zstd/downloads","issues_url":"https://api.github.com/repos/facebook/zstd/issues{/number}","pulls_url":"https://api.github.com/repos/facebook/zstd/pulls{/number}","milestones_url":"https://api.github.com/repos/facebook/zstd/milestones{/number}","notifications_url":"https://api.github.com/repos/facebook/zstd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/facebook/zstd/labels{/name}","releases_url":"https://api.github.com/repos/facebook/zstd/releases{/id}","deployments_url":"https://api.github.com/repos/facebook/zstd/deployments","created_at":"2015-01-24T00:22:38Z","updated_at":"2017-11-14T20:05:29Z","pushed_at":"2017-11-13T10:27:02Z","git_url":"git://github.com/facebook/zstd.git","ssh_url":"git@github.com:facebook/zstd.git","clone_url":"https://github.com/facebook/zstd.git","svn_url":"https://github.com/facebook/zstd","homepage":"http://www.zstd.net","size":12309,"stargazers_count":5595,"watchers_count":5595,"language":"C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":518,"mirror_url":null,"archived":false,"open_issues_count":25,"forks":518,"open_issues":25,"watchers":5595,"default_branch":"dev"}},"base":{"label":"facebook:dev","ref":"dev","sha":"aec56a52fbab207fc639a1937d1e708a282edca8","user":{"login":"facebook","id":69631,"avatar_url":"https://avatars3.githubusercontent.com/u/69631?v=4","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"repo":{"id":29759715,"name":"zstd","full_name":"facebook/zstd","owner":{"login":"facebook","id":69631,"avatar_url":"https://avatars3.githubusercontent.com/u/69631?v=4","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/facebook/zstd","description":"Zstandard - Fast real-time compression algorithm","fork":false,"url":"https://api.github.com/repos/facebook/zstd","forks_url":"https://api.github.com/repos/facebook/zstd/forks","keys_url":"https://api.github.com/repos/facebook/zstd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/facebook/zstd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/facebook/zstd/teams","hooks_url":"https://api.github.com/repos/facebook/zstd/hooks","issue_events_url":"https://api.github.com/repos/facebook/zstd/issues/events{/number}","events_url":"https://api.github.com/repos/facebook/zstd/events","assignees_url":"https://api.github.com/repos/facebook/zstd/assignees{/user}","branches_url":"https://api.github.com/repos/facebook/zstd/branches{/branch}","tags_url":"https://api.github.com/repos/facebook/zstd/tags","blobs_url":"https://api.github.com/repos/facebook/zstd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/facebook/zstd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/facebook/zstd/git/refs{/sha}","trees_url":"https://api.github.com/repos/facebook/zstd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/facebook/zstd/statuses/{sha}","languages_url":"https://api.github.com/repos/facebook/zstd/languages","stargazers_url":"https://api.github.com/repos/facebook/zstd/stargazers","contributors_url":"https://api.github.com/repos/facebook/zstd/contributors","subscribers_url":"https://api.github.com/repos/facebook/zstd/subscribers","subscription_url":"https://api.github.com/repos/facebook/zstd/subscription","commits_url":"https://api.github.com/repos/facebook/zstd/commits{/sha}","git_commits_url":"https://api.github.com/repos/facebook/zstd/git/commits{/sha}","comments_url":"https://api.github.com/repos/facebook/zstd/comments{/number}","issue_comment_url":"https://api.github.com/repos/facebook/zstd/issues/comments{/number}","contents_url":"https://api.github.com/repos/facebook/zstd/contents/{+path}","compare_url":"https://api.github.com/repos/facebook/zstd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/facebook/zstd/merges","archive_url":"https://api.github.com/repos/facebook/zstd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/facebook/zstd/downloads","issues_url":"https://api.github.com/repos/facebook/zstd/issues{/number}","pulls_url":"https://api.github.com/repos/facebook/zstd/pulls{/number}","milestones_url":"https://api.github.com/repos/facebook/zstd/milestones{/number}","notifications_url":"https://api.github.com/repos/facebook/zstd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/facebook/zstd/labels{/name}","releases_url":"https://api.github.com/repos/facebook/zstd/releases{/id}","deployments_url":"https://api.github.com/repos/facebook/zstd/deployments","created_at":"2015-01-24T00:22:38Z","updated_at":"2017-11-14T20:05:29Z","pushed_at":"2017-11-13T10:27:02Z","git_url":"git://github.com/facebook/zstd.git","ssh_url":"git@github.com:facebook/zstd.git","clone_url":"https://github.com/facebook/zstd.git","svn_url":"https://github.com/facebook/zstd","homepage":"http://www.zstd.net","size":12309,"stargazers_count":5595,"watchers_count":5595,"language":"C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":518,"mirror_url":null,"archived":false,"open_issues_count":25,"forks":518,"open_issues":25,"watchers":5595,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/facebook/zstd/pulls/912"},"html":{"href":"https://github.com/facebook/zstd/pull/912"},"issue":{"href":"https://api.github.com/repos/facebook/zstd/issues/912"},"comments":{"href":"https://api.github.com/repos/facebook/zstd/issues/912/comments"},"review_comments":{"href":"https://api.github.com/repos/facebook/zstd/pulls/912/comments"},"review_comment":{"href":"https://api.github.com/repos/facebook/zstd/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/facebook/zstd/pulls/912/commits"},"statuses":{"href":"https://api.github.com/repos/facebook/zstd/statuses/72c0f4574cfef1d5d5f35fc7277ee353793956ab"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"Cyan4973"}}