Skip to content

Commit

Permalink
Merge branch 'release/0.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
jtnelson committed Oct 4, 2014
2 parents 166be8c + b3e0d01 commit 2b82401
Show file tree
Hide file tree
Showing 50 changed files with 3,389 additions and 742 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.1
0.4.2
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
## Changelog

#### Version 0.4.2 (October 4, 2014)
* Improved the way that the storage engine processes `find` queries, resulting in a further speed improvement of over 35 percent.
* Fixed a bug with real-time transaction failure detection that made it possible for [phantom reads](http://en.wikipedia.org/wiki/Isolation_(database_systems)#Phantom_reads) to occur.
* Fixed an issue that caused Concourse Server to drop transaction tokens when under increased concurrency.
* Fixed and bug in the just-in-time locking protocol that prematurely removed references to active locks.
* Fixed a bug where transactions that started to commit but failed before completing did not release locks, resulting in deadlocks.
* Fixed an issue where transactions unnecessarily grabbed locks twice while committing.
* Fixed an issues that made it possible for deadlocks to occur with many concurrent Transactions performing atomic operations (i.e. `set`).
* Improved the javadoc for the `Tag` datatype.
* Fixed a bug where the `Tag#toString` method threw a `NullPointerException` if the Tag was created using a `null` value.
* Add a `min` method to the `Numbers` utility class.
* Fixed a bug that caused the `insert` methods to incorrectly store values encoded as *resolvable link specifications* as strings instead of links to resolved records.
* Added a `heap_size` preference in `concourse.prefs` that configures the initial and max heap for the Concourse Server JVM.

#### Version 0.3.8 (October 4, 2014)
* Fixed a bug where database records and indexes were not properly cached. Now, reads are over 87 percent faster.
* Removed a potential race-condition between real-time failure detection and just-in-time locking that made it possible for an failed transaction to errneously commit and violate ACID consistency.
* Fixed a bug where the `Numbers#max` method actually returned the minimum value.

#### Version 0.4.1 (September 13, 2014)
* Reduced the number of primary record lookups required to perform a `find` query which yields up to an order of magnitude in increased speed.
* Fixed a bug that accidentally stripped underscore *_* characters from environment names.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Concourse runs on Java 1.7.

#### Versioning

This is version 0.4.1 of Concourse.
This is version 0.4.2 of Concourse.

Concourse will be maintained under the [Semantic Versioning](http://semver.org)
guidelines such that release versions will be formatted as `<major>.<minor>.<patch>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*/
package org.cinchapi.concourse;

import org.cinchapi.concourse.thrift.Operator;
import org.cinchapi.concourse.util.Convert;
import org.junit.Assert;
import org.junit.Test;

Expand Down Expand Up @@ -78,5 +80,27 @@ public void testInsertBooleanAsTag() {
long record = client.insert(json);
Assert.assertEquals(Boolean.toString(value), client.get(key, record));
}

@Test
public void testInsertResolvableLink(){
client.set("name", "Jeff", 1);
JsonObject object = new JsonObject();
object.addProperty("name", "Ashleah");
object.addProperty("spouse", Convert.stringToResolvableLinkSpecification("name", "Jeff"));
String json = object.toString();
client.insert(json, 2);
Assert.assertTrue(client.find("spouse", Operator.LINKS_TO, 1).contains(2L));
}

@Test
public void testInsertResolvableLinkIntoNewRecord(){
client.set("name", "Jeff", 1);
JsonObject object = new JsonObject();
object.addProperty("name", "Ashleah");
object.addProperty("spouse", Convert.stringToResolvableLinkSpecification("name", "Jeff"));
String json = object.toString();
long record = client.insert(json);
Assert.assertTrue(client.find("spouse", Operator.LINKS_TO, 1).contains(record));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Jeff Nelson, Cinchapi Software Collective
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.cinchapi.concourse.bugrepro;

import org.cinchapi.concourse.Concourse;
import org.cinchapi.concourse.ConcourseIntegrationTest;
import org.cinchapi.concourse.TransactionException;
import org.cinchapi.concourse.thrift.Operator;
import org.junit.Assert;
import org.junit.Test;

/**
* Repro of issue described in CON-171 where a phantom read is possible when
* using transactions.
*
* @author jnelson
*/
public class CON171 extends ConcourseIntegrationTest {

@Test(expected=TransactionException.class)
public void repro1() {
Concourse client2 = Concourse.connect(SERVER_HOST, SERVER_PORT,
"admin", "admin");
client.stage();
client.find("foo", Operator.EQUALS, "bar");
client2.set("foo", "bar", 1);
Assert.assertTrue(client.find("foo", Operator.EQUALS, "bar").isEmpty());
}

@Test(expected=TransactionException.class)
public void repro2(){
Concourse client2 = Concourse.connect(SERVER_HOST, SERVER_PORT,
"admin", "admin");
client.stage();
client.find("foo", Operator.EQUALS, "bar");
client2.add("foo", "bar", 1);
Assert.assertTrue(client.find("foo", Operator.EQUALS, "bar").isEmpty());
}

@Test(expected=TransactionException.class)
public void repro3(){
Concourse client2 = Concourse.connect(SERVER_HOST, SERVER_PORT,
"admin", "admin");
client.stage();
client2.add("foo", "bar", 1);
client.find("foo", Operator.EQUALS, "bar");
client2.remove("foo", "bar", 1);
Assert.assertFalse(client.find("foo", Operator.EQUALS, "bar").isEmpty());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013-2014 Jeff Nelson, Cinchapi Software Collective
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.cinchapi.concourse.perf;

import java.util.concurrent.TimeUnit;

import org.cinchapi.concourse.ConcourseIntegrationTest;
import org.cinchapi.concourse.thrift.Operator;
import org.junit.Test;

import com.google.common.base.Stopwatch;

/**
* Test the speed of find queries
*
* @author jnelson
*
*/
public class FindThroughputTest extends ConcourseIntegrationTest {

@Test
public void testFindPerformance1() {
System.out.println("Doing the testFindPerformance1 test");
int count = 20000;
for (int i = 0; i < count; i++) {
client.add("foo", i, i);
}
Stopwatch watch = Stopwatch.createStarted();
client.find("foo", Operator.GREATER_THAN_OR_EQUALS, 0);
watch.stop();
TimeUnit unit = TimeUnit.MILLISECONDS;
System.out.println(watch.elapsed(unit) + " " + unit);
System.gc();
}

@Test
public void testFindPerformance2() {
System.out.println("Doing the testFindPerformance2 test");
int count = 500;
for (int i = 0; i < count; i++) {
for (int j = 0; j <= i; j++) {
client.add("foo", j, i);
}
}
Stopwatch watch = Stopwatch.createStarted();
client.find("foo", Operator.BETWEEN, 5, 100);
watch.stop();
TimeUnit unit = TimeUnit.MILLISECONDS;
System.out.println(watch.elapsed(unit) + " " + unit);
System.gc();

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013-2014 Jeff Nelson, Cinchapi Software Collective
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.cinchapi.concourse.perf;

import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import org.cinchapi.concourse.Concourse;
import org.cinchapi.concourse.ConcourseIntegrationTest;
import org.cinchapi.concourse.TransactionException;
import org.junit.Test;

import com.google.common.base.Throwables;
import com.google.common.collect.Lists;

/**
* A test of transaction throughput.
*
* @author jnelson
*/
public class TransactionThroughputTest extends ConcourseIntegrationTest {

AtomicBoolean running = new AtomicBoolean(true);
long stoptime = 0;
AtomicLong rounds = new AtomicLong(0);
AtomicLong failed = new AtomicLong(0);

@Test
public void test() {
try {
System.out.println("Doing the TransactionThroughputTest");
int size = 10;
// Pre-seed the data
for (int i = 0; i < size; i++) {
client.clear(i);
client.set("username", Integer.toString(i), i);
client.set("password", Integer.toString(i), i);
client.set("age", Integer.toString(i), i);
}

List<Concourse> connections = Lists.newArrayList();
for (int i = 0; i < size; i++) {
connections.add(Concourse.connect(SERVER_HOST, SERVER_PORT,
"admin", "admin"));
}
List<Thread> threads = Lists.newArrayList();
for (int i = 0; i < size; i++) {
threads.add(new Thread(new ConcourseRunnable(connections
.remove(0))));
}
stoptime = System.currentTimeMillis() + 10000;
for (Thread thread : threads) {
thread.start();
}
while (System.currentTimeMillis() < stoptime) {
continue;
}
running.set(false);
for (Thread thread : threads) {
thread.join();
}
System.out.println("rounds=" + rounds.get());
System.out.println("failed=" + failed.get());
client.exit();

}
catch (Exception e) {
throw Throwables.propagate(e);
}
}

class ConcourseRunnable implements Runnable {

private Concourse client;
private Random random = new Random();

public ConcourseRunnable(Concourse client) {
this.client = client;
}

@Override
public void run() {
while (running.get()) {
int id = random.nextInt(10);
try {
client.stage();
client.set("username",
((String) client.get("username", id)) + "n", id);
client.set("password",
((String) client.get("password", id)) + "n", id);
client.set("age", ((String) client.get("age", id)) + "n",
id);
if(client.commit()) {
rounds.incrementAndGet();
}
else {
failed.incrementAndGet();
}
}
catch (TransactionException e) {
client.abort();
failed.incrementAndGet();
}

}
client.exit();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class WritePerformanceTest extends ConcourseIntegrationTest {
@Test
@Theory
public void testWriteWordsDotTxt(int run){
System.out.println("Doing the WritePerformanceTest with words.txt");
Stopwatch watch = Stopwatch.createStarted();
StandardActions.importWordsDotText(client);
watch.stop();
Expand Down
Loading

0 comments on commit 2b82401

Please sign in to comment.