Skip to content

Commit 247b31d

Browse files
committed
[c++/m] Add Source findSources function
Closes #99
1 parent 75c62cd commit 247b31d

File tree

5 files changed

+157
-0
lines changed

5 files changed

+157
-0
lines changed

+nix/Source.m

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,31 @@
7878
filtered = nix.Utils.filter(obj, filter, val, ...
7979
'Source::sourcesFiltered', @nix.Source);
8080
end
81+
82+
% maxdepth is an index where idx = 0 corresponds to the calling
83+
% source
84+
function sec = find_sources(obj, max_depth)
85+
sec = obj.find_filtered_sources(max_depth, nix.Filter.accept_all, '');
86+
end
87+
88+
% maxdepth is an index where idx = 0 corresponds to the calling
89+
% source
90+
function sec = find_filtered_sources(obj, max_depth, filter, val)
91+
if (~isnumeric(max_depth))
92+
error('Provide a valid search depth');
93+
end
94+
95+
valid = nix.Utils.valid_filter(filter, val);
96+
if(~isempty(valid))
97+
error(valid);
98+
end
99+
100+
ret = nix_mx('Source::findSources', obj.nix_handle, ...
101+
max_depth, uint8(filter), val);
102+
sec = cell(length(ret), 1);
103+
for i = 1:length(ret)
104+
sec{i} = nix.Source(ret{i});
105+
end;
106+
end
81107
end;
82108
end

nix_mx.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ void mexFunction(int nlhs,
287287
methods->add("Source::openSourceIdx", nixsource::openSourceIdx);
288288
methods->add("Source::compare", nixsource::compare);
289289
methods->add("Source::sourcesFiltered", nixsource::sourcesFiltered);
290+
methods->add("Source::findSources", nixsource::findSources);
290291

291292
classdef<nix::Tag>("Tag", methods)
292293
.desc(&nixtag::describe)

src/nixsource.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,17 @@ namespace nixsource {
4949
output.set(0, res);
5050
}
5151

52+
void findSources(const extractor &input, infusor &output) {
53+
nix::Source currObj = input.entity<nix::Source>(1);
54+
size_t max_depth = (size_t)input.num<double>(2);
55+
uint8_t filter_id = input.num<uint8_t>(3);
56+
57+
std::vector<nix::Source> res = filterFullEntity<nix::Source>(input, filter_id, 4, max_depth,
58+
[currObj](const nix::util::Filter<nix::Source>::type &filter, size_t &md) {
59+
return currObj.findSources(filter, md);
60+
});
61+
62+
output.set(0, res);
63+
}
64+
5265
} // namespace nixsource

src/nixsource.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ namespace nixsource {
2121

2222
void sourcesFiltered(const extractor &input, infusor &output);
2323

24+
void findSources(const extractor &input, infusor &output);
25+
2426
} // namespace nixsource
2527

2628
#endif

tests/TestSource.m

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
funcs{end+1} = @test_referring_multi_tags;
2828
funcs{end+1} = @test_compare;
2929
funcs{end+1} = @test_filter_source;
30+
funcs{end+1} = @test_find_source;
31+
funcs{end+1} = @test_find_source_filtered;
3032
end
3133

