private void updateHandle(RollingSegmentHandle handle, byte[] data) throws StreamSegmentException { try { this.baseStorage.write(handle.getHeaderHandle(), handle.getHeaderLength(), new ByteArrayInputStream(data), data.length); handle.increaseHeaderLength(data.length); log.debug("Header for '{}' updated with {} bytes for a length of {}.", handle.getSegmentName(), data.length, handle.getHeaderLength()); } catch (BadOffsetException ex) { // If we get BadOffsetException when writing the Handle, it means it was modified externally. throw new StorageNotPrimaryException(handle.getSegmentName(), ex); } }
/** * Updates the contents of this handle with information from the given one. * * @param source The RollingSegmentHandle to update from. */ synchronized void refresh(RollingSegmentHandle source) { Preconditions.checkArgument(source.getSegmentName().equals(this.getSegmentName()), "SegmentName mismatch."); if (this.readOnly == source.readOnly) { // Update the header handle, but only if both this handle and the source one have the same read-only flag. // Otherwise we risk attaching a read-only header handle to a read-write handle or vice-versa. this.headerHandle = source.headerHandle; } this.segmentChunks = new ArrayList<>(source.chunks()); setHeaderLength(source.getHeaderLength()); if (source.isSealed()) { markSealed(); } if (source.isDeleted()) { markDeleted(); } }
sealActiveChunk(target); serializeBeginConcat(target, source); this.baseStorage.concat(target.getHeaderHandle(), target.getHeaderLength(), source.getHeaderHandle().getSegmentName()); target.increaseHeaderLength(source.getHeaderLength()); target.addChunks(newSegmentChunks);
val newHandle = HandleSerializer.deserialize(serialization, source.getHeaderHandle()); assertHandleEquals(source, newHandle, source.getHeaderHandle()); Assert.assertEquals("getHeaderLength", serialization.length, newHandle.getHeaderLength());
/** * Tests the basic Serialization-Deserialization for a Handle with no concat executed on it. */ @Test public void testNormalSerialization() { final int chunkCount = 1000; val source = newHandle(chunkCount); val serialization = serialize(source); val newHandle = HandleSerializer.deserialize(serialization, source.getHeaderHandle()); assertHandleEquals(source, newHandle, source.getHeaderHandle()); Assert.assertEquals("getHeaderLength", serialization.length, newHandle.getHeaderLength()); }
/** * Tests the ability of the Handle to refresh based on information from another similar handle. */ @Test public void testRefresh() { val headerHandle = new TestHandle(HEADER_NAME, true); val target = new RollingSegmentHandle(headerHandle, DEFAULT_ROLLING_POLICY, Collections.singletonList(new SegmentChunk("s1", 0L))); val source = new RollingSegmentHandle(headerHandle, DEFAULT_ROLLING_POLICY, Arrays.asList( new SegmentChunk("s1", 0L), new SegmentChunk("s2", 100L))); source.chunks().get(0).setLength(100); source.markSealed(); source.setHeaderLength(1000); source.setActiveChunkHandle(new TestHandle(source.lastChunk().getName(), false)); target.refresh(source); Assert.assertEquals("Unexpected getHeaderLength()", source.getHeaderLength(), target.getHeaderLength()); AssertExtensions.assertListEquals("Unexpected chunks()", source.chunks(), target.chunks(), Object::equals); Assert.assertTrue("Unexpected isSealed.", target.isSealed()); Assert.assertNull("Not expecting any ActiveSegmentHandle to be copied.", target.getActiveChunkHandle()); }
Assert.assertEquals("Unexpected contents in chunks() for empty handle.", 0, h.chunks().size()); Assert.assertEquals("Unexpected value for length() for empty handle.", 0, h.length()); Assert.assertEquals("Unexpected value for getHeaderLength() for empty handle.", 0, h.getHeaderLength()); Assert.assertEquals("Unexpected value for getHeaderHandle().", headerHandle, h.getHeaderHandle()); Assert.assertEquals("Unexpected segment name.", SEGMENT_NAME, h.getSegmentName()); Assert.assertEquals("Unexpected value for getHeaderLength when set and then increased.", 15, h.getHeaderLength());