Implement compact serialization for a set of discrete resources

This is for ONOS-4281.

Change-Id: I08a9fc4fd334c499c7a09d2960145743a798094e
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 515f9fc..63c8f7d 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -31,6 +31,7 @@
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
 import org.onlab.util.Bandwidth;
+import org.onlab.util.ClosedOpenRange;
 import org.onlab.util.Frequency;
 import org.onlab.util.KryoNamespace;
 import org.onlab.util.Match;
@@ -191,12 +192,18 @@
 import org.onosproject.net.resource.ContinuousResource;
 import org.onosproject.net.resource.ContinuousResourceId;
 import org.onosproject.net.resource.DiscreteResource;
+import org.onosproject.net.resource.DiscreteResourceCodec;
 import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.DiscreteResourceSet;
+import org.onosproject.net.resource.DiscreteResourceSetSerializer;
+import org.onosproject.net.resource.MplsCodec;
+import org.onosproject.net.resource.NoOpCodec;
 import org.onosproject.net.resource.ResourceAllocation;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.DefaultPacketRequest;
 import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.resource.VlanCodec;
 import org.onosproject.security.Permission;
 import org.onosproject.store.Timestamp;
 import org.onosproject.store.primitives.MapUpdate;
@@ -521,7 +528,12 @@
                     org.onlab.packet.MplsLabel.class,
                     org.onlab.packet.MPLS.class
             )
-
+            .register(ClosedOpenRange.class)
+            .register(new DiscreteResourceSetSerializer(), DiscreteResourceSet.class)
+            .register(DiscreteResourceCodec.class)
+            .register(VlanCodec.class)
+            .register(MplsCodec.class)
+            .register(NoOpCodec.class)
             .build();
 
 
diff --git a/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java b/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
index b159422..883892c 100644
--- a/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
+++ b/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
@@ -24,6 +24,7 @@
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
 import org.onlab.util.Bandwidth;
 import org.onlab.util.Frequency;
@@ -62,6 +63,9 @@
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleBatchEntry;
 import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.resource.DiscreteResource;
+import org.onosproject.net.resource.DiscreteResourceSet;
+import org.onosproject.net.resource.MplsCodec;
 import org.onosproject.net.resource.ResourceAllocation;
 import org.onosproject.net.resource.Resources;
 import org.onosproject.net.provider.ProviderId;
@@ -80,11 +84,15 @@
 import org.onlab.packet.Ip6Prefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.util.KryoNamespace;
+import org.onosproject.net.resource.VlanCodec;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Collections;
 import java.time.Duration;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import static java.util.Arrays.asList;
 import static org.junit.Assert.*;
@@ -356,6 +364,38 @@
     }
 
     @Test
+    public void testVlanIdResourceSet() {
+        DiscreteResource port = Resources.discrete(DID1, P1).resource();
+
+        Set<DiscreteResource> vlans = IntStream.range(0, 4096)
+                .mapToObj(x -> VlanId.vlanId((short) x))
+                .map(x -> Resources.discrete(port.id(), x).resource())
+                .collect(Collectors.toSet());
+
+        DiscreteResourceSet sut = DiscreteResourceSet.of(vlans, new VlanCodec());
+        testSerializedEquals(sut);
+    }
+
+    @Test
+    public void testMplsLabelResourceSet() {
+        DiscreteResource port = Resources.discrete(DID1, P1).resource();
+
+        Set<DiscreteResource> labels = IntStream.range(0, 1024 * 1024)
+                .mapToObj(MplsLabel::mplsLabel)
+                .map(x -> Resources.discrete(port.id(), x).resource())
+                .collect(Collectors.toSet());
+
+        DiscreteResourceSet sut = DiscreteResourceSet.of(labels, new MplsCodec());
+        testSerializedEquals(sut);
+    }
+
+    @Test
+    public void testEmptyResourceSet() {
+        DiscreteResourceSet sut = DiscreteResourceSet.empty();
+        testSerializedEquals(sut);
+    }
+
+    @Test
     public void testResourceId() {
         testSerializedEquals(Resources.discrete(DID1, P1).id());
     }