Sho SHIMIZU
Committed by Gerrit Code Review

Implement a class representing frequency

This resolves ONOS-1769

Change-Id: Ia4d0da59aec79bafdf7686dfad1f1952f94cefc7
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.util;
17 +
18 +import com.google.common.base.MoreObjects;
19 +
20 +import java.util.Objects;
21 +
22 +/**
23 + * Class representing frequency. This class is intended to be used for a value whose unit is Hz
24 + * and its family (KHz, MHz, etc.).
25 + *
26 + * <p>
27 + * Note: this class is mainly intended to be used for lambda, which
28 + * represents THz order. Long has enough space to represent over THz frequency as Hz,
29 + * and the underlying value is long as Hz. This means this class can't represent
30 + * sub-Hz accuracy.
31 + * </p>
32 + */
33 +public final class Frequency {
34 +
35 + private static final long KHZ = 1_000L;
36 + private static final long MHZ = 1_000_000L;
37 + private static final long GHZ = 1_000_000_000L;
38 + private static final long THZ = 1_000_000_000_000L;
39 +
40 + private final long frequency; // frequency in Hz
41 +
42 + /**
43 + * Creates an instance representing the specified frequency in Hz.
44 + *
45 + * @param frequency frequency in Hz
46 + */
47 + private Frequency(long frequency) {
48 + this.frequency = frequency;
49 + }
50 +
51 + /**
52 + * Return the value this instance represents as Hz.
53 + *
54 + * @return frequency in Hz
55 + */
56 + public long asHz() {
57 + return frequency;
58 + }
59 +
60 + /**
61 + * Returns an instance representing the specified value in Hz.
62 + *
63 + * @param value frequency in Hz
64 + * @return instance representing the given frequency
65 + */
66 + public static Frequency ofHz(long value) {
67 + return new Frequency(value);
68 + }
69 +
70 + /**
71 + * Returns an instance representing the specified value in KHz.
72 + *
73 + * @param value frequency in KHz
74 + * @return instance representing the given frequency
75 + */
76 + public static Frequency ofKHz(double value) {
77 + return new Frequency((long) (value * KHZ));
78 + }
79 +
80 + /**
81 + * Returns an instance representing the specified value in MHz.
82 + *
83 + * @param value frequency in MHz
84 + * @return instance representing the given frequency
85 + */
86 + public static Frequency ofMHz(double value) {
87 + return new Frequency((long) (value * MHZ));
88 + }
89 +
90 + /**
91 + * Returns an instance representing the specified value in GHz.
92 + *
93 + * @param value frequency in GHz
94 + * @return instance representing the given frequency
95 + */
96 + public static Frequency ofGHz(double value) {
97 + return new Frequency((long) (value * GHZ));
98 + }
99 +
100 + /**
101 + * Returns an instance representing the specified value in THz.
102 + *
103 + * @param value frequency in THz
104 + * @return instance representing the given frequency
105 + */
106 + public static Frequency ofTHz(double value) {
107 + return new Frequency((long) (value * THZ));
108 + }
109 +
110 + /**
111 + * Returns a Frequency whose value is (this + value).
112 + *
113 + * @param value value to be added to this Frequency
114 + * @return this + value
115 + */
116 + public Frequency add(Frequency value) {
117 + return new Frequency(this.frequency + value.frequency);
118 + }
119 +
120 + /**
121 + * Returns a Frequency whose value is (this - value).
122 + *
123 + * @param value value to be subtracted from this Frequency
124 + * @return this - value
125 + */
126 + public Frequency subtract(Frequency value) {
127 + return new Frequency(this.frequency - value.frequency);
128 + }
129 +
130 + /**
131 + * Returns a Frequency whose value is (this * value).
132 + *
133 + * @param value value to be multiplied by this Frequency
134 + * @return this * value
135 + */
136 + public Frequency multiply(long value) {
137 + return new Frequency(this.frequency * value);
138 + }
139 +
140 + @Override
141 + public int hashCode() {
142 + return Objects.hash(frequency);
143 + }
144 +
145 + @Override
146 + public boolean equals(Object obj) {
147 + if (this == obj) {
148 + return true;
149 + }
150 +
151 + if (!(obj instanceof Frequency)) {
152 + return false;
153 + }
154 +
155 + final Frequency other = (Frequency) obj;
156 + return this.frequency == other.frequency;
157 + }
158 +
159 + @Override
160 + public String toString() {
161 + return MoreObjects.toStringHelper(this)
162 + .add("frequency", frequency + "Hz")
163 + .toString();
164 + }
165 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.util;
17 +
18 +import com.google.common.testing.EqualsTester;
19 +import org.junit.Test;
20 +import org.onlab.junit.ImmutableClassChecker;
21 +
22 +import static org.hamcrest.MatcherAssert.assertThat;
23 +import static org.hamcrest.Matchers.is;
24 +
25 +public class FrequencyTest {
26 +
27 + private final Frequency frequency1 = Frequency.ofMHz(1000);
28 + private final Frequency sameFrequency1 = Frequency.ofMHz(1000);
29 + private final Frequency frequency2 = Frequency.ofGHz(1000);
30 + private final Frequency sameFrequency2 = Frequency.ofGHz(1000);
31 + private final Frequency moreSameFrequency2 = Frequency.ofTHz(1);
32 + private final Frequency frequency3 = Frequency.ofTHz(193.1);
33 + private final Frequency sameFrequency3 = Frequency.ofGHz(193100);
34 +
35 + /**
36 + * Tests immutability of Frequency.
37 + */
38 + @Test
39 + public void testImmutability() {
40 + ImmutableClassChecker.assertThatClassIsImmutable(Frequency.class);
41 + }
42 +
43 + /**
44 + * Tests equality of Frequency instances.
45 + */
46 + @Test
47 + public void testEquality() {
48 + new EqualsTester()
49 + .addEqualityGroup(frequency1, sameFrequency1)
50 + .addEqualityGroup(frequency2, sameFrequency2, moreSameFrequency2)
51 + .addEqualityGroup(frequency3, sameFrequency3)
52 + .testEquals();
53 + }
54 +
55 + /**
56 + * Tests add operation of two Frequencies.
57 + */
58 + @Test
59 + public void testAdd() {
60 + Frequency low = Frequency.ofMHz(100);
61 + Frequency high = Frequency.ofGHz(1);
62 + Frequency expected = Frequency.ofMHz(1100);
63 +
64 + assertThat(low.add(high), is(expected));
65 + }
66 +
67 + /**
68 + * Tests subtract operation of two Frequencies.
69 + */
70 + @Test
71 + public void testSubtract() {
72 + Frequency high = Frequency.ofGHz(1);
73 + Frequency low = Frequency.ofMHz(100);
74 + Frequency expected = Frequency.ofMHz(900);
75 +
76 + assertThat(high.subtract(low), is(expected));
77 + }
78 +
79 + /**
80 + * Tests multiply operation of Frequency.
81 + */
82 + @Test
83 + public void testMultiply() {
84 + Frequency frequency = Frequency.ofMHz(1000);
85 + long factor = 5;
86 + Frequency expected = Frequency.ofGHz(5);
87 +
88 + assertThat(frequency.multiply(5), is(expected));
89 + }
90 +}