| 848 | } |
| 849 | |
| 850 | void DsqlBatch::DataCache::put(const void* d, ULONG dataSize) |
| 851 | { |
| 852 | if (m_used + m_cache.getCount() + dataSize > m_limit) |
| 853 | ERR_post(Arg::Gds(isc_batch_too_big)); |
| 854 | |
| 855 | const UCHAR* data = reinterpret_cast<const UCHAR*>(d); |
| 856 | |
| 857 | // Coefficient affecting direct data write to tempspace |
| 858 | const ULONG K = 4; |
| 859 | |
| 860 | // ensure ram cache presence |
| 861 | fb_assert(m_cacheCapacity); |
| 862 | |
| 863 | // swap to secondary cache if needed |
| 864 | if (m_cache.getCount() + dataSize > m_cacheCapacity) |
| 865 | { |
| 866 | // store data in the end of ram cache if needed |
| 867 | // avoid copy in case of huge buffer passed |
| 868 | ULONG delta = m_cacheCapacity - m_cache.getCount(); |
| 869 | if (dataSize - delta < m_cacheCapacity / K) |
| 870 | { |
| 871 | m_cache.append(data, delta); |
| 872 | data += delta; |
| 873 | dataSize -= delta; |
| 874 | } |
| 875 | |
| 876 | // swap ram cache to tempspace |
| 877 | flush(); |
| 878 | |
| 879 | // in a case of huge buffer write directly to tempspace |
| 880 | if (dataSize > m_cacheCapacity / K) |
| 881 | { |
| 882 | const FB_UINT64 writtenBytes = m_space->write(m_used, data, dataSize); |
| 883 | fb_assert(writtenBytes == dataSize); |
| 884 | m_used += dataSize; |
| 885 | return; |
| 886 | } |
| 887 | } |
| 888 | |
| 889 | m_cache.append(data, dataSize); |
| 890 | } |
| 891 | |
| 892 | void DsqlBatch::DataCache::flush() |
| 893 | { |
no test coverage detected