Listing 2: The cdc_data_flush function
int cdc_data_flush(cdc_t *cdc) { int rc; rc = 0; if (cdc->data.cluster.dirty) { unsigned long bat_entry; unsigned long bat_entry_next; const char *ptr; unsigned long count; size_t zsize; unsigned long compress_flag; cdc->data.cluster.dirty = 0; count = cdc->data.blocks; ptr = cdc->data.cluster.buffer; compress_flag = 0; zsize = cdc->data.size; rc = cdc->env->deflate.fn( cdc->env->deflate.arg, cdc->data.zbuffer, &zsize, cdc->data.cluster.buffer, cdc->data.size ); if (0 == rc) { /* * success! but if we don't save at least 1 block, * don't bother */ count = (zsize + cdc->blk.size - 1) / cdc->blk.size; if (count < cdc->data.blocks) { compress_flag = MAP_FLAG_COMPRESSED; ptr = cdc->data.zbuffer; } } rc = cdc_map_entry_get(cdc, cdc->data.cluster.cluster, &bat_entry); if (0 == rc) { if (BAT_ENTRY_EOL == bat_entry) { /* get a free bat entry */ rc = cdc_bat_entry_alloc(cdc, &bat_entry); if (0 == rc) { rc = cdc_map_entry_set( cdc, cdc->data.cluster.cluster, bat_entry | compress_flag ); } } else { unsigned long map_entry; map_entry = bat_entry; if (compress_flag) { map_entry |= MAP_FLAG_COMPRESSED; } else { map_entry &= ~MAP_FLAG_COMPRESSED; } if (bat_entry != map_entry) { rc = cdc_map_entry_set(cdc, cdc->data.cluster.cluster, map_entry); } bat_entry &= ~MAP_FLAG_COMPRESSED; } } while ((0 == rc) && count) { rc = data_block_write(cdc, bat_entry, ptr); if (0 == rc) { rc = cdc_bat_entry_get(cdc, bat_entry, &bat_entry_next); } if (0 == rc) { count--; if (count) { ptr += cdc->blk.size; if (0 == rc) { if (BAT_ENTRY_EOL == bat_entry_next) { rc = cdc_bat_entry_alloc(cdc, &bat_entry_next); if (0 == rc) { rc = cdc_bat_entry_set(cdc, bat_entry, bat_entry_next); } } bat_entry = bat_entry_next; } } } } /* * free up any remaining entries * --- occurs if the current cluster compresses to less than * the previous one */ if ((0 == rc) && (BAT_ENTRY_EOL != bat_entry_next)) { /* mark the end */ cdc_bat_entry_set(cdc, bat_entry, BAT_ENTRY_EOL); do { bat_entry = bat_entry_next; rc = cdc_bat_entry_get(cdc, bat_entry, &bat_entry_next); if (0 == rc) { rc = cdc_bat_entry_free(cdc, bat_entry); } } while ((0 == rc) && (BAT_ENTRY_EOL != bat_entry_next)); } } return rc; } End of Listing