Skip to content

Commit 42e66d8

Browse files
vpecinkaVlastimil Pečínka
andauthored
format segment name, close #365 (#366)
* format segment name, close #365 --------- Co-authored-by: Vlastimil Pečínka <vlastimil.pecinka@firma.seznam.cz>
1 parent cba8dc5 commit 42e66d8

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

src/ObjectStore/v1/Models/Container.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,22 @@ public function objectExists(string $name): bool
180180
}
181181
}
182182

183+
/**
184+
* Verifies if provied segment index format for DLOs is valid.
185+
*
186+
* @param string $fmt The format of segment index name, e.g. %05d for 00001, 00002, etc.
187+
*
188+
* @return bool TRUE if the format is valid, FALSE if it is not
189+
*/
190+
public function isValidSegmentIndexFormat($fmt)
191+
{
192+
$testValue1 = sprintf($fmt, 1);
193+
$testValue2 = sprintf($fmt, 10);
194+
195+
// Test if different results of the same string length
196+
return ($testValue1 !== $testValue2) && (strlen($testValue1) === strlen($testValue2));
197+
}
198+
183199
/**
184200
* Creates a single object according to the values provided.
185201
*
@@ -197,11 +213,12 @@ public function createObject(array $data): StorageObject
197213
* container. When this completes, a manifest file is uploaded which references the prefix of the segments,
198214
* allowing concatenation when a request is executed against the manifest.
199215
*
200-
* @param array $data {@see \OpenStack\ObjectStore\v1\Api::putObject}
201-
* @param int $data['segmentSize'] The size in Bytes of each segment
202-
* @param string $data['segmentContainer'] The container to which each segment will be uploaded
203-
* @param string $data['segmentPrefix'] The prefix that will come before each segment. If omitted, a default
204-
* is used: name/timestamp/filesize
216+
* @param array $data {@see \OpenStack\ObjectStore\v1\Api::putObject}
217+
* @param int $data['segmentSize'] The size in Bytes of each segment
218+
* @param string $data['segmentContainer'] The container to which each segment will be uploaded
219+
* @param string $data['segmentPrefix'] The prefix that will come before each segment. If omitted, a default
220+
* is used: name/timestamp/filesize
221+
* @param string $data['segmentIndexFormat'] The format of segment index name, default %05d - 00001, 00002, etc.
205222
*/
206223
public function createLargeObject(array $data): StorageObject
207224
{
@@ -213,6 +230,11 @@ public function createLargeObject(array $data): StorageObject
213230
$segmentPrefix = isset($data['segmentPrefix'])
214231
? $data['segmentPrefix']
215232
: sprintf('%s/%s/%d', $data['name'], microtime(true), $stream->getSize());
233+
$segmentIndexFormat = isset($data['segmentIndexFormat']) ? $data['segmentIndexFormat'] : '%05d';
234+
235+
if (!$this->isValidSegmentIndexFormat($segmentIndexFormat)) {
236+
throw new \InvalidArgumentException('The provided segmentIndexFormat is not valid.');
237+
}
216238

217239
/** @var \OpenStack\ObjectStore\v1\Service $service */
218240
$service = $this->getService();
@@ -226,7 +248,7 @@ public function createLargeObject(array $data): StorageObject
226248

227249
while (!$stream->eof() && $count < $totalSegments) {
228250
$promises[] = $this->model(StorageObject::class)->createAsync([
229-
'name' => sprintf('%s/%d', $segmentPrefix, ++$count),
251+
'name' => sprintf('%s/'.$segmentIndexFormat, $segmentPrefix, ++$count),
230252
'stream' => new LimitStream($stream, $segmentSize, ($count - 1) * $segmentSize),
231253
'containerName' => $segmentContainer,
232254
]);

tests/unit/ObjectStore/v1/Models/ContainerTest.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ public function test_other_exceptions_are_thrown()
208208
$this->container->objectExists('bar');
209209
}
210210

211+
public function test_valid_segment_index_format()
212+
{
213+
self::assertTrue($this->container->isValidSegmentIndexFormat("%03d"));
214+
self::assertTrue($this->container->isValidSegmentIndexFormat("%05d"));
215+
self::assertFalse($this->container->isValidSegmentIndexFormat("%d"));
216+
self::assertFalse($this->container->isValidSegmentIndexFormat("d"));
217+
}
218+
211219
public function test_it_chunks_according_to_provided_segment_size()
212220
{
213221
$stream = function_exists('\GuzzleHttp\Psr7\stream_for')
@@ -220,6 +228,7 @@ public function test_it_chunks_according_to_provided_segment_size()
220228
'segmentSize' => 10,
221229
'segmentPrefix' => 'objectPrefix',
222230
'segmentContainer' => 'segments',
231+
'segmentIndexFormat' => '%03d',
223232
];
224233

225234
// check container creation
@@ -235,9 +244,9 @@ public function test_it_chunks_according_to_provided_segment_size()
235244
$this->setupMock('PUT', 'segments', null, [], new Response(201));
236245

237246
// The stream has size 24 so we expect three segments.
238-
$this->setupMock('PUT', 'segments/objectPrefix/1', $stream->read(10), [], new Response(201));
239-
$this->setupMock('PUT', 'segments/objectPrefix/2', $stream->read(10), [], new Response(201));
240-
$this->setupMock('PUT', 'segments/objectPrefix/3', $stream->read(10), [], new Response(201));
247+
$this->setupMock('PUT', 'segments/objectPrefix/001', $stream->read(10), [], new Response(201));
248+
$this->setupMock('PUT', 'segments/objectPrefix/002', $stream->read(10), [], new Response(201));
249+
$this->setupMock('PUT', 'segments/objectPrefix/003', $stream->read(10), [], new Response(201));
241250
$this->setupMock('PUT', 'test/object', null, ['X-Object-Manifest' => 'segments/objectPrefix'], new Response(201));
242251

243252
$stream->rewind();

0 commit comments

Comments
 (0)