1 /*- 2 * Public Domain 2014-2018 MongoDB, Inc. 3 * Public Domain 2008-2014 WiredTiger, Inc. 4 * 5 * This is free and unencumbered software released into the public domain. 6 * 7 * Anyone is free to copy, modify, publish, use, compile, sell, or 8 * distribute this software, either in source code form or as a compiled 9 * binary, for any purpose, commercial or non-commercial, and by any 10 * means. 11 * 12 * In jurisdictions that recognize copyright laws, the author or authors 13 * of this software dedicate any and all copyright interest in the 14 * software to the public domain. We make this dedication for the benefit 15 * of the public at large and to the detriment of our heirs and 16 * successors. We intend this dedication to be an overt act of 17 * relinquishment in perpetuity of all present and future rights to this 18 * software under copyright law. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 * OTHER DEALINGS IN THE SOFTWARE. 27 */ 28 package com.wiredtiger.test; 29 30 import java.util.Arrays; 31 import com.wiredtiger.db.Connection; 32 import com.wiredtiger.db.Cursor; 33 import com.wiredtiger.db.Session; 34 import com.wiredtiger.db.WiredTigerException; 35 import com.wiredtiger.db.WiredTigerPackingException; 36 import com.wiredtiger.db.wiredtiger; 37 38 import static org.junit.Assert.assertEquals; 39 40 import org.junit.Test; 41 import org.junit.Assert; 42 import org.junit.runner.RunWith; 43 import org.junit.runners.JUnit4; 44 45 public class PackTest02 { 46 47 public static final String TEST_NAME = "PackTest02"; 48 49 private Connection connection; 50 private Session session; 51 52 // Compare two byte arrays, assert if different compareByteArrays(byte[] a1, byte[] a2)53 void compareByteArrays(byte[] a1, byte[] a2) { 54 //printByteArray(a1, a1.length); 55 //printByteArray(a2, a2.length); 56 if (a1.length != a2.length) { 57 System.err.println("Length differ"); 58 } 59 assertEquals(a1.length, a2.length); 60 for (int i = 0; i < a1.length; i++) { 61 if (a1[i] != a2[i]) 62 System.err.println("DIFFER at " + i); 63 assertEquals(a1[i], a2[i]); 64 } 65 } 66 67 // Add either a set of keys or a set of values to the 68 // cursor at the current position. addKeyValues(Cursor cursor, Object[] args, boolean iskey)69 boolean addKeyValues(Cursor cursor, Object[] args, boolean iskey) { 70 for (Object arg : args) { 71 if (arg instanceof Integer) { 72 if (iskey) 73 cursor.putKeyInt((Integer)arg); 74 else 75 cursor.putValueInt((Integer)arg); 76 } 77 else if (arg instanceof String) { 78 if (iskey) 79 cursor.putKeyString((String)arg); 80 else 81 cursor.putValueString((String)arg); 82 } 83 else if (arg instanceof byte[]) { 84 if (iskey) 85 cursor.putKeyByteArray((byte[])arg); 86 else 87 cursor.putValueByteArray((byte[])arg); 88 } 89 else 90 throw new IllegalArgumentException("unknown type"); 91 } 92 return true; 93 } 94 95 // Check that either a set of keys or a set of values match 96 // the given expected values. Assert when different. checkKeyValues(Cursor cursor, Object[] args, boolean iskey)97 boolean checkKeyValues(Cursor cursor, Object[] args, boolean iskey) { 98 for (Object arg : args) { 99 if (arg instanceof Integer) { 100 if (iskey) 101 assertEquals(arg, cursor.getKeyInt()); 102 else 103 assertEquals(arg, cursor.getValueInt()); 104 } 105 else if (arg instanceof String) { 106 if (iskey) 107 assertEquals(arg, cursor.getKeyString()); 108 else 109 assertEquals(arg, cursor.getValueString()); 110 } 111 else if (arg instanceof byte[]) { 112 if (iskey) 113 compareByteArrays((byte[])arg, cursor.getKeyByteArray()); 114 else 115 compareByteArrays((byte[])arg, cursor.getValueByteArray()); 116 } 117 else 118 throw new IllegalArgumentException("unknown type"); 119 } 120 return true; 121 } 122 123 // Helper function to make an array out of variable args makeArray(Object... args)124 Object[] makeArray(Object... args) 125 { 126 return args; 127 } 128 129 // Use checkCompare for the common case that what 130 // we store is what we expect. check(String fmt, Object... args)131 boolean check(String fmt, Object... args) 132 { 133 return checkCompare(fmt, args, args); 134 } 135 136 // Create a table with 'fmt' as the value, and also a 137 // reverse index. Store the given arguments as values, 138 // make sure we can retrieve them from the main table 139 // and the index. We compare the result using compareArgs, 140 // these may be different from what we store due to padding. checkCompare(String fmt, Object[] storeArgs, Object[] compareArgs)141 boolean checkCompare(String fmt, Object[] storeArgs, Object[] compareArgs) 142 throws WiredTigerException { 143 String uri = "table:" + TEST_NAME + "-" + fmt; 144 String idx_uri = "index:" + TEST_NAME + "-" + fmt + ":inverse"; 145 int nargs = storeArgs.length; 146 String colnames = ""; 147 for (int i = 0; i < nargs; i++) { 148 if (i > 0) 149 colnames += ","; 150 colnames += "v" + i; 151 } 152 session.create(uri, "columns=(k," + colnames + ")," + 153 "key_format=i,value_format=" + fmt); 154 session.create(idx_uri, "columns=(" + colnames + ")"); 155 Cursor forw = session.open_cursor(uri, null, null); 156 Cursor forw_idx = session.open_cursor(idx_uri + "(k)", null, null); 157 158 forw.putKeyInt(1234); 159 if (!addKeyValues(forw, storeArgs, false)) 160 return false; 161 forw.insert(); 162 163 forw.putKeyInt(1234); 164 assertEquals(0, forw.search()); 165 if (!checkKeyValues(forw, compareArgs, false)) 166 return false; 167 168 if (!addKeyValues(forw_idx, storeArgs, true)) 169 return false; 170 assertEquals(0, forw_idx.search()); 171 172 Integer expected[] = { 1234 }; 173 174 if (!checkKeyValues(forw_idx, expected, false)) 175 return false; 176 177 forw.close(); 178 forw_idx.close(); 179 session.drop(idx_uri, null); 180 session.drop(uri, null); 181 return true; 182 } 183 184 // A debug helper method printByteArray(byte[] bytes, int len)185 private void printByteArray(byte[] bytes, int len) { 186 for (int i = 0; i < len; i++) { 187 System.out.println(String.format( 188 "\t%8s", Integer.toBinaryString( 189 bytes[i] & 0xff)).replace(' ', '0')); 190 } 191 } 192 setup()193 private void setup() { 194 connection = wiredtiger.open("WT_HOME", "create"); 195 session = connection.open_session(null); 196 } 197 teardown()198 private void teardown() { 199 session.close(null); 200 connection.close(null); 201 } 202 203 @Test packTest()204 public void packTest() 205 throws WiredTigerPackingException { 206 207 // Do a test of packing, based on test suite's test_pack.py 208 209 String a10 = "aaaaaaaaaa"; 210 String a42 = a10 + a10 + a10 + a10 + "aa"; 211 byte[] b10 = 212 { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 }; 213 byte[] b20 = 214 { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 215 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 }; 216 byte[] b1 = { 0x4 }; 217 byte[] b3 = { 0x4, 0x0, 0x0 }; 218 219 setup(); 220 check("iii", 0, 101, -99); 221 check("3i", 0, 101, -99); 222 check("iS", 42, "forty two"); 223 check("S", "abc"); 224 check("9S", "aaaaaaaaa"); 225 check("9sS", "forty two", "spam egg"); 226 check("42s", a42); 227 check("42sS", a42, "something"); 228 check("S42s", "something", a42); 229 // nul terminated string with padding 230 check("10sS", "aaaaa\0\0\0\0\0", "something"); 231 check("S10s", "something", "aaaaa\0\0\0\0\0"); 232 check("u", b20); 233 check("uu", b10, b10); 234 // input 1 byte for a 3 byte format, extra null bytes will be stored 235 checkCompare("3u", makeArray(b1), makeArray(b3)); 236 checkCompare("3uu", makeArray(b1, b10), makeArray(b3, b10)); 237 checkCompare("u3u", makeArray(b10, b1), makeArray(b10, b3)); 238 239 check("s", "4"); 240 check("1s", "4"); 241 check("2s", "42"); 242 teardown(); 243 } 244 main(String[] args)245 public static void main(String[] args) { 246 PackTest02 tester = new PackTest02(); 247 try { 248 tester.packTest(); 249 } catch (WiredTigerPackingException wtpe) { 250 System.err.println("Packing exception: " + wtpe); 251 } 252 } 253 } 254