The premise
One day, I opened the SOFA – Bolt project by chance, searched part of the source code, and saw the feature of realizing the function switch by using bit array in the project. I felt that this method could be used for reference, so I wrote this article.
The principle of
The layout of the bit array looks like this:
Since each bit can represent either a 1 or a 0, it corresponds to the ON and OFF of the switch. Just define the bit array subscript of each switch and the state of the switch (ON = 1 or OFF = 0), and judge the state of the switch by judging the bit subscript of different switches:
- Advantages: Saves space, theoretically takes up the most
2n
Bit memory (n
Is the number of switches, here consider expansion, expansion letbit
The array length is the same as before2
Times) - Cons: Not found yet
implementation
Bit arrays in the JDK can use bitsets directly. First define the switch definition SwitchDef:
public class SwitchConst {
public static final boolean ON = true;
public static final boolean OFF = false;
}
@RequiredArgsConstructor
@Getter
public enum SwitchDef {
/** * enable HTTPS */
ENABLE_HTTPS(0, SwitchConst.ON, "Enable HTTPS"),
/** * Enable asynchronous */
ENABLE_ASYNC(1, SwitchConst.OFF, "Enable asynchrony"),;/** ** subscript */
private final int index;
/**
* 默认状态
*/
private final boolean defaultStatus;
/** * description */
private final String description;
@Override
public String toString(a) {
return String.format("SwitchDef(name=%s,description=%s)", name(), description); }}Copy the code
Then define the Switch interface Switch:
public interface Switch {
/** * Enable **@param switchDef switchDef
*/
void turnOn(SwitchDef switchDef);
/** * close **@param switchDef switchDef
*/
void turnOff(SwitchDef switchDef);
/** * Check the status **@param switchDef switchDef
* @return boolean
*/
boolean status(SwitchDef switchDef);
}
Copy the code
Finally write the switch to achieve BitSetSwitch and client code:
public enum BitSetSwitch implements Switch {
/** * singleton */
X;
BitSetSwitch() {
init();
}
private final BitSet switches = new BitSet();
@Override
public void turnOn(SwitchDef switchDef) {
switches.set(switchDef.getIndex(), SwitchConst.ON);
}
@Override
public void turnOff(SwitchDef switchDef) {
switches.clear(switchDef.getIndex());
}
@Override
public boolean status(SwitchDef switchDef) {
return switches.get(switchDef.getIndex());
}
private void init(a) {
Stream.of(SwitchDef.values()).forEach(item -> switches.set(item.getIndex(), item.isDefaultStatus()));
}
public static void main(String[] args) {
Switch s = BitSetSwitch.X;
s.turnOn(SwitchDef.ENABLE_HTTPS);
s.turnOff(SwitchDef.ENABLE_ASYNC);
System.out.printf("Switch [%s], status :%s%n", SwitchDef.ENABLE_HTTPS, s.status(SwitchDef.ENABLE_HTTPS));
System.out.printf("Switch [%s], status :%s%n", SwitchDef.ENABLE_ASYNC, s.status(SwitchDef.ENABLE_ASYNC)); }}Copy the code
The console output after executing the main method is as follows:
Switch [SwitchDef(name=ENABLE_HTTPS,description= HTTPS enabled)], status: True Switch [SwitchDef(name=ENABLE_ASYNC, Description = Async enabled)], status: FalseCopy the code
Simulation scenarios (pseudocodes) are as follows:
Switch s = BitSetSwitch.X;
String uri = "www.throwx.cn";
String schema = "http";
if (s.turnOn(SwitchDef.ENABLE_HTTPS)){
schema = "https";
}
HttpClint ch = new DefaultHttpClient();
if (s.turnOn(SwitchDef.ENABLE_ASYNC)){
ch = newAsyncHttpClient(); } Result r = ch.executeRequest(schema + uri); .Copy the code
summary
When reading some mainstream framework source code, you can draw lessons from some reasonable design programs to apply to their daily development.
References:
- Sofa – bolt the source code