| 791 | } |
| 792 | |
| 793 | int cDataMemoryLevel::growLevel(long newSize) |
| 794 | { |
| 795 | SMILE_DBG(3,"increasing buffer size of level '%s' from nT=%i to nT=%i",getName(),lcfg.nT,newSize); |
| 796 | // resize underlying data buffer |
| 797 | if (!data->resize(newSize)) { |
| 798 | SMILE_ERR(1,"could not increase buffer size of level '%s' from nT=%i to nT=%i. Out of memory.",getName(),lcfg.nT,newSize); |
| 799 | return 0; |
| 800 | } |
| 801 | if (lcfg.isRb) { |
| 802 | // for ring buffers, we need to re-order the data in the buffer: |
| 803 | // data at location vIdx % lcfg.nT must be moved to vIdx % newSize in the new buffer |
| 804 | // we only re-order data from curR to curW and zero-fill the remaining space |
| 805 | // (the latter might not be strictly necessary but ensures components read consistent data |
| 806 | // in case they do somehow read data beyond their read pointer) |
| 807 | |
| 808 | // re-order actual data |
| 809 | if (newSize == lcfg.nT * 2) { |
| 810 | // optimization for the common case of doubling the level size |
| 811 | // in this case, we can do the re-ordering in-place |
| 812 | if (curR % lcfg.nT < curW % lcfg.nT) { |
| 813 | // data is stored contiguously (i.e. does not wrap around the end of the ring buffer) |
| 814 | if (curR % lcfg.nT == curR % newSize) { |
| 815 | // data can stay at its place |
| 816 | } else { |
| 817 | // move all data between curR and curW as one contiguous block to the second half of the buffer |
| 818 | data->copyTo(*data, curR % newSize, curR % lcfg.nT, curW - curR, true); |
| 819 | } |
| 820 | } else { |
| 821 | // data wraps around the end of the ring buffer |
| 822 | if (curR % lcfg.nT == curR % newSize) { |
| 823 | // second part of data at beginning of ring buffer needs to be moved to the beginning of second half of the buffer |
| 824 | data->copyTo(*data, lcfg.nT, 0, curW % lcfg.nT, true); |
| 825 | } else { |
| 826 | // first part of data up to end of first half of buffer needs to be moved to the end of the second half of the buffer |
| 827 | data->copyTo(*data, (curR % lcfg.nT) + lcfg.nT, curR % lcfg.nT, lcfg.nT - (curR % lcfg.nT), true); |
| 828 | } |
| 829 | } |
| 830 | } else { |
| 831 | // general case (temporarily needs more space but works for any buffer size) |
| 832 | void *tmp = calloc(sizeof(FLOAT_DMEM), lcfg.nT * data->N); |
| 833 | if (tmp == NULL) { |
| 834 | SMILE_ERR(1,"could not allocate temporary buffer for increasing buffer size of level '%s' from nT=%i to nT=%i. Out of memory.",getName(),lcfg.nT,newSize); |
| 835 | return 0; |
| 836 | } |
| 837 | data->copyTo(tmp, 0, 0, lcfg.nT, true); |
| 838 | for (long t = curR; t < curW; t++) { |
| 839 | data->copyFrom(tmp, t % lcfg.nT, t % newSize, 1, false); |
| 840 | } |
| 841 | free(tmp); |
| 842 | } |
| 843 | |
| 844 | if (data->tmeta != NULL) { |
| 845 | // also re-order data->tmeta in the same way |
| 846 | TimeMetaInfo *tmetatmp = new TimeMetaInfo[lcfg.nT]; |
| 847 | std::move(data->tmeta, data->tmeta + lcfg.nT, tmetatmp); |
| 848 | std::fill(data->tmeta, data->tmeta + lcfg.nT, TimeMetaInfo()); |
| 849 | for (long t = curR; t < curW; t++) { |
| 850 | data->tmeta[t % newSize] = std::move(tmetatmp[t % lcfg.nT]); |
nothing calls this directly
no test coverage detected