GitHub PullRequestReviewCommentEvent at 2014-04-22 21:19:20
Repository: voltdb
Actor: aweisberg
Payload: {"comment":{"url":"https://api.github.com/repos/VoltDB/voltdb/pulls/comments/11876598","id":11876598,"diff_hunk":"@@ -0,0 +1,170 @@\n+/* This file is part of VoltDB.\n+ * Copyright (C) 2008-2014 VoltDB Inc.\n+ *\n+ * Permission is hereby granted, free of charge, to any person obtaining\n+ * a copy of this software and associated documentation files (the\n+ * \"Software\"), to deal in the Software without restriction, including\n+ * without limitation the rights to use, copy, modify, merge, publish,\n+ * distribute, sublicense, and/or sell copies of the Software, and to\n+ * permit persons to whom the Software is furnished to do so, subject to\n+ * the following conditions:\n+ *\n+ * The above copyright notice and this permission notice shall be\n+ * included in all copies or substantial portions of the Software.\n+ *\n+ * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n+ * OTHER DEALINGS IN THE SOFTWARE.\n+ */\n+package com.procedures;\n+\n+import java.nio.ByteBuffer;\n+import java.util.HashSet;\n+\n+import org.voltdb.SQLStmt;\n+import org.voltdb.VoltProcedure;\n+import org.voltdb.VoltTable;\n+\n+public class Put extends VoltProcedure {\n+    public final SQLStmt selectStmt = new SQLStmt(\"SELECT value FROM Store WHERE keyspace = ? AND key = ?\");\n+    public final SQLStmt insertStmt = new SQLStmt(\"INSERT INTO Store VALUES (?, ?, ?)\");\n+    public final SQLStmt updateStmt = new SQLStmt(\"UPDATE Store SET value = ? WHERE keyspace = ? AND key = ?\");\n+\n+    public long run(byte[] keyspace, String key, byte[] data)\n+    {\n+        voltQueueSQL(selectStmt, keyspace, key);\n+        VoltTable res = voltExecuteSQL()[0];\n+        if (res.advanceRow())\n+        {\n+            voltQueueSQL(updateStmt, merge(res.getVarbinary(0), data), keyspace, key);\n+        }\n+        else\n+        {\n+            voltQueueSQL(insertStmt, keyspace, key, data);\n+        }\n+        voltExecuteSQL(true);\n+        return 0l;\n+    }\n+\n+    private byte[] merge(byte[] dest, byte[] src)\n+    {\n+        HashSet<ByteWrapper> mergeSet = new HashSet<ByteWrapper>();\n+        ByteBuffer buf = ByteBuffer.wrap(src);\n+        int nSrc = buf.getInt();\n+        for (int i = 0; i < nSrc; i++)\n+        {\n+            int len = buf.getInt();\n+            int off = buf.position();\n+            mergeSet.add(new ByteWrapper(src, off, len));\n+            buf.position(off + len);\n+            len = buf.getInt();\n+            buf.position(buf.position() + len);\n+        }\n+\n+        byte[] merged = new byte[src.length + dest.length];\n+        ByteBuffer out = ByteBuffer.wrap(merged);\n+\n+        buf = ByteBuffer.wrap(dest);\n+        int nDest = buf.getInt();\n+        int nFields = nSrc + nDest;\n+        out.putInt(nFields);\n+\n+        int blockStart = 4;\n+        int blockEnd = 4;\n+        for (int i = 0; i < nDest; i++)\n+        {\n+            int len = buf.getInt();\n+            int off = buf.position();\n+            boolean flushBlock = mergeSet.contains(new ByteWrapper(dest, off, len));\n+            buf.position(off + len);\n+            len = buf.getInt();\n+            buf.position(buf.position() + len);\n+            if (flushBlock)\n+            {\n+                if (blockStart < blockEnd)\n+                {\n+                    out.put(dest, blockStart, blockEnd - blockStart);\n+                }\n+                nFields--;\n+                blockStart = buf.position();\n+            }\n+            blockEnd = buf.position();\n+        }\n+        if (blockStart < blockEnd)\n+        {\n+            out.put(dest, blockStart, blockEnd - blockStart);\n+        }\n+        out.put(src, 4, src.length - 4);\n+\n+        int length = out.position();\n+        if (nFields != nSrc + nDest)\n+        {\n+            out.position(0);\n+            out.putInt(nFields);\n+        }\n+\n+        byte[] res = new byte[length];\n+        System.arraycopy(merged, 0, res, 0, length);\n+        return res;\n+    }\n+\n+    private static class ByteWrapper\n+    {\n+        byte[] m_arr;\n+        int m_off;\n+        int m_len;\n+\n+        ByteWrapper(byte[] arr, int off, int len)\n+        {\n+            m_arr = arr;\n+            m_off = off;\n+            m_len = len;\n+        }\n+\n+        @Override\n+        public boolean equals(Object obj)\n+        {\n+            if (this == obj)\n+            {\n+                return true;\n+            }\n+            if (!(obj instanceof ByteWrapper))\n+            {\n+                return false;\n+            }\n+            ByteWrapper that = (ByteWrapper) obj;\n+            if (this.m_len != that.m_len)\n+            {\n+                return false;\n+            }\n+            for (int i = 0; i < this.m_len; i++)\n+            {\n+                if (this.m_arr[this.m_off + i] != that.m_arr[that.m_off + i])\n+                {\n+                    return false;\n+                }\n+            }\n+            return true;\n+        }\n+\n+        @Override\n+        public int hashCode()","path":"tests/test_apps/ycsb/src/com/procedures/Put.java","position":155,"original_position":155,"commit_id":"e638ad14c8a357c1b0e83839090ecdad307aeac1","original_commit_id":"e638ad14c8a357c1b0e83839090ecdad307aeac1","user":{"login":"aweisberg","id":1047741,"avatar_url":"https://avatars.githubusercontent.com/u/1047741?","gravatar_id":"42de74b49138cdf58a84b9f1982cf6db","url":"https://api.github.com/users/aweisberg","html_url":"https://github.com/aweisberg","followers_url":"https://api.github.com/users/aweisberg/followers","following_url":"https://api.github.com/users/aweisberg/following{/other_user}","gists_url":"https://api.github.com/users/aweisberg/gists{/gist_id}","starred_url":"https://api.github.com/users/aweisberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aweisberg/subscriptions","organizations_url":"https://api.github.com/users/aweisberg/orgs","repos_url":"https://api.github.com/users/aweisberg/repos","events_url":"https://api.github.com/users/aweisberg/events{/privacy}","received_events_url":"https://api.github.com/users/aweisberg/received_events","type":"User","site_admin":false},"body":"You should cache the value of this hash code, it's pretty expensive to compute. If YCSB produces random enough values you could build the hash code on just a prefix","created_at":"2014-04-22T21:19:20Z","updated_at":"2014-04-22T21:19:20Z","html_url":"https://github.com/VoltDB/voltdb/pull/1308#discussion_r11876598","pull_request_url":"https://api.github.com/repos/VoltDB/voltdb/pulls/1308","_links":{"self":{"href":"https://api.github.com/repos/VoltDB/voltdb/pulls/comments/11876598"},"html":{"href":"https://github.com/VoltDB/voltdb/pull/1308#discussion_r11876598"},"pull_request":{"href":"https://api.github.com/repos/VoltDB/voltdb/pulls/1308"}}}}