// Test CacheBlockAddress Utility class, mostly that constructor and // comparison operators are properly defined. bool TestCacheBlockAddress() { uint32 offset = 100; uint32 segment_id = 1010; CachedReadAccessor::CacheBlockAddress address1(segment_id, offset); TestAssertEquals(offset, address1.Offset()); { // Equality and copy constructor tests. CachedReadAccessor::CacheBlockAddress address2(segment_id, offset); TestAssert(address1 == address2); TestAssert((address1 < address2) == false); CachedReadAccessor::CacheBlockAddress address3 = address1; TestAssert(address2 == address3); } { // less than by segment id CachedReadAccessor::CacheBlockAddress address2(segment_id+1, offset); TestAssert(address1 < address2); TestAssert(address1 != address2); TestAssert((address2 < address1) == false); } { // less than by offset CachedReadAccessor::CacheBlockAddress address2(segment_id, offset+1); TestAssert(address1 < address2); TestAssert(address1 != address2); TestAssert((address2 < address1) == false); } return true; }
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // SetPropertyData() //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void SMPTETimeCallback::SetPropertyData(const CMIOObjectPropertyAddress& address, UInt32 /*qualifierDataSize*/, const void* /*qualifierData*/, UInt32 dataSize, const void* data) { switch (address.mSelector) { case kCMIODevicePropertySMPTETimeCallback: ThrowIf(dataSize != sizeof(CMIODeviceSMPTETimeCallback), CAException(kCMIOHardwareBadPropertySizeError), "SMPTETimeCallback::SetData: wrong data size for kCMIODevicePropertySMPTETimeCallback"); mSMPTECallback = *(static_cast<const CMIODeviceSMPTETimeCallback*>(data)); PropertyAddress address1(kCMIODevicePropertySMPTETimeCallback); mOwningDevice.PropertiesChanged(1, &address1); break; }; }
// Test the CacheBlock utility object Read() and LastAccessTick(). bool TestCacheBlock() { uint32 offset = 13; uint32 segment_id = 0; uint32 block_size = file_bundle_size_ / 4; CachedReadAccessor::CacheBlockAddress address1(segment_id, 0); uint64 access_tick = 1033; CachedReadAccessor::CacheBlock block1(address1, block_size); // Check the initial access tick TestAssert(block1.LastAccessTick() == 0); block1.SetLastAccessTick(access_tick - 1); TestAssert(block1.LastAccessTick() == (access_tick - 1)); // Test Read // Read request that is contained in 1 block. uint32 request_count = block_size - offset - 10; FileBundleReaderSegment segment(file_pool_, path_base_, segment_names_[segment_id], segment_names_[segment_id], segment_id); std::string buffer; buffer.reserve(block_size); buffer.resize(request_count); char* out_buffer = const_cast<char*>(buffer.data()); // Test read within non-cached (uninitialized) block uint64 stats_bytes_read = 0; uint64 stats_disk_accesses = 0; uint32 read_count = block1.Read(segment, out_buffer, request_count, offset, access_tick++, stats_bytes_read, stats_disk_accesses); TestAssert(block1.LastAccessTick() + 1 == access_tick); TestAssertEquals(stats_bytes_read, static_cast<uint64>(block_size)); TestAssertEquals(stats_disk_accesses, static_cast<uint64>(1)); TestAssertEquals(request_count, read_count); char* expected = test_buffer_ + offset; if (!TestBuffer(out_buffer, expected, read_count, std::string("TestCacheBlock: all data in one non-cached block"))) return false; // Test read from the NOW cached block within the segment. offset = 23; request_count /= 3; buffer.resize(request_count); read_count = block1.Read(segment, out_buffer, request_count, offset, access_tick++, stats_bytes_read, stats_disk_accesses); TestAssertEquals(stats_bytes_read, static_cast<uint64>(block_size)); TestAssertEquals(stats_disk_accesses, static_cast<uint64>(1)); TestAssertEquals(request_count, read_count); expected = test_buffer_ + offset; if (!TestBuffer(out_buffer, expected, read_count, std::string("TestCacheBlock: all data in one cached block"))) return false; // Test a PARTIAL reads from a block (i.e., a request past the block // boundary. // create a new CacheBlock to start with an empty cache. block1 = CachedReadAccessor::CacheBlock(address1, block_size); request_count = 200; buffer.resize(request_count); uint32 expected_read_count = 133; offset = block_size - expected_read_count; // Read from a non-cached block read_count = block1.Read(segment, out_buffer, request_count, offset, access_tick++, stats_bytes_read, stats_disk_accesses); TestAssertEquals(stats_bytes_read, static_cast<uint64>(2*block_size)); TestAssertEquals(stats_disk_accesses, static_cast<uint64>(2)); TestAssertEquals(expected_read_count, read_count); expected = test_buffer_ + offset; if (!TestBuffer(out_buffer, expected, read_count, std::string("TestCacheBlock: partial data in cached block"))) return false; // Read from a cached block read_count = block1.Read(segment, out_buffer, request_count, offset, access_tick++, stats_bytes_read, stats_disk_accesses); TestAssertEquals(expected_read_count, read_count); expected = test_buffer_ + offset; if (!TestBuffer(out_buffer, expected, read_count, std::string("TestCacheBlock: partial data in cached block"))) return false; return true; }