How to store and retrieve multiple Boolean values using single integer value

There are situations when we need to store multiple Boolean values related to the properties of an object in our project. For example, I am going to create a project related to a client having multiple services to offer to the end user. To be more specific say we have a telecom operator having multiple services like SMS, Calling , Roaming, internet packs to be offered to their end user. Now for every customer record we need to store the information which services the user is having at any point of time. Here we are just covering the Boolean information like whether user is having SMS pack or not(instead of details of services) and similar information for other packs.

For storing and accessing the information for this case we can have different solutions(as everyone has their own logical mind working), but the solutions that I can think of are:
1. Having one Boolean type column in Database(DB) or variable in our code for each pack type. This is the most simple way of storing information that comes into my mind.

2. The other logic that I think is crating the String type column in DB having some fixed car for each pack like S for SMS, R for Roaming and so on and if user opts for say call and internet I will store “CI” where C is for calling pack and I will denote internet.

3. Storing the values in a integer (or Long depending on the number of services to be used) in a way to be able to identify each services value form clubbed flag value. This is the one I love the most.

For this you need to imagine the flags in binary format. For each service value there will be one bit defined, so for the 4 pack as in above example we need 4 bits and for every bit 1 will represent true/yes/on/service_availed and 0 will represent false/no/off/service_not_availed. So first we need to fix the positioning of bit for each service. I am taking least significant bit/LSB(uniary position or left most) for Calling pack, starting from right to left second bit for Internet pack, third for roaming pack and forth one for SMS pack(SRIC). If the user is having all the packs that in binary the flag value will be “1111” decimal value “15” i.e. all flags on, similarly if user is having SMS and internet only than flags value will be “1010” decimal value “10”. In this case only SMS & internet bits are on/1 and roaming and calling pack bits are 0.

Now lets try this with code example(Java ):9

package com.authorcode;
public class BitFlagExample {
	static int serviceFlag = 0;
	static final int CALLING_PACK = 1;// 0001 LSB
	static final int INTERNET_PACK = 2;// 0010
	static final int ROAMING_PACK = 4;// 0100
	static final int SMS_PACK = 8;// 1000 MSB
 
	public static void main(String[] args) {
		BitFlagExample customer = new BitFlagExample();
 
		//Adding SMS pack in customer service
		customer.activateService(SMS_PACK);
		//Adding Calling pack in customer service
		customer.activateService(CALLING_PACK);
		//printing service flag value
		System.out.println("Value of service flag: " + serviceFlag);
		//Checking & printing services from integer value
		customer.printSevicesOpted();
	}
 
	private void printSevicesOpted() {
		System.out.println("Packs opted by the customer:");
 
		//XXXX & 0001 will either return 0 or 1
		//0 when there is 0 in binary format of service flag at right most location 1 otherwise
		if ((serviceFlag & CALLING_PACK) > 0) {
			System.out.println("Calling Pack");
		}
		//XXXX & 0010 will either return 0 or 2
		//0 when there is 0 in binary format of service flag at second location (from right to left) 2 otherwise
		if ((serviceFlag & INTERNET_PACK) > 0) {
			System.out.println("Internet Pack");
		}
		//XXXX & 0100 will either return 0 or 4
		//0 when there is 0 in binary format of service flag at third location (from right to left) 4 otherwise
		if ((serviceFlag & ROAMING_PACK) > 0) {
			System.out.println("Roaming Pack");
		}
		//XXXX & 1000 will either return 0 or 8
		//0 when there is 0 in binary format of service flag at forth location (from right to left) 8 otherwise
		if ((serviceFlag & SMS_PACK) > 0) {
			System.out.println("SMS Pack");
		}
	}
 
	void activateService(int service) {
		serviceFlag = serviceFlag + service;
	}
}


************************** Code Output **************************
Value of service flag: 9
Packs opted by the customer:
Calling Pack
SMS Pack
*****************************************************************

The advantage for having each one of these is different, but the decision of choise is of course your own.

In the firset case its easy to sotre and read the values but the problem with this approach is that “what if we need to add one or more such services ?”
For adding another service we need to add another column in db and the coupling that will also affect the object structure in our code. That means while adding each service we need to handle that in our code too which will not be easy to do.

In the second case we would not require to cahnge the table in our db untill the size of string (varchar) is less than the number of service. This will also not affect the object structure of the code storing this value. But here each char in DB is going to take a new byte and the same will take the space in object data in code. One more thing the comparison check here will be string comparison. eg if the customer service flag is “CI” and we need to query if customer is having sms pack or not. For this we will do something like this in java

if(serviceFlat.contains("S"))
	system.out.println("User has SMS pack.")

Even in DB for fetching the list of customers having SMS pack will be like:

select * from tbl_customer where service_flag like '%S%';

Both of the above transactions are heavier in term of CPU usage both in DB and application wise as compare to third one where we will be using binary operations.

The only disadvantage of the third one that I can think of is non readability. By looking at the value it will not be easily trackable which information it contains eg in first by looking at the boolean values you can say which service is active for the customer, similarly in second case if the flag value of user is “SI” still you can easily say only sms and internet pack are active for user. But in third case if user service flag is say 5 you cant say which service is active(unless you are used to of it).