3234
%% Test: fetch sources
@@ -369,3 +371,116 @@
369371
assert(size(filtered, 1) == 1);
370372
assert(strcmp(filtered{1}.name, mainName));
371373
end
374+
375+
%% Test: Find source w/o filter
376+
function [] = test_find_source
377+
f = nix.File(fullfile(pwd, 'tests', 'testRW.h5'), nix.FileMode.Overwrite);
378+
b = f.create_block('testBlock', 'nixBlock');
379+
s = b.create_source('mainSource', 'nixSource');
380+
sl1 = s.create_source('sourceLvl1', 'nixSource');
381+
382+
sl21 = sl1.create_source('sourceLvl2_1', 'nixSource');
383+
sl22 = sl1.create_source('sourceLvl2_2', 'nixSource');
384+
385+
sl31 = sl21.create_source('sourceLvl3_1', 'nixSource');
386+
sl32 = sl21.create_source('sourceLvl3_2', 'nixSource');
387+
sl33 = sl21.create_source('sourceLvl3_3', 'nixSource');
388+
389+
sl41 = sl31.create_source('sourceLvl4_1', 'nixSource');
390+
sl42 = sl31.create_source('sourceLvl4_2', 'nixSource');
391+
sl43 = sl31.create_source('sourceLvl4_3', 'nixSource');
392+
sl44 = sl31.create_source('sourceLvl4_4', 'nixSource');
393+
394+
% Check invalid entry
395+
err = 'Provide a valid search depth';
396+
try
397+
s.find_sources('hurra');
398+
catch ME
399+
assert(strcmp(ME.message, err));
400+
end
401+
402+
% find all
403+
filtered = s.find_sources(4);
404+
assert(size(filtered, 1) == 11);
405+
406+
% find until level 3
407+
filtered = s.find_sources(3);
408+
assert(size(filtered, 1) == 7);
409+
410+
% find until level 2
411+
filtered = s.find_sources(2);
412+
assert(size(filtered, 1) == 4);
413+
414+
% find until level 1
415+
filtered = s.find_sources(1);
416+
assert(size(filtered, 1) == 2);
417+
418+
% find until level 0
419+
filtered = s.find_sources(0);
420+
assert(size(filtered, 1) == 1);
421+
end
422+
423+
%% Test: Find sources with filters
424+
function [] = test_find_source_filtered
425+
findSource = 'nixFindSource';
426+
f = nix.File(fullfile(pwd, 'tests', 'testRW.h5'), nix.FileMode.Overwrite);
427+
b = f.create_block('testBlock', 'nixBlock');
428+
s = b.create_source('mainSource', 'nixSource');
429+
sl1 = s.create_source('sourceLvl1', 'nixSource');
430+
431+
sl21 = sl1.create_source('sourceLvl2_1', 'nixSource');
432+
sl22 = sl1.create_source('sourceLvl2_2', findSource);
433+
434+
sl31 = sl21.create_source('sourceLvl3_1', findSource);
435+
sl32 = sl21.create_source('sourceLvl3_2', 'nixSource');
436+
sl33 = sl21.create_source('sourceLvl3_3', 'nixSource');
437+
438+
sl41 = sl31.create_source('sourceLvl4_1', 'nixSource');
439+
sl42 = sl31.create_source('sourceLvl4_2', 'nixSource');
440+
sl43 = sl31.create_source('sourceLvl4_3', findSource);
441+
sl44 = sl31.create_source('sourceLvl4_4', 'nixSource');
442+
443+
% test find by id
444+
filtered = s.find_filtered_sources(0, nix.Filter.id, sl41.id);
445+
assert(isempty(filtered));
446+
filtered = s.find_filtered_sources(4, nix.Filter.id, sl41.id);
447+
assert(size(filtered, 1) == 1);
448+
assert(strcmp(filtered{1}.id, sl41.id));
449+
450+
% test find by ids
451+
filterids = {sl1.id, sl41.id};
452+
filtered = s.find_filtered_sources(1, nix.Filter.ids, filterids);
453+
assert(size(filtered, 1) == 1);
454+
filtered = s.find_filtered_sources(4, nix.Filter.ids, filterids);
455+
assert(size(filtered, 1) == 2);
456+
457+
% test find by name
458+
filtered = s.find_filtered_sources(0, nix.Filter.name, sl41.name);
459+
assert(isempty(filtered));
460+
filtered = s.find_filtered_sources(4, nix.Filter.name, sl41.name);
461+
assert(size(filtered, 1) == 1);
462+
assert(strcmp(filtered{1}.name, sl41.name));
463+
464+
% test find by type
465+
filtered = s.find_filtered_sources(0, nix.Filter.type, findSource);
466+
assert(isempty(filtered));
467+
filtered = s.find_filtered_sources(4, nix.Filter.type, findSource);
468+
assert(size(filtered, 1) == 3);
469+
assert(strcmp(filtered{1}.type, findSource));
470+
471+
% test nix.Filter.metadata
472+
sec = f.create_section('testSection', 'nixSection');
473+
sl43.set_metadata(sec);
474+
filtered = s.find_filtered_sources(0, nix.Filter.metadata, sec.id);
475+
assert(isempty(filtered));
476+
filtered = s.find_filtered_sources(4, nix.Filter.metadata, sec.id);
477+
assert(size(filtered, 1) == 1);
478+
strcmp(filtered{1}.id, sl43.id);
479+
480+
% test nix.Filter.source
481+
filtered = s.find_filtered_sources(0, nix.Filter.source, sl44.id);
482+
assert(isempty(filtered));
483+
filtered = s.find_filtered_sources(4, nix.Filter.source, sl44.id);
484+
assert(size(filtered, 1) == 1);
485+
assert(strcmp(filtered{1}.id, sl31.id));
486+
end

0 commit comments

Comments
 (0)