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 most2nBit memory (nIs the number of switches, here consider expansion, expansion letbitThe array length is the same as before2Times)
  • 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