Merge "BUG-650: use weakCompareAndSwap()"
authorTony Tkacik <ttkacik@cisco.com>
Mon, 15 Sep 2014 09:22:45 +0000 (09:22 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 15 Sep 2014 09:22:45 +0000 (09:22 +0000)
36 files changed:
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/AugmentRelativeXPathTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/AugmentedTypeTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/BinaryTypeTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/BitAndUnionTOEnclosingTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ControllerTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ExtendedTypedefTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GenEnumResolvingTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GenTypesSubSetTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GenerateInnerClassForBitsAndUnionInLeavesTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesBitsTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesLeafrefTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesStringTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedTypesTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/IdentityrefTypeTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/UnionTypeDefTest.java
code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/UsesTest.java
common/features/pom.xml
common/features/src/main/resources/features.xml
common/parent/pom.xml
common/util/src/main/java/org/opendaylight/yangtools/util/ConcurrentDurationStatisticsTracker.java [new file with mode: 0644]
common/util/src/main/java/org/opendaylight/yangtools/util/DurationStatisticsTracker.java [new file with mode: 0644]
common/util/src/main/java/org/opendaylight/yangtools/util/DurationStatsTracker.java
common/util/src/main/java/org/opendaylight/yangtools/util/DurationWithTime.java [new file with mode: 0644]
common/util/src/main/java/org/opendaylight/yangtools/util/SynchronizedDurationStatsTracker.java [new file with mode: 0644]
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/YangInstanceIdentifier.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/SynchronizedDataTreeModification.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterListContext.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStreamWriterNamedObjectContext.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XMLStreamNormalizedNodeStreamWriter.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlStreamUtils.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeModification.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaPath.java

index de566eea1ec6c46eb40a5969738167be25d75186..250faf8c280c00384eb0974ef89235c9f0a25be2 100644 (file)
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
@@ -36,7 +37,7 @@ public class AugmentRelativeXPathTest extends AbstractTypesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull("context is null", context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull("genTypes is null", genTypes);
index ba5d1c984c9f730b371871cb52ebd9118bafb6d8..70c7c6684e601be7bd8263d21dbd304a6efb03be 100644 (file)
@@ -14,6 +14,7 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.util.Arrays;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
@@ -43,7 +44,7 @@ public class AugmentedTypeTest {
                 augmentNetworkLink, augmentTopologyTunnels, ietfInterfaces));
         assertNotNull("Schema Context is null", context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull("genTypes is null", genTypes);
index f5c2c1b2aa65b902ac0aabbd606d4c35b6a3d100..32b51af1931243be4d9b164a41203734c2deaed4 100644 (file)
@@ -16,6 +16,7 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
@@ -45,7 +46,7 @@ public class BinaryTypeTest {
         final SchemaContext context = parser.parseFiles(yangModels);
 
         assertNotNull("context is null", context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull("genTypes is null", genTypes);
index 030cd11757544a5ceb2eb131680560f22c309e4a..419551a2d7bdcf5053cdd6649fb062d11e7dec0f 100644 (file)
@@ -17,6 +17,7 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
@@ -39,7 +40,7 @@ public class BitAndUnionTOEnclosingTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         genTypes = bindingGen.generateTypes(context);
 
         for (Type type : genTypes) {
index 7498a10a64a04eb1ed47b314c24bf1307abd571f..e7c28d7e0202a8f35bfcfb3b89437a602165641d 100644 (file)
@@ -15,6 +15,7 @@ import static org.opendaylight.yangtools.sal.binding.generator.impl.SupportTestU
 
 import java.io.IOException;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
@@ -30,7 +31,7 @@ public class ChoiceCaseGenTypesTest extends AbstractTypesTest {
         super(ChoiceCaseGenTypesTest.class.getResource("/choice-case-type-test-models"));
     }
 
-    private GeneratedType checkGeneratedType(List<Type> genTypes, String genTypeName, String packageName, int occurences) {
+    private GeneratedType checkGeneratedType(final List<Type> genTypes, final String genTypeName, final String packageName, final int occurences) {
         GeneratedType searchedGenType = null;
         int searchedGenTypeCounter = 0;
         for (Type type : genTypes) {
@@ -49,7 +50,7 @@ public class ChoiceCaseGenTypesTest extends AbstractTypesTest {
 
     }
 
-    private GeneratedType checkGeneratedType(List<Type> genTypes, String genTypeName, String packageName) {
+    private GeneratedType checkGeneratedType(final List<Type> genTypes, final String genTypeName, final String packageName) {
         return checkGeneratedType(genTypes, genTypeName, packageName, 1);
     }
 
@@ -59,7 +60,7 @@ public class ChoiceCaseGenTypesTest extends AbstractTypesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull("context is null", context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull("genTypes is null", genTypes);
index 221ff7807643fb7d0ea608565745ccc6e49f50b0..0fde6324ef904a0763e612d15522360274af0359 100644 (file)
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.util.Arrays;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -30,7 +31,7 @@ public class ControllerTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Arrays.asList(cn, co, ietfInetTypes));
         assertNotNull("Schema Context is null", context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
index 27ac8add50543a79f35b678b6ee2588802a22f2b..329934fb3091db0e97f7f44632225098230df304 100644 (file)
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.util.Arrays;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
@@ -34,7 +35,7 @@ public class ExtendedTypedefTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Arrays.asList(abstractTopology, ietfInetTypes));
         assertNotNull("Schema Context is null", context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         GeneratedTransferObject simpleTypedef4 = null;
index c00afcf2e8581b332ab80d5fcd21ff5cddb4ab51..1227d70e3ab7f6806d39b7d3b1a86d53258ac031 100644 (file)
@@ -17,6 +17,7 @@ import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration;
@@ -37,7 +38,7 @@ public class GenEnumResolvingTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Arrays.asList(ietfInterfaces, ianaIfTypeModel));
         assertTrue(context != null);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
         assertTrue(genTypes != null);
 
@@ -98,7 +99,7 @@ public class GenEnumResolvingTest {
         File ianaIfType = new File(getClass().getResource("/ietf/iana-if-type.yang").toURI());
         final SchemaContext context = new YangParserImpl().parseFiles(Collections.singleton(ianaIfType));
         assertTrue(context != null);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
         assertTrue(genTypes != null);
         assertEquals(1, genTypes.size());
@@ -121,7 +122,7 @@ public class GenEnumResolvingTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Arrays.asList(abstractTopology, ietfInterfaces,
                 ianaIfType));
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
         assertNotNull(genTypes);
         assertTrue(!genTypes.isEmpty());
index 59f0e135f4538356f61f052859b04de8308e1700..5f3988a0f6584eff8ff25e37348ea9aea980a030 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -48,7 +49,7 @@ public class GenTypesSubSetTest {
 
         assertEquals("Set of to Generate Modules must contain 2 modules", 2, toGenModules.size());
         assertNotNull("Schema Context is null", context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context, toGenModules);
         assertNotNull("genTypes is null", genTypes);
         assertFalse("genTypes is empty", genTypes.isEmpty());
@@ -82,7 +83,7 @@ public class GenTypesSubSetTest {
         }
         assertEquals("Set of to Generate Modules must contain 3 modules", 3, toGenModules.size());
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context, toGenModules);
         assertNotNull("genTypes is null", genTypes);
         assertFalse("genTypes is empty", genTypes.isEmpty());
index cc03ea4aafee6c38d503a5ca89668f2f16323604..d48f736fda39319e4ac1ca34c6f6df02c0251081 100644 (file)
@@ -13,9 +13,9 @@ import java.io.File;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
-import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
@@ -30,8 +30,8 @@ public class GenerateInnerClassForBitsAndUnionInLeavesTest {
         final YangContextParser parser = new YangParserImpl();
 
         final List<File> inputFiles = new ArrayList<File>();
-        for (int i = 0; i < yangFiles.length; ++i) {
-            inputFiles.add(new File(yangFiles[i]));
+        for (URI yangFile : yangFiles) {
+            inputFiles.add(new File(yangFile));
         }
 
         return parser.parseFiles(inputFiles);
@@ -44,7 +44,7 @@ public class GenerateInnerClassForBitsAndUnionInLeavesTest {
         final SchemaContext context = resolveSchemaContextFromFiles(yangTypesPath);
         assertTrue(context != null);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
         assertTrue(genTypes != null);
 
index 1dc8f00dde6757309805380aa0ff635f7c558fb2..16abfd7b1c9fcc47f434ce84bc4bb6158245a999 100644 (file)
@@ -14,6 +14,7 @@ import static org.junit.Assert.assertTrue;
 
 import java.net.URI;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
@@ -34,7 +35,7 @@ public class GeneratedTypesBitsTest {
         final SchemaContext context = SupportTestUtil.resolveSchemaContextFromFiles(yangTypesPath);
         assertTrue(context != null);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
         assertTrue(genTypes != null);
 
index 1d8649be272f4f209deb5e59e2e9613d534c02bf..70d242ee3f0fb73f94190abefcac8db58171234b 100644 (file)
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.fail;
 
 import com.google.common.io.ByteSource;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -23,6 +24,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
@@ -51,8 +53,8 @@ public class GeneratedTypesLeafrefTest {
         final YangContextParser parser = new YangParserImpl();
 
         final List<File> inputFiles = new ArrayList<File>();
-        for (int i = 0; i < yangFiles.length; ++i) {
-            inputFiles.add(new File(yangFiles[i]));
+        for (URI yangFile : yangFiles) {
+            inputFiles.add(new File(yangFile));
         }
 
         return parser.parseFiles(inputFiles);
@@ -71,7 +73,7 @@ public class GeneratedTypesLeafrefTest {
         assertNotNull(context);
         assertEquals(4, context.getModules().size());
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertEquals(54, genTypes.size());
@@ -252,7 +254,7 @@ public class GeneratedTypesLeafrefTest {
         assertNotNull(context);
         assertEquals(1, context.getModules().size());
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         try {
             bindingGen.generateTypes(context);
             fail("Expected IllegalArgumentException caused by invalid leafref path");
index d0f15174f384d2aa3e58d8d4d05dfc4d92b56ccd..fa7e0bfc59a9d679fd35ae50405d70083470f776 100644 (file)
@@ -15,6 +15,7 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
@@ -43,7 +44,7 @@ public class GeneratedTypesStringTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         boolean typedefStringFound = false;
@@ -64,35 +65,41 @@ public class GeneratedTypesStringTest {
                     for (Constant con : constants) {
                         if (con.getName().equals("PATTERN_CONSTANTS")) {
                             constantRegExListFound = true;
-                        } else
+                        } else {
                             break;
+                        }
                         ParameterizedType pType;
                         if (con.getType() instanceof ParameterizedType) {
                             pType = (ParameterizedType) con.getType();
-                        } else
+                        } else {
                             break;
+                        }
 
                         Type[] types;
                         if (pType.getName().equals("List")) {
                             constantRegExListTypeContainer = true;
                             types = pType.getActualTypeArguments();
-                        } else
+                        } else {
                             break;
+                        }
 
                         if (types.length == 1) {
                             constantRegExListTypeOneGeneric = true;
-                        } else
+                        } else {
                             break;
+                        }
 
                         if (types[0].getName().equals("String")) {
                             constantRegExListTypeGeneric = true;
-                        } else
+                        } else {
                             break;
+                        }
 
                         if (con.getValue() instanceof List) {
                             constantRegExListValueOK = true;
-                        } else
+                        } else {
                             break;
+                        }
 
                         for (Object obj : (List<?>) con.getValue()) {
                             if (!(obj instanceof String)) {
index f929414609a10a2f2670abcc6056f2528b238595..6ab45367de7d339128e4325c339909cb9ac7576f 100644 (file)
@@ -16,6 +16,7 @@ import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
@@ -36,7 +37,7 @@ public class GeneratedTypesTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Arrays.asList(abstractTopology, ietfInetTypes));
         assertNotNull(context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
@@ -49,7 +50,7 @@ public class GeneratedTypesTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Collections.singleton(testFile));
         assertNotNull(context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
@@ -134,7 +135,7 @@ public class GeneratedTypesTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Collections.singleton(testFile));
         assertNotNull(context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
@@ -218,7 +219,7 @@ public class GeneratedTypesTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Collections.singleton(testFile));
         assertNotNull(context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
@@ -341,7 +342,7 @@ public class GeneratedTypesTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Collections.singleton(testFile));
         assertNotNull(context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
@@ -393,7 +394,7 @@ public class GeneratedTypesTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Collections.singleton(testFile));
         assertNotNull(context);
 
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull(genTypes);
index ff81f55bebbe62a670986625e080471e7b6905f4..0c20b91b01e6cdad970f5fd9744279a9933e1075 100644 (file)
@@ -16,6 +16,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
@@ -60,7 +61,7 @@ public class IdentityrefTypeTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         GeneratedType moduleGenType = null;
index 76b13bfedb0f36f6c2e0a0e8e66f70e510cdeb21..ae8a3eb3d4c3d3bb180f85fb7b74d0ddacd86512 100644 (file)
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertNotNull;
 import java.io.File;
 import java.util.Arrays;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -28,7 +29,7 @@ public class UnionTypeDefTest {
         final SchemaContext context = new YangParserImpl().parseFiles(Arrays.asList(abstractTopology, ietfInetTypes));
 
         assertNotNull("context is null", context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         assertNotNull("genTypes is null", genTypes);
index 8c4cb56c361e7323b36748f776a56c216e23d063..524ef51962fd070976da7715c6d611ff82c635ae 100644 (file)
@@ -18,6 +18,7 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
@@ -29,7 +30,7 @@ import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
 public class UsesTest {
 
-    private static List<File> loadTestResources(String testFile) {
+    private static List<File> loadTestResources(final String testFile) {
         try {
         final List<File> testModels = new ArrayList<File>();
         final File listModelFile = new File(UsesTest.class.getResource(testFile).toURI());
@@ -47,7 +48,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
         GeneratedType groupingU = null;
         GeneratedType groupingX = null;
@@ -102,7 +103,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         GeneratedType groupingCaseTest = null;
@@ -150,7 +151,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         int containerTestCount = 0;
@@ -203,7 +204,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         int groupingTestCount = 0;
@@ -254,7 +255,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         int listTestCounter = 0;
@@ -336,7 +337,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         int groupingModulTestCounter = 0;
@@ -387,7 +388,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         int rpcTestInputCounter = 0;
@@ -480,7 +481,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         GeneratedType containerAugment1 = null;
@@ -533,7 +534,7 @@ public class UsesTest {
         final SchemaContext context = parser.parseFiles(testModels);
 
         assertNotNull(context);
-        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final BindingGenerator bindingGen = new BindingGeneratorImpl(true);
         final List<Type> genTypes = bindingGen.generateTypes(context);
 
         GeneratedType notificationTest = null;
index 7e457727033cd1492ed3b3fbcac02c63824b0716..9ecaeb485288d219b096792e020863d4edb544b5 100644 (file)
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>ietf-inet-types</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-restconf</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>ietf-yang-types</artifactId>
index 45f1a8de1bec4c3f71a5f4ff46a9e54b9af46b32..baba09124cca17d37796fa74e1f169066eb3cd3e 100644 (file)
@@ -24,6 +24,7 @@
         <bundle>mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf.inet.types.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf.yang.types.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types-20130715/${ietf.yang.types.20130715.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools.model/ietf-restconf/${ietf.restconf.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools.model/yang-ext/${yang.ext.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools.model/opendaylight-l2-types/${opendaylight.l2.types.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools.model/ietf-topology/${ietf.topology.version}</bundle>
index f39968b8d2e7960ebeb109523540fa4ff9e05d10..914d1973bfd16a04b0517e71ee51ababdb0753f5 100644 (file)
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
                 <artifactId>ietf-restconf</artifactId>
-                <version>2013.09.04.1-SNAPSHOT</version>
+                <version>${ietf.restconf.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools.model</groupId>
diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/ConcurrentDurationStatisticsTracker.java b/common/util/src/main/java/org/opendaylight/yangtools/util/ConcurrentDurationStatisticsTracker.java
new file mode 100644 (file)
index 0000000..a06abbe
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.util;
+
+import com.google.common.primitives.UnsignedLong;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+/**
+ * Concurrent version of {@link DurationStatisticsTracker}.
+ */
+// TODO: once DurationStatsTracker is gone make this class final
+class ConcurrentDurationStatisticsTracker extends DurationStatisticsTracker {
+    private static final AtomicReferenceFieldUpdater<ConcurrentDurationStatisticsTracker, DurationWithTime> LONGEST_UPDATER =
+            AtomicReferenceFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, DurationWithTime.class, "longest");
+    private static final AtomicReferenceFieldUpdater<ConcurrentDurationStatisticsTracker, DurationWithTime> SHORTEST_UPDATER =
+            AtomicReferenceFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, DurationWithTime.class, "shortest");
+    private static final AtomicLongFieldUpdater<ConcurrentDurationStatisticsTracker> COUNT_UPDATER =
+            AtomicLongFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, "count");
+    private static final AtomicLongFieldUpdater<ConcurrentDurationStatisticsTracker> SUM_UPDATER =
+            AtomicLongFieldUpdater.newUpdater(ConcurrentDurationStatisticsTracker.class, "sum");
+
+    private volatile long sum = 0;
+    private volatile long count = 0;
+    private volatile DurationWithTime longest = null;
+    private volatile DurationWithTime shortest = null;
+
+    ConcurrentDurationStatisticsTracker() {
+        // Hidden on purpose
+    }
+
+    @Override
+    public final void addDuration(final long duration) {
+        // First update the quick stats
+        SUM_UPDATER.addAndGet(this, duration);
+        COUNT_UPDATER.incrementAndGet(this);
+
+        /*
+         * Now the hairy 'min/max' things. The notion of "now" we cache,
+         * so the first time we use it, we do not call it twice. We populate
+         * it lazily, though.
+         *
+         * The longest/shortest stats both are encapsulated in an object,
+         * so we update them atomically and we minimize the number of volatile
+         * operations.
+         */
+        DurationWithTime current = shortest;
+        if (current == null || duration < current.getDuration()) {
+            final DurationWithTime newObj = new DurationWithTime(duration, System.currentTimeMillis());
+            while (!SHORTEST_UPDATER.weakCompareAndSet(this, current, newObj)) {
+                current = shortest;
+                if (current != null && duration >= current.getDuration()) {
+                    break;
+                }
+            }
+        }
+
+        current = longest;
+        if (current == null || duration > current.getDuration()) {
+            final DurationWithTime newObj = new DurationWithTime(duration, System.currentTimeMillis());
+            while (!LONGEST_UPDATER.weakCompareAndSet(this, current, newObj)) {
+                current = longest;
+                if (current != null && duration <= current.getDuration()) {
+                    break;
+                }
+            }
+        }
+    }
+
+    @Override
+    public final long getTotalDurations() {
+        return count;
+    }
+
+    @Override
+    public final double getAverageDuration() {
+        final long myCount = count;
+        return myCount == 0 ? 0 : UnsignedLong.fromLongBits(sum).doubleValue() / myCount;
+    }
+
+    @Override
+    public final synchronized void reset() {
+        // Synchronized is just to make sure we do not have concurrent resets :)
+        longest = null;
+        shortest = null;
+        count = 0;
+        sum = 0;
+    }
+
+    @Override
+    protected final DurationWithTime getLongest() {
+        return longest;
+    }
+
+    @Override
+    protected final DurationWithTime getShortest() {
+        return shortest;
+    }
+}
diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/DurationStatisticsTracker.java b/common/util/src/main/java/org/opendaylight/yangtools/util/DurationStatisticsTracker.java
new file mode 100644 (file)
index 0000000..10cb39c
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.util;
+
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import com.google.common.annotations.Beta;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class that calculates and tracks time duration statistics.
+ *
+ * @author Thomas Pantelis
+ * @author Robert Varga
+ */
+@Beta
+public abstract class DurationStatisticsTracker {
+    private static final Logger LOG = LoggerFactory.getLogger(DurationStatisticsTracker.class);
+    private static final DecimalFormat DECIMAL_FORMAT;
+
+    static {
+        final DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
+        symbols.setDecimalSeparator('.');
+        DECIMAL_FORMAT = new DecimalFormat("0.00", symbols);
+    }
+
+    /**
+     * Create a concurrent {@link DurationStatisticsTracker}, which performs well
+     * in very contended environments.
+     *
+     * @return A new instance.
+     */
+    public static DurationStatisticsTracker createConcurrent() {
+        return new ConcurrentDurationStatisticsTracker();
+    }
+
+    /**
+     * Create a synchronized {@link DurationStatisticsTracker}, which performs well
+     * in non-contended environments.
+     *
+     * @return A new instance.
+     */
+    public static DurationStatisticsTracker createSynchronized() {
+        return new SynchronizedDurationStatsTracker();
+    }
+
+    /**
+     * Add a duration to track.
+     *
+     * @param duration
+     *            non-negative duration in nanoseconds.
+     */
+    public abstract void addDuration(long duration);
+
+    /**
+     * Returns the average duration in nanoseconds.
+     */
+    public abstract double getAverageDuration();
+
+    /**
+     * Returns the total number of tracked durations.
+     *
+     * @return Total number of measurements accumulated since last
+     *         {@link #reset()}.
+     */
+    public abstract long getTotalDurations();
+
+    /**
+     * Resets all statistics back to their defaults.
+     */
+    public abstract void reset();
+
+    /**
+     * Get the shortest recorded duration and the time when it was recorded.
+     *
+     * @return Duration and timestamp.
+     */
+    protected abstract DurationWithTime getShortest();
+
+    /**
+     * Get the longest recorded duration and the time when it was recorded.
+     *
+     * @return Duration and timestamp.
+     */
+    protected abstract DurationWithTime getLongest();
+
+    /**
+     * Returns the longest duration in nanoseconds.
+     */
+    public final long getLongestDuration() {
+        return getDuration(getLongest());
+    }
+
+    /**
+     * Returns the shortest duration in nanoseconds.
+     */
+    public final long getShortestDuration() {
+        return getDuration(getShortest());
+    }
+
+    /**
+     * Returns the average duration as a displayable String with units, e.g.
+     * "12.34 ms".
+     */
+    public final String getDisplayableAverageDuration() {
+        return formatDuration(getAverageDuration(), null);
+    }
+
+    /**
+     * Returns the longest duration as a displayable String with units and the
+     * date/time at which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
+     */
+    public final String getDisplayableLongestDuration() {
+        return formatDuration(getLongest());
+    }
+
+    /**
+     * Returns the shortest duration as a displayable String with units and the
+     * date/time at which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
+     */
+    public final String getDisplayableShortestDuration() {
+        return formatDuration(getShortest());
+    }
+
+    /**
+     * Returns the time stamp of the longest duration.
+     */
+    public final long getTimeOfLongestDuration() {
+        return getTimeMillis(getLongest());
+    }
+
+    /**
+     * Returns the time stamp of the shortest duration.
+     */
+    public final long getTimeOfShortestDuration() {
+        return getTimeMillis(getShortest());
+    }
+
+    /**
+     * Returns formatted value of number, e.g. "12.34". Always is used dot as
+     * decimal separator.
+     */
+    private static synchronized String formatDecimalValue(final double value) {
+        return DECIMAL_FORMAT.format(value);
+    }
+
+    private static long getDuration(final DurationWithTime current) {
+        return current == null ? 0L : current.getDuration();
+    }
+
+    private static long getTimeMillis(final DurationWithTime current) {
+        return current == null ? 0L : current.getTimeMillis();
+    }
+
+    private static String formatDuration(final double duration, final Long timeStamp) {
+        final TimeUnit unit = chooseUnit((long) duration);
+        final double value = duration / NANOSECONDS.convert(1, unit);
+
+        final StringBuilder sb = new StringBuilder();
+        sb.append(formatDecimalValue(value));
+        sb.append(' ');
+        sb.append(abbreviate(unit));
+
+        if (timeStamp != null) {
+            sb.append(String.format(" at %1$tD %1$tT", new Date(timeStamp)));
+        }
+
+        return sb.toString();
+    }
+
+    private static String formatDuration(final DurationWithTime current) {
+        if (current != null) {
+            return formatDuration(current.getDuration(), current.getTimeMillis());
+        } else {
+            return formatDuration(0, null);
+        }
+    }
+
+    private static TimeUnit chooseUnit(final long nanos) {
+        // TODO: this could be inlined, as we are doing needless divisions
+        if (NANOSECONDS.toSeconds(nanos) > 0) {
+            return SECONDS;
+        }
+        if (NANOSECONDS.toMillis(nanos) > 0) {
+            return MILLISECONDS;
+        }
+        if (NANOSECONDS.toMicros(nanos) > 0) {
+            return MICROSECONDS;
+        }
+        return NANOSECONDS;
+    }
+
+    private static String abbreviate(final TimeUnit unit) {
+        switch (unit) {
+        case NANOSECONDS:
+            return "ns";
+        case MICROSECONDS:
+            return "\u03bcs"; // Î¼s
+        case MILLISECONDS:
+            return "ms";
+        case SECONDS:
+            return "s";
+        case MINUTES:
+            return "m";
+        case HOURS:
+            return "h";
+        case DAYS:
+            return "d";
+        }
+
+        LOG.warn("Unhandled time unit {}", unit);
+        return "";
+    }
+}
index 9a29dca6a8002eaf1b62f96a44baaa8c7a2d69ce..ca85e83d9554fa86300aa1ab75a993fadc4db06e 100644 (file)
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.yangtools.util;
 
-import static java.util.concurrent.TimeUnit.MICROSECONDS;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import com.google.common.util.concurrent.AtomicDouble;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.Date;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
 /**
  * Class that calculates and tracks time duration statistics.
  *
  * @author Thomas Pantelis
+ * @author Robert Varga
+ *
+ * @deprecated Use {@link DurationStatisticsTracker} instead.
  */
-public class DurationStatsTracker {
-
-    private static final DecimalFormat decimalFormat;
-
-    private final AtomicLong totalDurations = new AtomicLong();
-    private final AtomicLong longestDuration = new AtomicLong();
-    private volatile long timeOfLongestDuration;
-    private final AtomicLong shortestDuration = new AtomicLong(Long.MAX_VALUE);
-    private volatile long timeOfShortestDuration;
-    private final AtomicDouble averageDuration = new AtomicDouble();
-
-    static {
-        final DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
-        symbols.setDecimalSeparator('.');
-        decimalFormat = new DecimalFormat("0.00", symbols);
-    }
-
+@Deprecated
+public class DurationStatsTracker extends ConcurrentDurationStatisticsTracker {
     /**
-     * Add a duration to track.
-     *
-     * @param duration
-     *            the duration in nanoseconds.
+     * @deprecated Use {@link DurationStatisticsTracker#createConcurrent() instead.
      */
-    public void addDuration(long duration) {
+    @Deprecated
+    public DurationStatsTracker() {
 
-        double currentAve = averageDuration.get();
-        long currentTotal = totalDurations.get();
-
-        long newTotal = currentTotal + 1;
-
-        // Calculate moving cumulative average.
-        double newAve = currentAve * currentTotal / newTotal + (double) duration / (double) newTotal;
-
-        averageDuration.compareAndSet(currentAve, newAve);
-        totalDurations.compareAndSet(currentTotal, newTotal);
-
-        long longest = longestDuration.get();
-        if (duration > longest) {
-            if (longestDuration.compareAndSet(longest, duration)) {
-                timeOfLongestDuration = System.currentTimeMillis();
-            }
-        }
-
-        long shortest = shortestDuration.get();
-        if (duration < shortest) {
-            if (shortestDuration.compareAndSet(shortest, duration)) {
-                timeOfShortestDuration = System.currentTimeMillis();
-            }
-        }
     }
 
-    /**
-     * Returns the total number of tracked durations.
-     */
-    public long getTotalDurations() {
-        return totalDurations.get();
-    }
-
-    /**
-     * Returns the longest duration in nanoseconds.
-     */
-    public long getLongestDuration() {
-        return longestDuration.get();
-    }
-
-    /**
-     * Returns the shortest duration in nanoseconds.
-     */
-    public long getShortestDuration() {
-        long shortest = shortestDuration.get();
-        return shortest < Long.MAX_VALUE ? shortest : 0;
-    }
-
-    /**
-     * Returns the average duration in nanoseconds.
-     */
-    public double getAverageDuration() {
-        return averageDuration.get();
-    }
-
-    /**
-     * Returns the time stamp of the longest duration.
-     */
-    public long getTimeOfLongestDuration() {
-        return timeOfLongestDuration;
-    }
-
-    /**
-     * Returns the time stamp of the shortest duration.
-     */
-    public long getTimeOfShortestDuration() {
-        return timeOfShortestDuration;
-    }
-
-    /**
-     * Resets all statistics back to their defaults.
-     */
-    public void reset() {
-        totalDurations.set(0);
-        longestDuration.set(0);
-        timeOfLongestDuration = 0;
-        shortestDuration.set(Long.MAX_VALUE);
-        timeOfShortestDuration = 0;
-        averageDuration.set(0.0);
-    }
-
-    /**
-     * Returns the average duration as a displayable String with units, e.g.
-     * "12.34 ms".
-     */
-    public String getDisplayableAverageDuration() {
-        return formatDuration(getAverageDuration(), 0);
-    }
-
-    /**
-     * Returns the shortest duration as a displayable String with units and the
-     * date/time at which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
-     */
-    public String getDisplayableShortestDuration() {
-        return formatDuration(getShortestDuration(), getTimeOfShortestDuration());
-    }
-
-    /**
-     * Returns the longest duration as a displayable String with units and the
-     * date/time at which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
-     */
-    public String getDisplayableLongestDuration() {
-        return formatDuration(getLongestDuration(), getTimeOfLongestDuration());
-    }
-
-    /**
-     * Returns formatted value of number, e.g. "12.34". Always is used dot as
-     * decimal separator.
-     */
-    private static synchronized String formatDecimalValue(double value) {
-        return decimalFormat.format(value);
-    }
-
-    private String formatDuration(double duration, long timeStamp) {
-        TimeUnit unit = chooseUnit((long) duration);
-        double value = duration / NANOSECONDS.convert(1, unit);
-
-        return timeStamp > 0 ? String.format("%s %s at %3$tD %3$tT", formatDecimalValue(value), abbreviate(unit),
-                new Date(timeStamp)) : String.format("%s %s", formatDecimalValue(value), abbreviate(unit));
-    }
-
-    private static TimeUnit chooseUnit(long nanos) {
-        if (SECONDS.convert(nanos, NANOSECONDS) > 0) {
-            return SECONDS;
-        }
-
-        if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
-            return MILLISECONDS;
-        }
-
-        if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
-            return MICROSECONDS;
-        }
-
-        return NANOSECONDS;
-    }
+    // Remove once the no-argument constructor is removed
+    DurationStatsTracker(final Void dummy) {
 
-    private static String abbreviate(TimeUnit unit) {
-        switch (unit) {
-        case NANOSECONDS:
-            return "ns";
-        case MICROSECONDS:
-            return "\u03bcs"; // Î¼s
-        case MILLISECONDS:
-            return "ms";
-        case SECONDS:
-            return "s";
-        default:
-            return "";
-        }
     }
 }
diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/DurationWithTime.java b/common/util/src/main/java/org/opendaylight/yangtools/util/DurationWithTime.java
new file mode 100644 (file)
index 0000000..aa77678
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.util;
+
+/**
+ * Utility holder for a duration/time of occurance.
+ */
+final class DurationWithTime {
+    private final long duration;
+    private final long timeMillis;
+
+    DurationWithTime(final long duration, final long timeMillis) {
+        this.duration = duration;
+        this.timeMillis = timeMillis;
+    }
+
+    long getDuration() {
+        return duration;
+    }
+
+    long getTimeMillis() {
+        return timeMillis;
+    }
+}
\ No newline at end of file
diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/SynchronizedDurationStatsTracker.java b/common/util/src/main/java/org/opendaylight/yangtools/util/SynchronizedDurationStatsTracker.java
new file mode 100644 (file)
index 0000000..b3e9007
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.util;
+
+import com.google.common.primitives.UnsignedLong;
+
+/**
+ * Non-concurrent implementation, useful for non-contended cases.
+ */
+final class SynchronizedDurationStatsTracker extends DurationStatisticsTracker {
+    private static final long NOT_SET = -1;
+
+    // Hot fields in the order in which they are accessed
+    private long durationSum = 0;
+    private long durationCount = 0;
+    private long shortestDuration = NOT_SET;
+    private long longestDuration = NOT_SET;
+
+    // Cold fields, longest has a higher chance of being accessed
+    private long longestTimestamp;
+    private long shortestTimestamp;
+
+    SynchronizedDurationStatsTracker() {
+        // Hidden on purpose
+    }
+
+    @Override
+    public synchronized void addDuration(final long duration) {
+        durationSum += duration;
+        durationCount++;
+
+        if (duration < shortestDuration || shortestDuration == NOT_SET) {
+            shortestDuration = duration;
+            shortestTimestamp = System.currentTimeMillis();
+        }
+        if (duration > longestDuration) {
+            longestDuration = duration;
+            longestTimestamp = System.currentTimeMillis();
+        }
+    }
+
+    @Override
+    public synchronized double getAverageDuration() {
+        return durationCount == 0 ? 0 : UnsignedLong.fromLongBits(durationSum).doubleValue() / durationCount;
+    }
+
+    @Override
+    public synchronized long getTotalDurations() {
+        return durationCount;
+    }
+
+    @Override
+    public synchronized void reset() {
+        durationSum = 0;
+        durationCount = 0;
+        longestDuration = NOT_SET;
+        shortestDuration = NOT_SET;
+    }
+
+    @Override
+    protected synchronized DurationWithTime getShortest() {
+        return shortestDuration == NOT_SET ? null : new DurationWithTime(shortestDuration, shortestTimestamp);
+    }
+
+    @Override
+    protected synchronized DurationWithTime getLongest() {
+        return longestDuration == NOT_SET ? null : new DurationWithTime(longestDuration, longestTimestamp);
+    }
+}
index bec56bf76fe77f54467ab5fc00e46d9f03eb1a59..452b2fa99e78965f5949a83801f738db137be34b 100644 (file)
@@ -11,7 +11,6 @@ import java.io.Serializable;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Date;
-
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.objcache.ObjectCache;
 import org.opendaylight.yangtools.objcache.ObjectCacheFactory;
@@ -31,7 +30,7 @@ public final class QNameModule implements Immutable, Serializable {
     private final Date revision;
 
     //Nullable
-    private String formattedRevision;
+    private volatile String formattedRevision;
 
     private QNameModule(final URI namespace, final Date revision) {
         this.namespace = namespace;
@@ -68,15 +67,13 @@ public final class QNameModule implements Immutable, Serializable {
             return null;
         }
 
-        if (formattedRevision == null) {
-            synchronized (this) {
-                if (formattedRevision == null) {
-                    formattedRevision = SimpleDateFormatUtil.getRevisionFormat().format(revision);
-                }
-            }
+        String ret = formattedRevision;
+        if (ret == null) {
+            ret = SimpleDateFormatUtil.getRevisionFormat().format(revision);
+            formattedRevision = ret;
         }
 
-        return formattedRevision;
+        return ret;
     }
 
     /**
index 84ebdf0f2035f30446e0098220050a80e9e7399d..2916b88e8bfde2898622e3076b151f5e0b8421c5 100644 (file)
@@ -13,7 +13,6 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-
 import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
@@ -25,7 +24,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
-
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.concepts.Path;
@@ -67,6 +66,11 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
  * @see http://tools.ietf.org/html/rfc6020#section-9.13
  */
 public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier>, Immutable, Serializable {
+    @SuppressWarnings("rawtypes")
+    private static final AtomicReferenceFieldUpdater<YangInstanceIdentifier, ImmutableList> LEGACYPATH_UPDATER =
+            AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, ImmutableList.class, "legacyPath");
+    private static final AtomicReferenceFieldUpdater<YangInstanceIdentifier, String> TOSTRINGCACHE_UPDATER =
+            AtomicReferenceFieldUpdater.newUpdater(YangInstanceIdentifier.class, String.class, "toStringCache");
     private static final YangInstanceIdentifier EMPTY = trustedCreate(Collections.<PathArgument>emptyList());
 
     private static final long serialVersionUID = 2L;
@@ -80,11 +84,10 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         // Temporary variable saves a volatile read
         ImmutableList<PathArgument> ret = legacyPath;
         if (ret == null) {
-            synchronized (this) {
-                // We could have used a synchronized block, but let's just not bother
-                ret = ImmutableList.copyOf(pathArguments);
-                legacyPath = ret;
-            }
+            // We could have used a synchronized block, but the window is quite
+            // small and worst that can happen is duplicate object construction.
+            ret = ImmutableList.copyOf(pathArguments);
+            LEGACYPATH_UPDATER.lazySet(this, ret);
         }
 
         return ret;
@@ -354,6 +357,8 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
     }
 
     private static abstract class AbstractPathArgument implements PathArgument {
+        private static final AtomicReferenceFieldUpdater<AbstractPathArgument, Integer> HASH_UPDATER =
+                AtomicReferenceFieldUpdater.newUpdater(AbstractPathArgument.class, Integer.class, "hash");
         private static final long serialVersionUID = -4546547994250849340L;
         private final QName nodeType;
         private volatile transient Integer hash = null;
@@ -380,13 +385,8 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
         public final int hashCode() {
             Integer ret = hash;
             if (ret == null) {
-                synchronized (this) {
-                    ret = hash;
-                    if (ret == null) {
-                        ret = hashCodeImpl();
-                        hash = ret;
-                    }
-                }
+                ret = hashCodeImpl();
+                HASH_UPDATER.lazySet(this, ret);
             }
 
             return ret;
@@ -787,23 +787,18 @@ public final class YangInstanceIdentifier implements Path<YangInstanceIdentifier
          */
         String ret = toStringCache;
         if (ret == null) {
-            synchronized (this) {
-                ret = toStringCache;
-                if (ret == null) {
-                    final StringBuilder builder = new StringBuilder("/");
-                    PathArgument prev = null;
-                    for (PathArgument argument : getPathArguments()) {
-                        if (prev != null) {
-                            builder.append('/');
-                        }
-                        builder.append(argument.toRelativeString(prev));
-                        prev = argument;
-                    }
-
-                    ret = builder.toString();
-                    toStringCache = ret;
+            final StringBuilder builder = new StringBuilder("/");
+            PathArgument prev = null;
+            for (PathArgument argument : getPathArguments()) {
+                if (prev != null) {
+                    builder.append('/');
                 }
+                builder.append(argument.toRelativeString(prev));
+                prev = argument;
             }
+
+            ret = builder.toString();
+            TOSTRINGCACHE_UPDATER.lazySet(this, ret);
         }
         return ret;
     }
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/SynchronizedDataTreeModification.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/SynchronizedDataTreeModification.java
new file mode 100644 (file)
index 0000000..d78f6fa
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.api.schema.tree;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * A {@link DataTreeModification} implementation which delegates all calls to
+ * another instance, making sure no method is being invoked from multiple threads
+ * concurrently.
+ */
+public final class SynchronizedDataTreeModification implements DataTreeModification {
+    private final DataTreeModification delegate;
+
+    private SynchronizedDataTreeModification(final DataTreeModification delegate) {
+        this.delegate = Preconditions.checkNotNull(delegate);
+    }
+
+    public DataTreeModification create(final DataTreeModification delegate) {
+        return new SynchronizedDataTreeModification(delegate);
+    }
+
+    @Override
+    public synchronized Optional<NormalizedNode<?, ?>> readNode(final YangInstanceIdentifier path) {
+        return delegate.readNode(path);
+    }
+
+    @Override
+    public synchronized DataTreeModification newModification() {
+        return delegate.newModification();
+    }
+
+    @Override
+    public synchronized void delete(final YangInstanceIdentifier path) {
+        delegate.delete(path);
+    }
+
+    @Override
+    public synchronized void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        delegate.merge(path, data);
+    }
+
+    @Override
+    public synchronized void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        delegate.write(path, data);
+    }
+
+    @Override
+    public synchronized void ready() {
+        delegate.ready();
+    }
+}
index 643e9de9ad041f9b2c4c3c02bf6e3d3317061295..8fcc596ab47ebe3e8e5d2ed86ecb00f8cc2d104e 100644 (file)
@@ -11,11 +11,9 @@ import com.google.common.base.CharMatcher;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.gson.stream.JsonWriter;
-
 import java.io.IOException;
 import java.io.Writer;
 import java.net.URI;
-
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -136,7 +134,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
         final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
 
         context.emittingChild(codecs.getSchemaContext(), writer, indent);
-        context.writeJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
+        context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
         writeValue(codec.serialize(value), codec.needQuotes());
     }
 
@@ -211,11 +209,12 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     @Override
     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
+        @SuppressWarnings("unused")
         final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
         // FIXME: should have a codec based on this :)
 
         context.emittingChild(codecs.getSchemaContext(), writer, indent);
-        context.writeJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
+        context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
         writeValue(String.valueOf(value), true);
     }
 
index 1a5181a5789f2e81982348fc263623e0f7a7e049..a3ad80dfb3f28473b523f3b12c1a1cc335063715 100644 (file)
@@ -8,13 +8,10 @@
 package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import com.google.common.base.Preconditions;
-
 import java.io.IOException;
 import java.io.Writer;
 import java.net.URI;
-
 import javax.annotation.Nonnull;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -50,7 +47,7 @@ abstract class JSONStreamWriterContext {
     }
 
     /**
-     * Write a JSON node identifier, optionally prefixing it with the module name
+     * Write a child JSON node identifier, optionally prefixing it with the module name
      * corresponding to its namespace.
      *
      * @param schema Schema context
@@ -58,7 +55,7 @@ abstract class JSONStreamWriterContext {
      * @param qname Namespace/name tuple
      * @throws IOException when the writer reports it
      */
-    protected final void writeJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
+    final void writeChildJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
         writer.append('"');
 
         // Prepend module name if namespaces do not match
@@ -75,6 +72,19 @@ abstract class JSONStreamWriterContext {
         writer.append("\":");
     }
 
+    /**
+     * Write our JSON node identifier, optionally prefixing it with the module name
+     * corresponding to its namespace.
+     *
+     * @param schema Schema context
+     * @param writer Output writer
+     * @param qname Namespace/name tuple
+     * @throws IOException when the writer reports it
+     */
+    protected final void writeMyJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
+        parent.writeChildJsonIdentifier(schema, writer, qname);
+    }
+
     /**
      * Return the namespace associated with current node.
      *
@@ -158,4 +168,5 @@ abstract class JSONStreamWriterContext {
         }
         return parent;
     }
+
 }
index ed7bd092c952c3e00552a6ab2aa5b7875f4673a9..9c0be476b1bb332e4d91a2a36f85a6e47cced61a 100644 (file)
@@ -24,7 +24,7 @@ final class JSONStreamWriterListContext extends JSONStreamWriterQNameContext {
 
     @Override
     protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
-        writeJsonIdentifier(schema, writer, getQName());
+        writeMyJsonIdentifier(schema, writer, getQName());
         writer.append('[');
     }
 
index f5e5d487779404a6749e5bc57613390a116f5bcc..91c6ca70ae2c5a613984610bbdba44ae5aeca598 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.data.codec.gson;
 
 import java.io.IOException;
 import java.io.Writer;
-
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -25,7 +24,7 @@ final class JSONStreamWriterNamedObjectContext extends JSONStreamWriterObjectCon
 
     @Override
     protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
-        writeJsonIdentifier(schema, writer, getQName());
+        writeMyJsonIdentifier(schema, writer, getQName());
         super.emitStart(schema, writer);
     }
-}
\ No newline at end of file
+}
index bec315491fc268c169ca5b41f6f1e6aaeb177778..97f676ae69bd62636764d138ea74e2ee4a678fb9 100644 (file)
@@ -7,13 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 
-import com.google.common.base.Preconditions;
+import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX;
 
+import com.google.common.base.Preconditions;
 import java.io.IOException;
-
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
@@ -70,17 +69,22 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
         return new XMLStreamNormalizedNodeStreamWriter(writer, context, path);
     }
 
-    private void writeElement(final QName qname, final TypeDefinition<?> type, final Object value) throws IOException {
-        final String ns = qname.getNamespace().toString();
+    private void writeStartElement( QName qname) throws XMLStreamException {
+        String ns = qname.getNamespace().toString();
+        String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
+        writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
+        if (!ns.equals(parentNs)) {
+            writer.writeDefaultNamespace(ns);
+        }
+    }
 
+    private void writeElement(final QName qname, final TypeDefinition<?> type, final Object value) throws IOException {
         try {
+            writeStartElement(qname);
             if (value != null) {
-                writer.writeStartElement(ns, qname.getLocalName());
                 UTILS.writeValue(writer, type, value);
-                writer.writeEndElement();
-            } else {
-                writer.writeEmptyElement(ns, qname.getLocalName());
             }
+            writer.writeEndElement();
         } catch (XMLStreamException e) {
             throw new IOException("Failed to emit element", e);
         }
@@ -88,7 +92,7 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
 
     private void startElement(final QName qname) throws IOException {
         try {
-            writer.writeStartElement(qname.getNamespace().toString(), qname.getLocalName());
+            writeStartElement(qname);
         } catch (XMLStreamException e) {
             throw new IOException("Failed to start element", e);
         }
@@ -166,16 +170,12 @@ public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNode
     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IOException {
         final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
         final QName qname = schema.getQName();
-        final String ns = qname.getNamespace().toString();
-
         try {
+            writeStartElement(qname);
             if (value != null) {
-                writer.writeStartElement(ns, qname.getLocalName());
                 UTILS.writeValue(writer, (Node<?>)value, schema);
-                writer.writeEndElement();
-            } else {
-                writer.writeEmptyElement(ns, qname.getLocalName());
             }
+            writer.writeEndElement();
         } catch (XMLStreamException e) {
             throw new IOException("Failed to emit element", e);
         }
index b60cf2bc19e878fda63c1cc57d372b75087a3fc9..aa379dc963f11606150fe370339eb21895d7edb8 100644 (file)
@@ -3,16 +3,13 @@ package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-
 import java.net.URI;
 import java.util.Map;
 import java.util.Map.Entry;
-
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -94,7 +91,10 @@ public class XmlStreamUtils {
         final String str = XmlUtils.encodeIdentifier(prefixes, id);
 
         for (Entry<URI, String> e: prefixes.getPrefixes()) {
-            writer.writeNamespace(e.getValue(), e.getKey().toString());
+            final String ns = e.getKey().toString();
+            final String p = e.getValue();
+
+            writer.writeNamespace(p, ns);
         }
         writer.writeCharacters(str);
     }
@@ -268,6 +268,7 @@ public class XmlStreamUtils {
         }
     }
 
+    @SuppressWarnings("deprecation")
     private static void write(final @Nonnull XMLStreamWriter writer, final @Nonnull IdentityrefTypeDefinition type, final @Nonnull Object value) throws XMLStreamException {
         if (value instanceof QName) {
             final QName qname = (QName) value;
@@ -278,7 +279,8 @@ public class XmlStreamUtils {
                 prefix = "x";
             }
 
-            writer.writeNamespace(prefix, qname.getNamespace().toString());
+            final String ns = qname.getNamespace().toString();
+            writer.writeNamespace(prefix, ns);
             writer.writeCharacters(prefix + ':' + qname.getLocalName());
         } else {
             LOG.debug("Value of {}:{} is not a QName but {}", type.getQName().getNamespace(), type.getQName().getLocalName(), value.getClass());
index de4bcef79666b6002ede5051ed2064a763838843..9e0c60f6a091bad054cd1c35c8b2630346be71c9 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import java.util.Map.Entry;
-
-import javax.annotation.concurrent.GuardedBy;
-
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -23,32 +23,31 @@ import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
 final class InMemoryDataTreeModification implements DataTreeModification {
+    private static final AtomicIntegerFieldUpdater<InMemoryDataTreeModification> UPDATER =
+            AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed");
     private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
+
     private final RootModificationApplyOperation strategyTree;
     private final InMemoryDataTreeSnapshot snapshot;
     private final ModifiedNode rootNode;
     private final Version version;
 
-    @GuardedBy("this")
-    private boolean sealed = false;
+    private volatile int sealed = 0;
 
     InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final RootModificationApplyOperation resolver) {
         this.snapshot = Preconditions.checkNotNull(snapshot);
         this.strategyTree = Preconditions.checkNotNull(resolver).snapshot();
         this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode(), false);
+
         /*
          * We could allocate version beforehand, since Version contract
-         * states two allocated version must be allways different.
-         * 
+         * states two allocated version must be always different.
+         *
          * Preallocating version simplifies scenarios such as
          * chaining of modifications, since version for particular
          * node in modification and in data tree (if successfully
-         * commited) will be same and will not change.
-         * 
+         * committed) will be same and will not change.
          */
         this.version = snapshot.getRootNode().getSubtreeVersion().next();
     }
@@ -62,20 +61,21 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public synchronized void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> value) {
+    public void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> value) {
         checkSealed();
+
         resolveModificationFor(path).write(value);
     }
 
     @Override
-    public synchronized void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    public void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkSealed();
+
         mergeImpl(resolveModificationFor(path),data);
     }
 
     private void mergeImpl(final OperationWithModification op,final NormalizedNode<?,?> data) {
-
-        if(data instanceof NormalizedNodeContainer<?,?,?>) {
+        if (data instanceof NormalizedNodeContainer<?,?,?>) {
             @SuppressWarnings({ "rawtypes", "unchecked" })
             NormalizedNodeContainer<?,?,NormalizedNode<PathArgument, ?>> dataContainer = (NormalizedNodeContainer) data;
             for(NormalizedNode<PathArgument, ?> child : dataContainer.getValue()) {
@@ -87,13 +87,14 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public synchronized void delete(final YangInstanceIdentifier path) {
+    public void delete(final YangInstanceIdentifier path) {
         checkSealed();
+
         resolveModificationFor(path).delete();
     }
 
     @Override
-    public synchronized Optional<NormalizedNode<?, ?>> readNode(final YangInstanceIdentifier path) {
+    public Optional<NormalizedNode<?, ?>> readNode(final YangInstanceIdentifier path) {
         /*
          * Walk the tree from the top, looking for the first node between root and
          * the requested path which has been modified. If no such node exists,
@@ -115,7 +116,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     private Optional<TreeNode> resolveSnapshot(final YangInstanceIdentifier path,
             final ModifiedNode modification) {
         final Optional<Optional<TreeNode>> potentialSnapshot = modification.getSnapshotCache();
-        if(potentialSnapshot.isPresent()) {
+        if (potentialSnapshot.isPresent()) {
             return potentialSnapshot.get();
         }
 
@@ -123,14 +124,14 @@ final class InMemoryDataTreeModification implements DataTreeModification {
             return resolveModificationStrategy(path).apply(modification, modification.getOriginal(),
                     version);
         } catch (Exception e) {
-            LOG.error("Could not create snapshot for {}:{}", path,modification,e);
+            LOG.error("Could not create snapshot for {}:{}", path, modification, e);
             throw e;
         }
     }
 
     private ModificationApplyOperation resolveModificationStrategy(final YangInstanceIdentifier path) {
         LOG.trace("Resolving modification apply strategy for {}", path);
-        if(rootNode.getType() == ModificationType.UNMODIFIED) {
+        if (rootNode.getType() == ModificationType.UNMODIFIED) {
             strategyTree.upgradeIfPossible();
         }
 
@@ -138,14 +139,17 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     private OperationWithModification resolveModificationFor(final YangInstanceIdentifier path) {
-        ModifiedNode modification = rootNode;
         // We ensure strategy is present.
-        ModificationApplyOperation operation = resolveModificationStrategy(path);
-        boolean isOrdered = true;
+        final ModificationApplyOperation operation = resolveModificationStrategy(path);
+
+        final boolean isOrdered;
         if (operation instanceof SchemaAwareApplyOperation) {
             isOrdered = ((SchemaAwareApplyOperation) operation).isOrdered();
+        } else {
+            isOrdered = true;
         }
 
+        ModifiedNode modification = rootNode;
         for (PathArgument pathArg : path.getPathArguments()) {
             modification = modification.modifyChild(pathArg, isOrdered);
         }
@@ -153,15 +157,15 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public synchronized void ready() {
-        Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree.");
-        sealed = true;
+    public void ready() {
+        final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
+        Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
+
         rootNode.seal();
     }
 
-    @GuardedBy("this")
     private void checkSealed() {
-        Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed.");
+        Preconditions.checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
     }
 
     @Override
@@ -170,16 +174,17 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public synchronized DataTreeModification newModification() {
-        Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification");
+    public DataTreeModification newModification() {
+        Preconditions.checkState(sealed == 1, "Attempted to chain on an unsealed modification");
 
-        if(rootNode.getType() == ModificationType.UNMODIFIED) {
+        if (rootNode.getType() == ModificationType.UNMODIFIED) {
+            // Simple fast case: just use the underlying modification
             return snapshot.newModification();
         }
 
         /*
-         *  We will use preallocated version, this means returned snapshot will 
-         *  have same version each time this method is called.
+         * We will use preallocated version, this means returned snapshot will
+         * have same version each time this method is called.
          */
         TreeNode originalSnapshotRoot = snapshot.getRootNode();
         Optional<TreeNode> tempRoot = strategyTree.apply(rootNode, Optional.of(originalSnapshotRoot), version);
index 56d240aed1ac426e4fd8ebd30ca4e87a9e09f446..b9f26f1b63a5986132cd7eef5da59553e6ad89dc 100644 (file)
@@ -12,12 +12,11 @@ import com.google.common.base.Objects.ToStringHelper;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
-
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
-
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.common.QName;
 
@@ -63,6 +62,10 @@ public abstract class SchemaPath implements Immutable {
         }
     }
 
+    @SuppressWarnings("rawtypes")
+    private static final AtomicReferenceFieldUpdater<SchemaPath, ImmutableList> LEGACYPATH_UPDATER =
+            AtomicReferenceFieldUpdater.newUpdater(SchemaPath.class, ImmutableList.class, "legacyPath");
+
     /**
      * Shared instance of the conceptual root schema node.
      */
@@ -97,13 +100,8 @@ public abstract class SchemaPath implements Immutable {
     private ImmutableList<QName> getLegacyPath() {
         ImmutableList<QName> ret = legacyPath;
         if (ret == null) {
-            synchronized (this) {
-                ret = legacyPath;
-                if (ret == null) {
-                    ret = ImmutableList.copyOf(getPathTowardsRoot()).reverse();
-                    legacyPath = ret;
-                }
-            }
+            ret = ImmutableList.copyOf(getPathTowardsRoot()).reverse();
+            LEGACYPATH_UPDATER.lazySet(this, ret);
         }
 
         return ret;