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;
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);
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;
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);
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;
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);
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;
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) {
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;
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) {
}
- 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);
}
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);
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;
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);
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;
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;
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;
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);
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());
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());
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;
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());
}
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());
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;
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);
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);
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;
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);
import static org.junit.Assert.fail;
import com.google.common.io.ByteSource;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
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;
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);
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());
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");
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;
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;
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)) {
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;
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);
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);
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);
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);
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);
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);
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;
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;
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;
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);
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;
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());
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;
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;
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;
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;
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;
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;
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;
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;
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;
<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>
<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>
<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>
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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 "";
+ }
+}
* 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 "";
- }
}
}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+ }
+}
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;
private final Date revision;
//Nullable
- private String formattedRevision;
+ private volatile String formattedRevision;
private QNameModule(final URI namespace, final Date revision) {
this.namespace = namespace;
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;
}
/**
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;
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;
* @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;
// 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;
}
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;
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;
*/
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;
}
--- /dev/null
+/*
+ * 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();
+ }
+}
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;
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());
}
@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);
}
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;
}
/**
- * 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
* @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
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.
*
}
return parent;
}
+
}
@Override
protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
- writeJsonIdentifier(schema, writer, getQName());
+ writeMyJsonIdentifier(schema, writer, getQName());
writer.append('[');
}
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;
@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
+}
*/
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;
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);
}
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);
}
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);
}
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;
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);
}
}
}
+ @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;
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());
*/
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;
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();
}
}
@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()) {
}
@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,
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();
}
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();
}
}
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);
}
}
@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
}
@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);
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;
}
}
+ @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.
*/
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;