Skip to content

Commit 7d8d0d2

Browse files
committed
Implement ls_recursive.
1 parent f20011a commit 7d8d0d2

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

clibrary.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ TILEDB_EXPORT int32_t _vfs_ls(
2121
return ret_val;
2222
}
2323

24+
TILEDB_EXPORT int32_t _vfs_ls_recursive(
25+
tiledb_ctx_t* ctx,
26+
tiledb_vfs_t* vfs,
27+
const char* path,
28+
void* data) {
29+
int32_t ret_val = tiledb_vfs_ls_recursive(ctx, vfs, path, vfsLsRecursive, data);
30+
return ret_val;
31+
}
32+
2433
TILEDB_EXPORT int32_t _tiledb_object_walk(
2534
tiledb_ctx_t* ctx,
2635
const char* path,
@@ -36,4 +45,4 @@ TILEDB_EXPORT int32_t _tiledb_object_ls(
3645
void* data) {
3746
int32_t ret_val = tiledb_object_ls(ctx, path, objectsInPath, data);
3847
return ret_val;
39-
}
48+
}

clibrary.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#ifndef CLIBRARY_H
22
#define CLIBRARY_H
33

4-
#include <tiledb/tiledb.h>
4+
#include <tiledb/tiledb_experimental.h>
55

66
typedef const char cchar_t;
77

88
int32_t numOfFragmentsInPath(cchar_t* path, void *data);
99
int32_t vfsLs(cchar_t* path, void *data);
10+
int32_t vfsLsRecursive(cchar_t* path, size_t path_len, uint64_t size, void *data);
1011
int32_t objectsInPath(cchar_t* path, tiledb_object_t objectType, void *data);
1112

1213
TILEDB_EXPORT int32_t _num_of_folders_in_path(
@@ -21,6 +22,12 @@ TILEDB_EXPORT int32_t _vfs_ls(
2122
const char* path,
2223
void* data);
2324

25+
TILEDB_EXPORT int32_t _vfs_ls_recursive(
26+
tiledb_ctx_t* ctx,
27+
tiledb_vfs_t* vfs,
28+
const char* path,
29+
void* data);
30+
2431
TILEDB_EXPORT int32_t _tiledb_object_walk(
2532
tiledb_ctx_t* ctx,
2633
const char* path,
@@ -32,4 +39,4 @@ TILEDB_EXPORT int32_t _tiledb_object_ls(
3239
const char* path,
3340
void* data);
3441

35-
#endif
42+
#endif

vfs.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,3 +643,52 @@ func (v *VFS) List(path string) ([]string, []string, error) {
643643

644644
return folderData.Folders, folderData.Files, nil
645645
}
646+
647+
type visitRecursiveCallback = func(path string, size uint64) (doContinue bool, err error)
648+
649+
// visitRecursiveState contains the state of a call to VisitRecursive.
650+
type visitRecursiveState struct {
651+
callback visitRecursiveCallback
652+
lastError error
653+
}
654+
655+
//export vfsLsRecursive
656+
func vfsLsRecursive(path *C.cchar_t, path_len C.size_t, size C.uint64_t, data unsafe.Pointer) int32 {
657+
state := pointer.Restore(data).(*visitRecursiveState)
658+
659+
if path_len > math.MaxInt {
660+
state.lastError = errors.New("path is too long")
661+
return 0
662+
}
663+
664+
doContinue, err := state.callback(C.GoStringN(path, C.int(path_len)), uint64(size))
665+
666+
if err != nil || !doContinue {
667+
// Save error to return to the user.
668+
state.lastError = err
669+
return 0
670+
}
671+
672+
return 1
673+
}
674+
675+
// VisitRecursive calls a function for every file in a path recursively.
676+
// This function returns if the listing ends, or if the callback returns false or an error.
677+
func (v *VFS) VisitRecursive(path string, callback visitRecursiveCallback) error {
678+
cpath := C.CString(path)
679+
defer C.free(unsafe.Pointer(cpath))
680+
681+
state := &visitRecursiveState{
682+
callback: callback,
683+
lastError: nil,
684+
}
685+
data := pointer.Save(state)
686+
defer pointer.Unref(data)
687+
688+
ret := C._vfs_ls_recursive(v.context.tiledbContext, v.tiledbVFS, cpath, data)
689+
if ret != C.TILEDB_OK {
690+
return fmt.Errorf("error in recursively listing path %s: %w", path, v.context.LastError())
691+
}
692+
693+
return state.lastError
694+
}

0 commit comments

Comments
 (0)