UNPKG

delta-sync

Version:

A lightweight framework for bi-directional database synchronization with automatic version tracking and conflict resolution.

112 lines (111 loc) 5.83 kB
import { describe, test, expect, beforeEach } from 'vitest'; import { SyncView } from '../core/types'; import { performance } from 'perf_hooks'; import { v4 as uuidv4 } from 'uuid'; describe('**SyncView Size Analysis**', () => { let syncView; beforeEach(() => { syncView = new SyncView(); }); function generateRealisticSyncViewItem(index) { return { id: uuidv4(), store: `store${Math.floor(index / 1000)}`, _ver: Math.floor(Math.random() * 5) + 1, deleted: Math.random() < 0.2, isAttachment: Math.random() < 0.1 }; } // 增加超时时间到30秒,减少测试数据量 test('analyze syncview size distribution with realistic data', async () => { // 减少测试数据量 const testVolumes = [1000, 5000, 10000, 50000, 100000]; const results = []; for (const volume of testVolumes) { // 清空之前的数据 syncView.clear(); console.log(`\nTesting with ${volume} items...`); // 分批生成和插入数据,避免内存压力 const BATCH_SIZE = 1000; const totalBatches = Math.ceil(volume / BATCH_SIZE); let totalDeletedItems = 0; let totalAttachments = 0; const storesSet = new Set(); const insertStartTime = performance.now(); for (let batch = 0; batch < totalBatches; batch++) { const start = batch * BATCH_SIZE; const end = Math.min(start + BATCH_SIZE, volume); const items = Array.from({ length: end - start }, (_, i) => generateRealisticSyncViewItem(start + i)); // 统计信息 items.forEach(item => { storesSet.add(item.store); if (item.deleted) totalDeletedItems++; if (item.isAttachment) totalAttachments++; }); syncView.upsertBatch(items); } const insertTime = performance.now() - insertStartTime; console.log(`Insert time: ${insertTime.toFixed(2)}ms`); // 序列化测试 const serializeStartTime = performance.now(); const serialized = syncView.serialize(); const serializationTime = performance.now() - serializeStartTime; // 计算大小 const sizeInBytes = new TextEncoder().encode(serialized).length; const sizeInMB = sizeInBytes / (1024 * 1024); const avgItemSizeInBytes = sizeInBytes / volume; results.push({ items: volume, sizeInMB: sizeInMB, avgItemSizeInBytes: avgItemSizeInBytes, serializationTimeMs: serializationTime, stores: storesSet.size, deletedItems: totalDeletedItems, attachments: totalAttachments }); // 验证数据完整性 expect(syncView.size()).toBe(volume); } // 打印分析报告 console.log('\n📊 SyncView Size Analysis Report'); console.log('================================================================'); console.log('Items\t\tSize(MB)\tAvg(B)\tSerial(ms)\tStores\tDeleted\tAttach'); console.log('----------------------------------------------------------------'); results.forEach(r => { console.log(`${r.items.toString().padEnd(8)}\t` + `${r.sizeInMB.toFixed(2).padEnd(8)}\t` + `${Math.round(r.avgItemSizeInBytes).toString().padEnd(6)}\t` + `${Math.round(r.serializationTimeMs).toString().padEnd(8)}\t` + `${r.stores.toString().padEnd(8)}\t` + `${r.deletedItems.toString().padEnd(8)}\t` + r.attachments); }); console.log('================================================================'); // 100k数据分析 const result100k = results.find(r => r.items === 100000); if (result100k) { console.log('\n🔍 Detailed Analysis for 100k items:'); console.log(`Total Size: ${result100k.sizeInMB.toFixed(2)}MB`); console.log(`Average Item Size: ${Math.round(result100k.avgItemSizeInBytes)} bytes`); console.log(`Serialization Time: ${Math.round(result100k.serializationTimeMs)}ms`); console.log(`Number of Stores: ${result100k.stores}`); console.log(`Deleted Items: ${result100k.deletedItems} (${(result100k.deletedItems / 100000 * 100).toFixed(1)}%)`); console.log(`Attachments: ${result100k.attachments} (${(result100k.attachments / 100000 * 100).toFixed(1)}%)`); // 分片建议 const TARGET_SHARD_SIZE_MB = 4; const suggestedShardSize = Math.ceil(100000 / Math.ceil(result100k.sizeInMB / TARGET_SHARD_SIZE_MB)); console.log('\n💡 Sharding Recommendations:'); console.log(`- Items per shard (targeting ${TARGET_SHARD_SIZE_MB}MB shards): ${suggestedShardSize}`); console.log(`- Expected number of shards for 100k items: ${Math.ceil(100000 / suggestedShardSize)}`); console.log(`- Expected shard size: ${(result100k.sizeInMB / Math.ceil(100000 / suggestedShardSize)).toFixed(2)}MB`); } // 内存使用分析 const memory = process.memoryUsage(); console.log('\n📈 Memory Usage:'); console.log(`Heap Used: ${(memory.heapUsed / 1024 / 1024).toFixed(2)}MB`); console.log(`Heap Total: ${(memory.heapTotal / 1024 / 1024).toFixed(2)}MB`); console.log(`RSS: ${(memory.rss / 1024 / 1024).toFixed(2)}MB`); }, { timeout: 30000 }); // 设置超时时间为30秒 });