* BufFileWrite * * Like fwrite() except we assume 1-byte element size and report errors via * ereport(). */
| 821 | * ereport(). |
| 822 | */ |
| 823 | void |
| 824 | BufFileWrite(BufFile *file, void *ptr, size_t size) |
| 825 | { |
| 826 | size_t nthistime; |
| 827 | |
| 828 | Assert(!file->readOnly); |
| 829 | |
| 830 | SIMPLE_FAULT_INJECTOR("workfile_write_failure"); |
| 831 | |
| 832 | switch (file->state) |
| 833 | { |
| 834 | case BFS_RANDOM_ACCESS: |
| 835 | case BFS_SEQUENTIAL_WRITING: |
| 836 | break; |
| 837 | |
| 838 | case BFS_COMPRESSED_WRITING: |
| 839 | BufFileDumpCompressedBuffer(file, ptr, size); |
| 840 | return; |
| 841 | |
| 842 | case BFS_SEQUENTIAL_READING: |
| 843 | case BFS_COMPRESSED_READING: |
| 844 | elog(ERROR, "cannot write to sequential BufFile after reading"); |
| 845 | } |
| 846 | |
| 847 | while (size > 0) |
| 848 | { |
| 849 | if (file->pos >= BLCKSZ) |
| 850 | { |
| 851 | /* Buffer full, dump it out */ |
| 852 | if (file->dirty) |
| 853 | BufFileDumpBuffer(file); |
| 854 | else |
| 855 | { |
| 856 | /* Hmm, went directly from reading to writing? */ |
| 857 | file->curOffset += file->pos; |
| 858 | file->pos = 0; |
| 859 | file->nbytes = 0; |
| 860 | } |
| 861 | } |
| 862 | |
| 863 | nthistime = BLCKSZ - file->pos; |
| 864 | if (nthistime > size) |
| 865 | nthistime = size; |
| 866 | Assert(nthistime > 0); |
| 867 | |
| 868 | memcpy(file->buffer.data + file->pos, ptr, nthistime); |
| 869 | |
| 870 | file->dirty = true; |
| 871 | file->pos += nthistime; |
| 872 | if (file->nbytes < file->pos) |
| 873 | file->nbytes = file->pos; |
| 874 | ptr = (void *) ((char *) ptr + nthistime); |
| 875 | size -= nthistime; |
| 876 | } |
| 877 | } |
| 878 | |
| 879 | /* |
| 880 | * BufFileFlush |