diff --git a/libraries/BoolArray/.github/FUNDING.yml b/libraries/BoolArray/.github/FUNDING.yml index 90d9ab4c..554358c3 100644 --- a/libraries/BoolArray/.github/FUNDING.yml +++ b/libraries/BoolArray/.github/FUNDING.yml @@ -1,4 +1,4 @@ # These are supported funding model platforms github: RobTillaart - +custom: "https://www.paypal.me/robtillaart" diff --git a/libraries/BoolArray/.github/workflows/arduino-lint.yml b/libraries/BoolArray/.github/workflows/arduino-lint.yml index 8a26f14a..7f8f4ef4 100644 --- a/libraries/BoolArray/.github/workflows/arduino-lint.yml +++ b/libraries/BoolArray/.github/workflows/arduino-lint.yml @@ -1,13 +1,13 @@ - name: Arduino-lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: arduino/arduino-lint-action@v1 with: library-manager: update - compliance: strict + compliance: strict \ No newline at end of file diff --git a/libraries/BoolArray/.github/workflows/arduino_test_runner.yml b/libraries/BoolArray/.github/workflows/arduino_test_runner.yml index fadfa904..dbd0ce79 100644 --- a/libraries/BoolArray/.github/workflows/arduino_test_runner.yml +++ b/libraries/BoolArray/.github/workflows/arduino_test_runner.yml @@ -1,4 +1,3 @@ ---- name: Arduino CI on: [push, pull_request] @@ -6,9 +5,10 @@ on: [push, pull_request] jobs: runTest: runs-on: ubuntu-latest + timeout-minutes: 20 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: 2.6 diff --git a/libraries/BoolArray/.github/workflows/jsoncheck.yml b/libraries/BoolArray/.github/workflows/jsoncheck.yml index 37a11298..1cbb5e2c 100644 --- a/libraries/BoolArray/.github/workflows/jsoncheck.yml +++ b/libraries/BoolArray/.github/workflows/jsoncheck.yml @@ -9,10 +9,10 @@ on: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: json-syntax-check - uses: limitusus/json-syntax-check@v1 + uses: limitusus/json-syntax-check@v2 with: - pattern: "\\.json$" - + pattern: "\\.json$" \ No newline at end of file diff --git a/libraries/BoolArray/BoolArray.cpp b/libraries/BoolArray/BoolArray.cpp index c73c01fc..c550ea83 100644 --- a/libraries/BoolArray/BoolArray.cpp +++ b/libraries/BoolArray/BoolArray.cpp @@ -1,7 +1,7 @@ // // FILE: BoolArray.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.2.8 +// VERSION: 0.3.0 // DATE: 2015-12-06 // PURPOSE: BoolArray library for Arduino // URL: https://github.com/RobTillaart/BoolArray @@ -11,6 +11,10 @@ #include "BoolArray.h" +///////////////////////////////////////////////////////// +// +// 16 bit version +// BoolArray::BoolArray() { _array = NULL; @@ -26,7 +30,11 @@ BoolArray::~BoolArray() uint8_t BoolArray::begin(const uint16_t size) { - if (size > BOOLARRAY_MAXSIZE) return BOOLARRAY_SIZE_ERROR; + // is this test needed.... + if (size > BOOLARRAY_MAXSIZE) + { + return BOOLARRAY_SIZE_ERROR; + } // do we need to re-allocate? if (_size != size) { @@ -37,6 +45,12 @@ uint8_t BoolArray::begin(const uint16_t size) free(_array); } _array = (uint8_t *) malloc(_bytes); + if (_array == NULL) + { + _size = 0; + _bytes = 0; + return BOOLARRAY_INIT_ERROR; + } } return BOOLARRAY_OK; } @@ -48,7 +62,7 @@ uint16_t BoolArray::size() } -uint8_t BoolArray::memory() +uint16_t BoolArray::memory() { return _bytes; } @@ -110,5 +124,140 @@ uint8_t BoolArray::toggle(const uint16_t index) } + +///////////////////////////////////////////////////////// +// +// 32 bit version for large bool arrays +// +BoolArray32::BoolArray32() +{ + _array = NULL; + _size = 0; +} + + +BoolArray32::~BoolArray32() +{ + if (_array) free(_array); +} + + +uint8_t BoolArray32::begin(const uint32_t size) +{ + if (size > BOOLARRAY_MAXSIZE) + { + return BOOLARRAY_SIZE_ERROR; + } + // do we need to re-allocate? + if (_size != size) + { + _size = size; + _bytes = (_size + 7) / 8; + if (_array) + { + free(_array); + } + _array = (uint8_t *) malloc(_bytes); + if (_array == NULL) + { + _size = 0; + _bytes = 0; + return BOOLARRAY_INIT_ERROR; + } + } + return BOOLARRAY_OK; +} + + +uint32_t BoolArray32::size() +{ + return _size; +} + + +uint32_t BoolArray32::memory() +{ + return _bytes; +} + + +uint8_t BoolArray32::setAll(const uint8_t value) +{ + if (_array == NULL) + { + return BOOLARRAY_INIT_ERROR; + } + uint8_t *p = _array; + uint32_t t = _bytes; + if (value == 0) + { + while (t--) *p++ = 0; + } + else + { + while (t--) *p++ = 0xFF; + } + return BOOLARRAY_OK; +} + + +uint8_t BoolArray32::clear() +{ + return setAll(0); +} + + +uint8_t BoolArray32::get(const uint32_t index) +{ + if (_array == NULL) + { + return BOOLARRAY_INIT_ERROR; + } + if (index >= _size) + { + return BOOLARRAY_SIZE_ERROR; + } + uint32_t by = index / 8; + uint8_t bi = index & 7; + return (_array[by] & _masks[bi]) > 0; +} + + +uint8_t BoolArray32::set(const uint32_t index, const uint8_t value) +{ + if (_array == NULL) + { + return BOOLARRAY_INIT_ERROR; + } + if (index >= _size) + { + return BOOLARRAY_SIZE_ERROR; + } + uint32_t by = index / 8; + uint8_t bi = index & 7; + if (value == 0) _array[by] &= ~_masks[bi]; + else _array[by] |= _masks[bi]; + return BOOLARRAY_OK; +} + + +uint8_t BoolArray32::toggle(const uint32_t index) +{ + if (_array == NULL) + { + return BOOLARRAY_INIT_ERROR; + } + if (index >= _size) + { + return BOOLARRAY_SIZE_ERROR; + } + uint32_t by = index / 8; + uint8_t bi = index & 7; + _array[by] ^= _masks[bi]; + return BOOLARRAY_OK; +} + + + // -- END OF FILE -- diff --git a/libraries/BoolArray/BoolArray.h b/libraries/BoolArray/BoolArray.h index 4bbb8c49..c362ddd1 100644 --- a/libraries/BoolArray/BoolArray.h +++ b/libraries/BoolArray/BoolArray.h @@ -2,7 +2,7 @@ // // FILE: BoolArray.h // AUTHOR: Rob Tillaart -// VERSION: 0.2.8 +// VERSION: 0.3.0 // DATE: 2015-12-06 // PURPOSE: BoolArray library for Arduino // URL: https://github.com/RobTillaart/BoolArray.git @@ -15,9 +15,11 @@ #include "Arduino.h" -#define BOOLARRAY_LIB_VERSION (F("0.2.8")) +#define BOOLARRAY_LIB_VERSION (F("0.3.0")) -#define BOOLARRAY_MAXSIZE (250 * 8) // 2000 +#ifndef BOOLARRAY_MAXSIZE +#define BOOLARRAY_MAXSIZE (1250 * 8) // 8000 +#endif #define BOOLARRAY_OK 0x00 #define BOOLARRAY_ERROR 0xFF @@ -25,6 +27,10 @@ #define BOOLARRAY_INIT_ERROR 0xFD +///////////////////////////////////////////////////////// +// +// 16 bit version +// class BoolArray { public: @@ -34,7 +40,7 @@ public: uint8_t begin(const uint16_t size); uint16_t size(); - uint8_t memory(); + uint16_t memory(); uint8_t setAll(const uint8_t value); uint8_t clear(); @@ -46,7 +52,37 @@ private: uint8_t _masks[8] = {1, 2, 4, 8, 16, 32, 64, 128}; uint8_t * _array; uint16_t _size = 0; - uint8_t _bytes = 0; + uint16_t _bytes = 0; +}; + + +///////////////////////////////////////////////////////// +// +// 32 bit version for large bool arrays +// separate class as it is slower +// +class BoolArray32 +{ +public: + BoolArray32(); + ~BoolArray32(); + + uint8_t begin(const uint32_t size); + + uint32_t size(); + uint32_t memory(); + + uint8_t setAll(const uint8_t value); + uint8_t clear(); + uint8_t get(const uint32_t index); + uint8_t set(const uint32_t index, const uint8_t value); + uint8_t toggle(const uint32_t index); + +private: + uint8_t _masks[8] = {1, 2, 4, 8, 16, 32, 64, 128}; + uint8_t * _array; + uint32_t _size = 0; + uint32_t _bytes = 0; }; diff --git a/libraries/BoolArray/CHANGELOG.md b/libraries/BoolArray/CHANGELOG.md index 201dbdd1..7c21c699 100644 --- a/libraries/BoolArray/CHANGELOG.md +++ b/libraries/BoolArray/CHANGELOG.md @@ -6,11 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.3.0] - 2024-04-10 +- made BOOLARRAY_MAXSIZE a -D command line define option +- increased default BOOLARRAY_MAXSIZE to 1250 x 8 = 10000 booleans + - about Arduino UNO max size +- add BoolArray32 class for larger arrays. +- update GitHub actions + +---- + ## [0.2.8] - 2023-02-08 - update readme.md - optimize begin - test for need to reallocate. - ## [0.2.7] - 2023-02-08 - update readme.md - update GitHub actions diff --git a/libraries/BoolArray/LICENSE b/libraries/BoolArray/LICENSE index 18c804e7..3b61d73d 100644 --- a/libraries/BoolArray/LICENSE +++ b/libraries/BoolArray/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2015-2023 Rob Tillaart +Copyright (c) 2015-2024 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libraries/BoolArray/README.md b/libraries/BoolArray/README.md index 8ccd34b4..bac22839 100644 --- a/libraries/BoolArray/README.md +++ b/libraries/BoolArray/README.md @@ -26,11 +26,29 @@ You need to check if your application needs more performance than this library c #### Notes The BoolArray class allocates dynamic memory. -The **BOOLARRAY_MAXSIZE** is set to 2000, this was chosen as **malloc()** can only allocate 255 bytes -in one call on an UNO. This is not checked with the recent versions of the IDE any more. +The **BOOLARRAY_MAXSIZE** is set to 10000 (booleans). +This number is chosen as it is about the maximum one can allocate in one call on an UNO. + +If one want to allocate more booleans, adjust the **BOOLARRAY_MAXSIZE**. +This can be done as a command line option. The library is tested on AVR architecture only. + +#### BoolArray32 + +Since 0.3.0 a **BoolArray32** class is added - **experimental** for now. + +Where the **BoolArray** class can have max 65535 booleans, the **BoolArray32** class +has a 32 bit interface allowing up to 4 billion++ booleans in theory. +Although most IOT devices would not have enough memory, it allows one to have more than +65535 booleans. + +Also it might be that the **BoolArray32** class is faster on some platforms +that are native 32 bit (not verified yet). +On an Arduino UNO the **BoolArray32** class is slower.(verified). + + #### Related The BitArray library is one from a set of three: @@ -44,6 +62,30 @@ BoolArray is faster than BitArray as it only supports single bits and does not n of different bytes to read/write a value. However BoolArray currently only supports 2000 bits while BitArray can support more. +## Performance + +See **boolArrayDemo0.ino** + +Indicative performance figures. + +| class | function | UNO | ESP32 | Notes | +|:--------------|:-----------:|:-------:|:--------:|:--------:| +| BoolArray | set(0) | 10.37 | | +| BoolArray | set(1) | 10.25 | | +| BoolArray | get(i) | 16.03 | | +| BoolArray | setAll(0) | 96 | | per 2000 +| BoolArray | setAll(1) | 100 | | per 2000 +| | | | | +| BoolArray32 | set(0) | 15.97 | | +| BoolArray32 | set(1) | 15.84 | | +| BoolArray32 | get(i) | 24.20 | | +| BoolArray32 | setAll(0) | 148 | | per 2000 +| BoolArray32 | setAll(1) | 144 | | per 2000 + +- UNO 16 MHz, ESP32 240 MHz. +- toggle() is expected to be similar to set() +- clear() is a wrapper around setAll(0) so similar. + ## Interface @@ -55,22 +97,24 @@ BitArray can support more. - **BoolArray()** Constructor - **~BoolArray()** Destructor -- **uint8_t begin(uint16_t size)** dynamically allocates size elements (8 bools in one byte). +- **uint8_t begin(uint32_t size)** dynamically allocates size elements (8 booleans in one byte). Returns **BOOLARRAY_OK** on success. #### Meta -- **uint16_t size()** returns number of bool elements. +- **uint16_t size()** returns number of boolean elements. - **uint16_t memory()** returns number of bytes used. #### Base +The following functions return **BOOLARRAY_OK** on success. + - **uint8_t setAll(uint8_t value)** Sets all elements to false (0) or true (all other values). - **uint8_t clear()** Sets all elements to false. - **uint8_t get(uint16_t index)** Return 0 or 1 OR an error value which can be interpreted as true. So one need to check these carefully. - **uint8_t set(uint16_t index, uint8_t value)** Set the element to false (0) or true (all other values). -- **uint8_t toggle(uint16_t index)** Toggles element at index. Returns **BOOLARRAY_OK** on success. +- **uint8_t toggle(uint16_t index)** Toggles element at index. ## Future @@ -84,18 +128,19 @@ So one need to check these carefully. - performance test on ESP32 - performance for **clear()** dedicated loop vs **setAll(0)** call -- performance intern 16 bit iso 8 bit. (0.3.0) - - faster on UNO - - does allocation work as it should? +- investigate template class + - improve allocation (see PrintCharArray) #### Could - update examples. -- boolArray32() class - - begin(uint32_t size); +- investigate **uint32_t array[N]** for BoolArray32 (ESP32?) + - adjust math #### Wont +- performance intern 16 bit instead of 8 bit is NOT faster on UNO + ## Support diff --git a/libraries/BoolArray/examples/boolArrayDemo0/boolArrayDemo0.ino b/libraries/BoolArray/examples/boolArrayDemo0/boolArrayDemo0.ino index c7d1b581..37caeb27 100644 --- a/libraries/BoolArray/examples/boolArrayDemo0/boolArrayDemo0.ino +++ b/libraries/BoolArray/examples/boolArrayDemo0/boolArrayDemo0.ino @@ -2,7 +2,6 @@ // FILE: boolArrayDemo0.ino // AUTHOR: Rob Tillaart // PURPOSE: demo performance reading boolean array -// DATE: 2015-12-06 // URL: https://github.com/RobTillaart/BoolArray @@ -21,14 +20,17 @@ uint32_t duration1, duration2; void setup() { Serial.begin(115200); - Serial.print("Start "); Serial.println(__FILE__); - Serial.print("LIB VERSION:\t"); + Serial.print("BOOLARRAY_LIB_VERSION:\t"); Serial.println(BOOLARRAY_LIB_VERSION); - int rv = b.begin(BOOLARRAY_MAXSIZE); - Serial.print("SIZE:\t"); + int rv = b.begin(2000); + Serial.print("SIZE bits:\t"); Serial.println(b.size()); + Serial.print("MEM bytes:\t"); + Serial.println(b.memory()); + Serial.print("freeMemory:\t"); + Serial.println(freeMemory()); if (rv != BOOLARRAY_OK) { @@ -191,5 +193,33 @@ void test3() } -// -- END OF FILE -- +#ifdef AVR +extern unsigned int __bss_end; +extern unsigned int __heap_start; +extern void *__brkval; + +int freeMemory() +{ + int free_memory; + + if ((int)__brkval == 0) + free_memory = ((int)&free_memory) - ((int)&__bss_end); + else + free_memory = ((int)&free_memory) - ((int)__brkval); + + return free_memory; +}; + +#else + +int freeMemory() +{ + return 0; +}; + +#endif + + + +// -- END OF FILE -- diff --git a/libraries/BoolArray/examples/boolArrayDemo0/output_0.3.0.txt b/libraries/BoolArray/examples/boolArrayDemo0/output_0.3.0.txt new file mode 100644 index 00000000..4d58031b --- /dev/null +++ b/libraries/BoolArray/examples/boolArrayDemo0/output_0.3.0.txt @@ -0,0 +1,63 @@ +BOOLARRAY_LIB_VERSION: 0.3.0 +SIZE bits: 2000 +MEM bytes: 250 +freeMemory: 1250 + +TEST SET(1) +DURATION: 26412 +DURATION: 47156 + 20744 10.37 + +TEST SET(0) +DURATION: 26156 +DURATION: 46660 + 20504 10.25 + +TEST GET(i) +DURATION: 37728 +DURATION: 69792 + 32064 16.03 + +TEST SET(0): 26156 +TEST SETALL(0): 96 +FACTOR: 272.46 + +TEST SET(1): 26412 +TEST SETALL(1): 100 +FACTOR: 264.12 +Done... + + +///////////////////////////////////////// +// +// BoolArray32 == slower +// +BOOLARRAY_LIB_VERSION: 0.3.0 +SIZE bits: 2000 +MEM bytes: 250 +freeMemory: 1246 + +TEST SET(1) +DURATION: 40116 +DURATION: 72060 + 31944 15.97 + +TEST SET(0) +DURATION: 39864 +DURATION: 71548 + 31684 15.84 + +TEST GET(i) +DURATION: 56596 +DURATION: 105000 + 48404 24.20 + +TEST SET(0): 39864 +TEST SETALL(0): 148 +FACTOR: 269.35 + +TEST SET(1): 40116 +TEST SETALL(1): 144 +FACTOR: 278.58 +Done... + diff --git a/libraries/BoolArray/examples/boolArrayDemo2/boolArrayDemo2.ino b/libraries/BoolArray/examples/boolArrayDemo2/boolArrayDemo2.ino index 3168abf7..9e43cc93 100644 --- a/libraries/BoolArray/examples/boolArrayDemo2/boolArrayDemo2.ino +++ b/libraries/BoolArray/examples/boolArrayDemo2/boolArrayDemo2.ino @@ -2,7 +2,6 @@ // FILE: boolArrayDemo2.ino // AUTHOR: Rob Tillaart // PURPOSE: demo performance boolean array -// DATE: 2015-12-12 // URL: https://github.com/RobTillaart/BoolArray @@ -19,7 +18,6 @@ volatile long x = 0; void setup() { Serial.begin(115200); - Serial.print("Start "); Serial.println(__FILE__); Serial.print("BOOLARRAY_LIB_VERSION:\t"); Serial.println(BOOLARRAY_LIB_VERSION); diff --git a/libraries/BoolArray/examples/boolArrayDemo2/performance_0.3.0.txt b/libraries/BoolArray/examples/boolArrayDemo2/performance_0.3.0.txt new file mode 100644 index 00000000..cc4c54c0 --- /dev/null +++ b/libraries/BoolArray/examples/boolArrayDemo2/performance_0.3.0.txt @@ -0,0 +1,59 @@ + +/////////////////////////////////////////////// +// +// BOOLARRAY +// +BOOLARRAY_LIB_VERSION: 0.2.7 +Bool array size: 1000 + +get +DURATION: 5160 +DURATION: 9876 + X: 0 + +set +DURATION: 3968 +DURATION: 7488 + +clear +DURATION: 48164 +DURATION: 96076 + +setAll +DURATION: 48164 +DURATION: 96076 + +toggle +DURATION: 3840 +DURATION: 7232 +Done... + + +/////////////////////////////////////////////// +// +// BOOLARRAY32 +// +BOOLARRAY_LIB_VERSION: 0.3.0 +Bool array size: 1000 + +get +DURATION: 7420 +DURATION: 14028 + X: 0 + +set +DURATION: 5728 +DURATION: 10624 + +clear +DURATION: 65204 +DURATION: 130148 + +setAll +DURATION: 73124 +DURATION: 145996 + +toggle +DURATION: 5600 +DURATION: 10376 +Done... diff --git a/libraries/BoolArray/keywords.txt b/libraries/BoolArray/keywords.txt index 0735d674..f06facfc 100644 --- a/libraries/BoolArray/keywords.txt +++ b/libraries/BoolArray/keywords.txt @@ -2,14 +2,15 @@ # Data types (KEYWORD1) BoolArray KEYWORD1 +BoolArray32 KEYWORD1 # Methods and Functions (KEYWORD2) begin KEYWORD2 size KEYWORD2 memory KEYWORD2 -setAll KEYWORD2 +setAll KEYWORD2 clear KEYWORD2 get KEYWORD2 set KEYWORD2 diff --git a/libraries/BoolArray/library.json b/libraries/BoolArray/library.json index 124b4b47..58a6e32d 100644 --- a/libraries/BoolArray/library.json +++ b/libraries/BoolArray/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/BoolArray.git" }, - "version": "0.2.8", + "version": "0.3.0", "license": "MIT", "frameworks": "*", "platforms": "*", diff --git a/libraries/BoolArray/library.properties b/libraries/BoolArray/library.properties index 263a73a5..688fb4c7 100644 --- a/libraries/BoolArray/library.properties +++ b/libraries/BoolArray/library.properties @@ -1,5 +1,5 @@ name=BoolArray -version=0.2.8 +version=0.3.0 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for compact array of booleans of max size 2000 (UNO). diff --git a/libraries/BoolArray/test/unit_test_001.cpp b/libraries/BoolArray/test/unit_test_001.cpp index de60a62b..bd735523 100644 --- a/libraries/BoolArray/test/unit_test_001.cpp +++ b/libraries/BoolArray/test/unit_test_001.cpp @@ -39,11 +39,11 @@ unittest_teardown() unittest(test_constants) { - assertEqual(2000, BOOLARRAY_MAXSIZE ); - assertEqual(0x00, BOOLARRAY_OK ); - assertEqual(0xFF, BOOLARRAY_ERROR ); - assertEqual(0xFE, BOOLARRAY_SIZE_ERROR); - assertEqual(0xFD, BOOLARRAY_INIT_ERROR); + assertEqual(10000, BOOLARRAY_MAXSIZE ); + assertEqual(0x00, BOOLARRAY_OK ); + assertEqual(0xFF, BOOLARRAY_ERROR ); + assertEqual(0xFE, BOOLARRAY_SIZE_ERROR); + assertEqual(0xFD, BOOLARRAY_INIT_ERROR); }