blob: 3bb9bfa0a8ee1659a07536fc70e2a884b697e4e4 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001package net.floodlightcontroller.devicemanager.internal;
2
3import java.util.EnumSet;
4
5import org.slf4j.Logger;
6import org.slf4j.LoggerFactory;
7
8import net.floodlightcontroller.devicemanager.IDeviceService;
9import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
10
11
12/**
13 * This is a thin wrapper around {@link Entity} that allows overriding
14 * the behavior of {@link Object#hashCode()} and {@link Object#equals(Object)}
15 * so that the keying behavior in a hash map can be changed dynamically
16 * @author readams
17 */
18public class IndexedEntity {
19 protected EnumSet<DeviceField> keyFields;
20 protected Entity entity;
21 private int hashCode = 0;
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070022 protected final static Logger logger =
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080023 LoggerFactory.getLogger(IndexedEntity.class);
24 /**
25 * Create a new {@link IndexedEntity} for the given {@link Entity} using
26 * the provided key fields.
27 * @param keyFields The key fields that will be used for computing
28 * {@link IndexedEntity#hashCode()} and {@link IndexedEntity#equals(Object)}
29 * @param entity the entity to wrap
30 */
31 public IndexedEntity(EnumSet<DeviceField> keyFields, Entity entity) {
32 super();
33 this.keyFields = keyFields;
34 this.entity = entity;
35 }
36
37 /**
38 * Check whether this entity has non-null values in any of its key fields
39 * @return true if any key fields have a non-null value
40 */
41 public boolean hasNonNullKeys() {
42 for (DeviceField f : keyFields) {
43 switch (f) {
44 case MAC:
45 return true;
46 case IPV4:
47 if (entity.ipv4Address != null) return true;
48 break;
49 case SWITCH:
50 if (entity.switchDPID != null) return true;
51 break;
52 case PORT:
53 if (entity.switchPort != null) return true;
54 break;
55 case VLAN:
56 if (entity.vlan != null) return true;
57 break;
58 }
59 }
60 return false;
61 }
62
63 @Override
64 public int hashCode() {
65
66 if (hashCode != 0) {
67 return hashCode;
68 }
69
70 final int prime = 31;
71 hashCode = 1;
72 for (DeviceField f : keyFields) {
73 switch (f) {
74 case MAC:
75 hashCode = prime * hashCode
76 + (int) (entity.macAddress ^
77 (entity.macAddress >>> 32));
78 break;
79 case IPV4:
80 hashCode = prime * hashCode
81 + ((entity.ipv4Address == null)
82 ? 0
83 : entity.ipv4Address.hashCode());
84 break;
85 case SWITCH:
86 hashCode = prime * hashCode
87 + ((entity.switchDPID == null)
88 ? 0
89 : entity.switchDPID.hashCode());
90 break;
91 case PORT:
92 hashCode = prime * hashCode
93 + ((entity.switchPort == null)
94 ? 0
95 : entity.switchPort.hashCode());
96 break;
97 case VLAN:
98 hashCode = prime * hashCode
99 + ((entity.vlan == null)
100 ? 0
101 : entity.vlan.hashCode());
102 break;
103 }
104 }
105 return hashCode;
106 }
107
108 @Override
109 public boolean equals(Object obj) {
110 if (this == obj) return true;
111 if (obj == null) return false;
112 if (getClass() != obj.getClass()) return false;
113 IndexedEntity other = (IndexedEntity) obj;
114
115 if (!keyFields.equals(other.keyFields))
116 return false;
117
118 for (IDeviceService.DeviceField f : keyFields) {
119 switch (f) {
120 case MAC:
121 if (entity.macAddress != other.entity.macAddress)
122 return false;
123 break;
124 case IPV4:
125 if (entity.ipv4Address == null) {
126 if (other.entity.ipv4Address != null) return false;
127 } else if (!entity.ipv4Address.
128 equals(other.entity.ipv4Address)) return false;
129 break;
130 case SWITCH:
131 if (entity.switchDPID == null) {
132 if (other.entity.switchDPID != null) return false;
133 } else if (!entity.switchDPID.
134 equals(other.entity.switchDPID)) return false;
135 break;
136 case PORT:
137 if (entity.switchPort == null) {
138 if (other.entity.switchPort != null) return false;
139 } else if (!entity.switchPort.
140 equals(other.entity.switchPort)) return false;
141 break;
142 case VLAN:
143 if (entity.vlan == null) {
144 if (other.entity.vlan != null) return false;
145 } else if (!entity.vlan.
146 equals(other.entity.vlan)) return false;
147 break;
148 }
149 }
150
151 return true;
152 }
153
154
155}