blob: af76aee7120f6d2e814a79cdb63be88c05b5271b [file] [log] [blame]
Andreas Wundsam7c15b172014-04-24 19:02:40 -07001package org.projectfloodlight.openflow.types;
2
3import org.jboss.netty.buffer.ChannelBuffer;
4
Andreas Wundsam7c15b172014-04-24 19:02:40 -07005import com.google.common.hash.PrimitiveSink;
6
7public class U128 implements OFValueType<U128>, HashValue<U128> {
8
9 static final int LENGTH = 16;
10
11 private final long raw1; // MSBs
12 private final long raw2; // LSBs
13
14 public static final U128 ZERO = new U128(0, 0);
15
16 private U128(long raw1, long raw2) {
17 this.raw1 = raw1;
18 this.raw2 = raw2;
19 }
20
21 public static U128 of(long raw1, long raw2) {
22 if (raw1 == 0 && raw2 == 0)
23 return ZERO;
24 return new U128(raw1, raw2);
25 }
26
27 @Override
28 public int getLength() {
29 return LENGTH;
30 }
31
32
33 public long getMsb() {
34 return raw1;
35 }
36
37 public long getLsb() {
38 return raw2;
39 }
40
41 @Override
42 public U128 applyMask(U128 mask) {
43 return and(mask);
44 }
45
46 @Override
47 public int hashCode() {
48 final int prime = 31;
49 int result = 1;
50 result = prime * result + (int) (raw1 ^ (raw1 >>> 32));
51 result = prime * result + (int) (raw2 ^ (raw2 >>> 32));
52 return result;
53 }
54
55 @Override
56 public boolean equals(Object obj) {
57 if (this == obj)
58 return true;
59 if (obj == null)
60 return false;
61 if (getClass() != obj.getClass())
62 return false;
63 U128 other = (U128) obj;
64 if (raw1 != other.raw1)
65 return false;
66 if (raw2 != other.raw2)
67 return false;
68 return true;
69 }
70
71 public void write16Bytes(ChannelBuffer cb) {
72 cb.writeLong(raw1);
73 cb.writeLong(raw2);
74 }
75
76 public static U128 read16Bytes(ChannelBuffer cb) {
77 long raw1 = cb.readLong();
78 long raw2 = cb.readLong();
79 return of(raw1, raw2);
80 }
81
82 @Override
83 public String toString() {
84 return String.format("0x%016x%016x", raw1, raw2);
85 }
86
87 @Override
88 public int compareTo(U128 o) {
89 long c = this.raw1 - o.raw1;
90 if (c != 0)
91 return Long.signum(c);
92 return Long.signum(this.raw2 - o.raw2);
93 }
94
95 @Override
96 public void putTo(PrimitiveSink sink) {
97 sink.putLong(raw1);
98 sink.putLong(raw2);
99 }
100
101 @Override
102 public U128 inverse() {
103 return U128.of(~raw1, ~raw2);
104 }
105
106 @Override
107 public U128 or(U128 other) {
108 return U128.of(raw1 | other.raw1, raw2 | other.raw2);
109 }
110
111 @Override
112 public U128 and(U128 other) {
113 return U128.of(raw1 & other.raw1, raw2 & other.raw2);
114 }
115
116 @Override
117 public U128 xor(U128 other) {
118 return U128.of(raw1 ^ other.raw1, raw2 ^ other.raw2);
119 }
120
121 @Override
122 public int prefixBits(int numBits) {
Andreas Wundsamc5e98702014-05-05 13:12:19 -0700123 return HashValueUtils.prefixBits(this.raw1, numBits);
Andreas Wundsam7c15b172014-04-24 19:02:40 -0700124 }
125
126 @Override
127 public U128 combineWithValue(U128 value, int keyBits) {
128 return U128.of(
129 HashValueUtils.combineWithValue(this.raw1, value.raw1, Math.min(64, keyBits)),
130 HashValueUtils.combineWithValue(this.raw2, value.raw2, Math.max(0,keyBits-64))
131 );
132 }
133}