'
Code:
'================================ ' Program to keep track of millions of "bit flags" ' - Set and Clear flags ' - Locate first available flag - about 1 million Tix to search through 10 million flags ' - increase/decrease total number of flags ' Stuart McLachlan, 2020 ' Released to the Public Domain. '================================= #COMPILE EXE 'Works with PBWin8-10 / PBCC4-6. #DIM ALL FUNCTION PBMAIN () AS LONG LOCAL sFlags AS STRING 'String storing the bit flags LOCAL pFlags AS QUAD PTR 'Pointer to block of 64 flags LOCAL FlagNo,x AS LONG LOCAL Flagcount,FlagsToAdd AS LONG 'Initialise everything Flagcount = 10000000 'will be rounded up to nearest multiple of 64 Flagcount = Flagcount + (63 - (Flagcount -1) MOD 64) sFlags = NUL$(Flagcount \ 8) pFlags = STRPTR(sFlags) DIM bFlags(1 TO LEN(sFlags)) AS BYTE AT pFlags GOSUB Demonstration EXIT FUNCTION '=========== Flag SUBS ================= GetFlag: FOR x = 0 TO (LEN(sFlags)\8)-1 IF @pFlags[x] <> &HFFFFFFFFFFFFFFFF THEN FlagNo = x * 64 + 65 - INSTR(-1,BIN$(@pFlags[x],64),"0") RETURN END IF NEXT FlagNo = 0 RETURN SetFlag: BIT SET bFlags(1),FlagNo-1 RETURN ClearFlag: BIT RESET bFlags(1),FlagNo-1 RETURN AddFlags: 'Add or remove Flags based on sign of FlagsToAdd ''FlagsToAdd is rounded away from 0 to a multiple of 64 bits 'Caution, that means that if FlagToAdd = -1, 8 bytes/64 Flags will be removed! SELECT CASE FlagsToAdd CASE > 0 FlagsToAdd =FlagsToAdd + 63 - (FlagsToAdd-1) MOD 64 sFlags = sFlags + STRING$(FlagsToAdd/8, CHR$(0)) CASE < 0 FlagsToAdd = FLagsToAdd - 63 - ABS(FlagsToAdd+1) MOD 64 sFlags = LEFT$(sFlags,FlagsToAdd/8) CASE ELSE '0 RETURN END SELECT pFlags = STRPTR(sFlags) REDIM bFlags(1 TO LEN(sFlags)) AT pFlags RETURN '========== DEMONSTRATION ============================ Demonstration: ? "Current number of Flags : " & STR$(LEN(sFlags) * 8) 'set most of the Flags to used FOR x = 1 TO Flagcount - 20 FlagNo = x GOSUB SetFlag NEXT 'Get first available Flag LOCAL q AS QUAD TIX Q GOSUB getFlag TIX END q ? "First Available Flag after setting all but last 20 " & STR$(FlagNo) & " took " & STR$(q) & " tix" 'Release a Flag FlagNo = 23 GOSUB clearFlag 'Get first avaiable Flag again GOSUB getFlag ? "First Available Flag after clearing 23: " & STR$(FlagNo) 'use all of the Flags FOR x = 1 TO LEN(sFlags)*8 FlagNo = x GOSUB SetFlag NEXT GOSUB getFlag ? "First available Flag after all set: " & STR$(FlagNo) 'add some Flags FlagsToAdd = 50 ' Number of additional Flags, will be rounded up to multiple of 64 GOSUB AddFlags ? "No of Flags after adding" & STR$(FlagsToAdd) & ": " & STR$(LEN(sFlags) * 8) GOSUB getFlag ? "First available Flag after adding: " & STR$(FlagNo) #IF %DEF(%PB_CC32) WAITKEY$ #ENDIF RETURN END FUNCTION '
Comment