nanoarrow 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/nanoarrow/nanoarrow/nanoarrow.h +140 -9
- data/ext/nanoarrow/nanoarrow.c +527 -74
- data/lib/nanoarrow/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: decb8918e601df4caf34ed3f7b3e0156e8cc786b8c71d9319eeeac232cfbd1bb
|
|
4
|
+
data.tar.gz: cebef59fcd99d497795f96286cc0442f3d2469f87b6f81245ccb30dd33231dfe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a55d007c99986854f1b91b30a8578b8873d192a3ff9b8dbeec02ac4cf0eb22ec1a5db8dc2510c8b6d0557fbaa0f9f5e1c595a7250b08079633ab1f9e381e6ea7
|
|
7
|
+
data.tar.gz: 526031a467ecb8266d641bd0947a3c67f252e5b77f52f3b2fb7dedcdf28f4a1f3a767505ada6d5f0ddf0e1e705e1d11cb9a8c196b93452bae5ad60c4dcf37076
|
data/CHANGELOG.md
CHANGED
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
#define NANOARROW_CONFIG_H_INCLUDED
|
|
20
20
|
|
|
21
21
|
#define NANOARROW_VERSION_MAJOR 0
|
|
22
|
-
#define NANOARROW_VERSION_MINOR
|
|
22
|
+
#define NANOARROW_VERSION_MINOR 9
|
|
23
23
|
#define NANOARROW_VERSION_PATCH 0
|
|
24
|
-
#define NANOARROW_VERSION "0.
|
|
24
|
+
#define NANOARROW_VERSION "0.9.0"
|
|
25
25
|
|
|
26
26
|
#define NANOARROW_VERSION_INT \
|
|
27
27
|
(NANOARROW_VERSION_MAJOR * 10000 + NANOARROW_VERSION_MINOR * 100 + \
|
|
@@ -181,6 +181,13 @@ struct ArrowArrayStream {
|
|
|
181
181
|
if (NAME) return NAME; \
|
|
182
182
|
} while (0)
|
|
183
183
|
|
|
184
|
+
// __COUNTER__ is not guaranteed to be available and some compiler warnings may occur
|
|
185
|
+
// if we use it (-Wc2y-extensions). We don't strictly need it because of the
|
|
186
|
+
// do { ... } while(0) scoping and because we never need the return value to live
|
|
187
|
+
// outside the temporary scope. Here we define a suffix that is unlikely to collide
|
|
188
|
+
// with anything in EXPR.
|
|
189
|
+
#define _NANOARROW_UNIQUE_SUFFIX _nanoarrow_unique_suffix
|
|
190
|
+
|
|
184
191
|
#define _NANOARROW_CHECK_RANGE(x_, min_, max_) \
|
|
185
192
|
NANOARROW_RETURN_NOT_OK((x_ >= min_ && x_ <= max_) ? NANOARROW_OK : EINVAL)
|
|
186
193
|
|
|
@@ -305,7 +312,8 @@ static inline void ArrowErrorSetString(struct ArrowError* error, const char* src
|
|
|
305
312
|
/// \brief Check the result of an expression and return it if not NANOARROW_OK
|
|
306
313
|
/// \ingroup nanoarrow-errors
|
|
307
314
|
#define NANOARROW_RETURN_NOT_OK(EXPR) \
|
|
308
|
-
_NANOARROW_RETURN_NOT_OK_IMPL(
|
|
315
|
+
_NANOARROW_RETURN_NOT_OK_IMPL( \
|
|
316
|
+
_NANOARROW_MAKE_NAME(errno_status_, _NANOARROW_UNIQUE_SUFFIX), EXPR)
|
|
309
317
|
|
|
310
318
|
/// \brief Check the result of an expression and return it if not NANOARROW_OK,
|
|
311
319
|
/// adding an auto-generated message to an ArrowError.
|
|
@@ -314,9 +322,10 @@ static inline void ArrowErrorSetString(struct ArrowError* error, const char* src
|
|
|
314
322
|
/// This macro is used to ensure that functions that accept an ArrowError
|
|
315
323
|
/// as input always set its message when returning an error code (e.g., when calling
|
|
316
324
|
/// a nanoarrow function that does *not* accept ArrowError).
|
|
317
|
-
#define NANOARROW_RETURN_NOT_OK_WITH_ERROR(EXPR, ERROR_EXPR)
|
|
318
|
-
_NANOARROW_RETURN_NOT_OK_WITH_ERROR_IMPL(
|
|
319
|
-
_NANOARROW_MAKE_NAME(errno_status_,
|
|
325
|
+
#define NANOARROW_RETURN_NOT_OK_WITH_ERROR(EXPR, ERROR_EXPR) \
|
|
326
|
+
_NANOARROW_RETURN_NOT_OK_WITH_ERROR_IMPL( \
|
|
327
|
+
_NANOARROW_MAKE_NAME(errno_status_, _NANOARROW_UNIQUE_SUFFIX), EXPR, ERROR_EXPR, \
|
|
328
|
+
#EXPR)
|
|
320
329
|
|
|
321
330
|
#if defined(NANOARROW_DEBUG) && !defined(NANOARROW_PRINT_AND_DIE)
|
|
322
331
|
#define NANOARROW_PRINT_AND_DIE(VALUE, EXPR_STR) \
|
|
@@ -343,7 +352,8 @@ static inline void ArrowErrorSetString(struct ArrowError* error, const char* src
|
|
|
343
352
|
/// be defining the NANOARROW_PRINT_AND_DIE macro before including nanoarrow.h
|
|
344
353
|
/// This macro is provided as a convenience for users and is not used internally.
|
|
345
354
|
#define NANOARROW_ASSERT_OK(EXPR) \
|
|
346
|
-
_NANOARROW_ASSERT_OK_IMPL(
|
|
355
|
+
_NANOARROW_ASSERT_OK_IMPL( \
|
|
356
|
+
_NANOARROW_MAKE_NAME(errno_status_, _NANOARROW_UNIQUE_SUFFIX), EXPR, #EXPR)
|
|
347
357
|
|
|
348
358
|
#define _NANOARROW_DCHECK_IMPL(EXPR, EXPR_STR) \
|
|
349
359
|
do { \
|
|
@@ -502,7 +512,7 @@ enum ArrowType {
|
|
|
502
512
|
/// \brief Get a string value of an enum ArrowType value
|
|
503
513
|
/// \ingroup nanoarrow-utils
|
|
504
514
|
///
|
|
505
|
-
/// Returns
|
|
515
|
+
/// Returns "<unknown type identifier>" for invalid values for type
|
|
506
516
|
static inline const char* ArrowTypeString(enum ArrowType type);
|
|
507
517
|
|
|
508
518
|
static inline const char* ArrowTypeString(enum ArrowType type) {
|
|
@@ -598,7 +608,7 @@ static inline const char* ArrowTypeString(enum ArrowType type) {
|
|
|
598
608
|
case NANOARROW_TYPE_LARGE_LIST_VIEW:
|
|
599
609
|
return "large_list_view";
|
|
600
610
|
default:
|
|
601
|
-
return
|
|
611
|
+
return "<unknown type identifier>";
|
|
602
612
|
}
|
|
603
613
|
}
|
|
604
614
|
|
|
@@ -1130,6 +1140,17 @@ static inline void ArrowDecimalSetBytes(struct ArrowDecimal* decimal,
|
|
|
1130
1140
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowBufferAllocatorDefault)
|
|
1131
1141
|
#define ArrowBufferDeallocator \
|
|
1132
1142
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowBufferDeallocator)
|
|
1143
|
+
#define ArrowSharedBufferInit NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSharedBufferInit)
|
|
1144
|
+
#define ArrowSharedBufferIsThreadSafe \
|
|
1145
|
+
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSharedBufferIsThreadSafe)
|
|
1146
|
+
#define ArrowSharedBufferClone \
|
|
1147
|
+
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSharedBufferClone)
|
|
1148
|
+
#define ArrowSharedArrayInit NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSharedArrayInit)
|
|
1149
|
+
#define ArrowSharedArrayRelease \
|
|
1150
|
+
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSharedArrayRelease)
|
|
1151
|
+
#define ArrowSharedArrayBuffer \
|
|
1152
|
+
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSharedArrayBuffer)
|
|
1153
|
+
#define ArrowIsSharedBuffer NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowIsSharedBuffer)
|
|
1133
1154
|
#define ArrowErrorSet NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowErrorSet)
|
|
1134
1155
|
#define ArrowLayoutInit NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowLayoutInit)
|
|
1135
1156
|
#define ArrowDecimalSetDigits NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowDecimalSetDigits)
|
|
@@ -1179,6 +1200,7 @@ static inline void ArrowDecimalSetBytes(struct ArrowDecimal* decimal,
|
|
|
1179
1200
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowMetadataBuilderRemove)
|
|
1180
1201
|
#define ArrowSchemaViewInit NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSchemaViewInit)
|
|
1181
1202
|
#define ArrowSchemaToString NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSchemaToString)
|
|
1203
|
+
#define ArrowArrayIsInternal NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayIsInternal)
|
|
1182
1204
|
#define ArrowArrayInitFromType \
|
|
1183
1205
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayInitFromType)
|
|
1184
1206
|
#define ArrowArrayInitFromSchema \
|
|
@@ -1199,6 +1221,8 @@ static inline void ArrowDecimalSetBytes(struct ArrowDecimal* decimal,
|
|
|
1199
1221
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayFinishBuilding)
|
|
1200
1222
|
#define ArrowArrayFinishBuildingDefault \
|
|
1201
1223
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayFinishBuildingDefault)
|
|
1224
|
+
#define ArrowArrayMoveShared NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayMoveShared)
|
|
1225
|
+
#define ArrowArrayCloneShared NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayCloneShared)
|
|
1202
1226
|
#define ArrowArrayViewInitFromType \
|
|
1203
1227
|
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowArrayViewInitFromType)
|
|
1204
1228
|
#define ArrowArrayViewInitFromSchema \
|
|
@@ -1288,6 +1312,85 @@ NANOARROW_DLL struct ArrowBufferAllocator ArrowBufferDeallocator(
|
|
|
1288
1312
|
|
|
1289
1313
|
/// @}
|
|
1290
1314
|
|
|
1315
|
+
/// \defgroup nanoarrow-shared-buffer Shared buffers and arrays
|
|
1316
|
+
///
|
|
1317
|
+
/// The nanoarrow library implements two kinds of shared buffers: those backed by
|
|
1318
|
+
/// a reference-counted ArrowBuffer and those backed by a reference-counted ArrowArray.
|
|
1319
|
+
/// These are useful for building ArrowArrays using buffers without copying the bytes
|
|
1320
|
+
/// of the source. For example the IPC implementation uses shared buffers derived from an
|
|
1321
|
+
/// ArrowBuffer to avoid copying buffers from an IPC message, and the Shared buffers
|
|
1322
|
+
/// derived from arrays are used to make a safe shallow clone of an array.
|
|
1323
|
+
///
|
|
1324
|
+
/// Reference counts are implemented using C11 atomics and not necessarily thread safe
|
|
1325
|
+
/// on all platforms (notably, MSVC requires `/experimental:c11atomics`). Use
|
|
1326
|
+
/// ArrowSharedBufferIsThreadSafe() to check for thread safety if this is needed.
|
|
1327
|
+
///
|
|
1328
|
+
/// @{
|
|
1329
|
+
|
|
1330
|
+
/// \brief Initialize a shared buffer from an ArrowBuffer
|
|
1331
|
+
///
|
|
1332
|
+
/// If NANOARROW_OK is returned, shared is a reference-counted buffer that
|
|
1333
|
+
/// took ownership of src. The caller should release the shared buffer
|
|
1334
|
+
/// using ArrowBufferReset() when finished. The underlying data will persist
|
|
1335
|
+
/// until all clones have also been released.
|
|
1336
|
+
NANOARROW_DLL ArrowErrorCode ArrowSharedBufferInit(struct ArrowBuffer* shared,
|
|
1337
|
+
struct ArrowBuffer* src);
|
|
1338
|
+
|
|
1339
|
+
/// \brief Check for shared buffer thread safety
|
|
1340
|
+
///
|
|
1341
|
+
/// Thread-safe shared buffers require C11 and the stdatomic.h header.
|
|
1342
|
+
/// If either are unavailable, shared buffers are still possible but
|
|
1343
|
+
/// the resulting arrays must not be passed to other threads to be released.
|
|
1344
|
+
NANOARROW_DLL int ArrowSharedBufferIsThreadSafe(void);
|
|
1345
|
+
|
|
1346
|
+
/// \brief Check if a buffer is a shared buffer
|
|
1347
|
+
///
|
|
1348
|
+
/// Returns non-zero if buffer was created by ArrowSharedBufferInit() or
|
|
1349
|
+
/// obtained from ArrowSharedArrayBuffer().
|
|
1350
|
+
NANOARROW_DLL int ArrowIsSharedBuffer(struct ArrowBuffer* buffer);
|
|
1351
|
+
|
|
1352
|
+
/// \brief Clone a shared buffer, incrementing its reference count
|
|
1353
|
+
///
|
|
1354
|
+
/// This creates a new ArrowBuffer that shares the same underlying data with the
|
|
1355
|
+
/// original shared buffer. The reference count is incremented. Returns EINVAL
|
|
1356
|
+
/// if shared is not a shared buffer (i.e. ArrowIsSharedBuffer() returns false).
|
|
1357
|
+
NANOARROW_DLL ArrowErrorCode ArrowSharedBufferClone(struct ArrowBuffer* shared,
|
|
1358
|
+
struct ArrowBuffer* shared_out);
|
|
1359
|
+
|
|
1360
|
+
/// \brief An opaque handle to a shared, reference-counted ArrowArray
|
|
1361
|
+
struct ArrowSharedArray {
|
|
1362
|
+
void* private_data;
|
|
1363
|
+
};
|
|
1364
|
+
|
|
1365
|
+
/// \brief Initialize a shared array from an ArrowArray
|
|
1366
|
+
///
|
|
1367
|
+
/// Takes ownership of src (sets src->release to NULL). The shared array
|
|
1368
|
+
/// should be released with ArrowSharedArrayRelease() when all buffers have
|
|
1369
|
+
/// been extracted from the source. The original array will be released
|
|
1370
|
+
/// when all borrowed buffers have been released.
|
|
1371
|
+
NANOARROW_DLL ArrowErrorCode ArrowSharedArrayInit(struct ArrowSharedArray* shared,
|
|
1372
|
+
struct ArrowArray* src);
|
|
1373
|
+
|
|
1374
|
+
/// \brief Release the caller's reference to a shared array
|
|
1375
|
+
///
|
|
1376
|
+
/// Decrements the reference count. When no more references remain
|
|
1377
|
+
/// (including any buffers obtained via ArrowSharedArrayBuffer()),
|
|
1378
|
+
/// the underlying ArrowArray is released.
|
|
1379
|
+
NANOARROW_DLL void ArrowSharedArrayRelease(struct ArrowSharedArray* shared);
|
|
1380
|
+
|
|
1381
|
+
/// \brief Obtain a buffer from a shared array
|
|
1382
|
+
///
|
|
1383
|
+
/// Returns an ArrowBuffer that views buffer i of the underlying ArrowArray.
|
|
1384
|
+
/// If the source array was built with nanoarrow (i.e. ArrowArrayIsInternal()
|
|
1385
|
+
/// returns true), buffer sizes are known and propagated to the output.
|
|
1386
|
+
/// Otherwise the output buffer's size_bytes will be 0. The shared array's
|
|
1387
|
+
/// reference count is incremented. The returned buffer is compatible with
|
|
1388
|
+
/// ArrowSharedBufferClone().
|
|
1389
|
+
NANOARROW_DLL ArrowErrorCode ArrowSharedArrayBuffer(struct ArrowSharedArray* shared,
|
|
1390
|
+
int64_t i, struct ArrowBuffer* out);
|
|
1391
|
+
|
|
1392
|
+
/// @}
|
|
1393
|
+
|
|
1291
1394
|
/// \brief Move the contents of an src ArrowSchema into dst and set src->release to NULL
|
|
1292
1395
|
/// \ingroup nanoarrow-arrow-cdata
|
|
1293
1396
|
static inline void ArrowSchemaMove(struct ArrowSchema* src, struct ArrowSchema* dst);
|
|
@@ -2123,6 +2226,12 @@ static inline ArrowErrorCode ArrowArrayShrinkToFit(struct ArrowArray* array);
|
|
|
2123
2226
|
NANOARROW_DLL ArrowErrorCode ArrowArrayFinishBuildingDefault(struct ArrowArray* array,
|
|
2124
2227
|
struct ArrowError* error);
|
|
2125
2228
|
|
|
2229
|
+
/// \brief Check if an ArrowArray was allocated by nanoarrow
|
|
2230
|
+
///
|
|
2231
|
+
/// Returns non-zero if array was allocated using ArrowArrayInitFromType(),
|
|
2232
|
+
/// ArrowArrayInitFromSchema(), or ArrowArrayInitFromArrayView().
|
|
2233
|
+
NANOARROW_DLL int ArrowArrayIsInternal(struct ArrowArray* array);
|
|
2234
|
+
|
|
2126
2235
|
/// \brief Finish building an ArrowArray with explicit validation
|
|
2127
2236
|
///
|
|
2128
2237
|
/// Finish building with an explicit validation level. This could perform less validation
|
|
@@ -2134,6 +2243,28 @@ NANOARROW_DLL ArrowErrorCode ArrowArrayFinishBuilding(
|
|
|
2134
2243
|
struct ArrowArray* array, enum ArrowValidationLevel validation_level,
|
|
2135
2244
|
struct ArrowError* error);
|
|
2136
2245
|
|
|
2246
|
+
/// \brief Create a shared copy of an ArrowArray
|
|
2247
|
+
///
|
|
2248
|
+
/// Recursively converts array into a version where all buffers are
|
|
2249
|
+
/// reference-counted. On success, shared is a new ArrowArray whose buffers
|
|
2250
|
+
/// are backed by ArrowSharedArray references, and array is consumed
|
|
2251
|
+
/// (release set to NULL). The resulting shared array can be safely moved
|
|
2252
|
+
/// or have its buffers cloned via ArrowSharedBufferClone(). On error,
|
|
2253
|
+
/// (e.g., failure to allocate a copy of a buffer), the input array is
|
|
2254
|
+
/// released as it may have been partially moved at the point the error
|
|
2255
|
+
/// occurs.
|
|
2256
|
+
NANOARROW_DLL ArrowErrorCode ArrowArrayMoveShared(struct ArrowArray* array,
|
|
2257
|
+
struct ArrowArray* shared);
|
|
2258
|
+
|
|
2259
|
+
/// \brief Clone a shared ArrowArray
|
|
2260
|
+
///
|
|
2261
|
+
/// Creates a new ArrowArray whose buffers share the same underlying data as
|
|
2262
|
+
/// the source shared array. The source must have been created by
|
|
2263
|
+
/// ArrowArrayMoveShared() (i.e. all buffers are reference-counted).
|
|
2264
|
+
/// Returns EINVAL if shared is not a shared array.
|
|
2265
|
+
NANOARROW_DLL ArrowErrorCode ArrowArrayCloneShared(struct ArrowArray* shared,
|
|
2266
|
+
struct ArrowArray* array);
|
|
2267
|
+
|
|
2137
2268
|
/// @}
|
|
2138
2269
|
|
|
2139
2270
|
/// \defgroup nanoarrow-array-view Reading arrays
|
data/ext/nanoarrow/nanoarrow.c
CHANGED
|
@@ -22,6 +22,29 @@
|
|
|
22
22
|
#include <stdlib.h>
|
|
23
23
|
#include <string.h>
|
|
24
24
|
|
|
25
|
+
// For thread safe shared buffers we need C11 + stdatomic.h
|
|
26
|
+
// Can compile with -DNANOARROW_USE_STDATOMIC=0 or 1 to override
|
|
27
|
+
// automatic detection
|
|
28
|
+
#if !defined(NANOARROW_USE_STDATOMIC)
|
|
29
|
+
#define NANOARROW_USE_STDATOMIC 0
|
|
30
|
+
|
|
31
|
+
// Check for C11
|
|
32
|
+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
|
33
|
+
|
|
34
|
+
// Check for GCC 4.8, which doesn't include stdatomic.h but does
|
|
35
|
+
// not define __STDC_NO_ATOMICS__
|
|
36
|
+
#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ >= 5
|
|
37
|
+
|
|
38
|
+
#if !defined(__STDC_NO_ATOMICS__)
|
|
39
|
+
#include <stdatomic.h>
|
|
40
|
+
#undef NANOARROW_USE_STDATOMIC
|
|
41
|
+
#define NANOARROW_USE_STDATOMIC 1
|
|
42
|
+
#endif
|
|
43
|
+
#endif
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
#endif
|
|
47
|
+
|
|
25
48
|
#include "nanoarrow/nanoarrow.h"
|
|
26
49
|
|
|
27
50
|
const char* ArrowNanoarrowVersion(void) { return NANOARROW_VERSION; }
|
|
@@ -276,6 +299,225 @@ struct ArrowBufferAllocator ArrowBufferDeallocator(
|
|
|
276
299
|
return allocator;
|
|
277
300
|
}
|
|
278
301
|
|
|
302
|
+
#if NANOARROW_USE_STDATOMIC
|
|
303
|
+
struct ArrowSharedBufferPrivate {
|
|
304
|
+
struct ArrowBuffer src;
|
|
305
|
+
atomic_long reference_count;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
static int64_t ArrowSharedBufferUpdate(struct ArrowSharedBufferPrivate* private_data,
|
|
309
|
+
int delta) {
|
|
310
|
+
int64_t old_count = atomic_fetch_add(&private_data->reference_count, delta);
|
|
311
|
+
return old_count + delta;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
static void ArrowSharedBufferSet(struct ArrowSharedBufferPrivate* private_data,
|
|
315
|
+
int64_t count) {
|
|
316
|
+
atomic_store(&private_data->reference_count, count);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
int ArrowSharedBufferIsThreadSafe(void) { return 1; }
|
|
320
|
+
|
|
321
|
+
struct ArrowSharedArrayPrivate {
|
|
322
|
+
struct ArrowArray src;
|
|
323
|
+
atomic_long reference_count;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
static int64_t ArrowSharedArrayUpdate(struct ArrowSharedArrayPrivate* private_data,
|
|
327
|
+
int delta) {
|
|
328
|
+
int64_t old_count = atomic_fetch_add(&private_data->reference_count, delta);
|
|
329
|
+
return old_count + delta;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
static void ArrowSharedArraySet(struct ArrowSharedArrayPrivate* private_data,
|
|
333
|
+
int64_t count) {
|
|
334
|
+
atomic_store(&private_data->reference_count, count);
|
|
335
|
+
}
|
|
336
|
+
#else
|
|
337
|
+
struct ArrowSharedBufferPrivate {
|
|
338
|
+
struct ArrowBuffer src;
|
|
339
|
+
int64_t reference_count;
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
static int64_t ArrowSharedBufferUpdate(struct ArrowSharedBufferPrivate* private_data,
|
|
343
|
+
int delta) {
|
|
344
|
+
private_data->reference_count += delta;
|
|
345
|
+
return private_data->reference_count;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
static void ArrowSharedBufferSet(struct ArrowSharedBufferPrivate* private_data,
|
|
349
|
+
int64_t count) {
|
|
350
|
+
private_data->reference_count = count;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
int ArrowSharedBufferIsThreadSafe(void) { return 0; }
|
|
354
|
+
|
|
355
|
+
struct ArrowSharedArrayPrivate {
|
|
356
|
+
struct ArrowArray src;
|
|
357
|
+
int64_t reference_count;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
static int64_t ArrowSharedArrayUpdate(struct ArrowSharedArrayPrivate* private_data,
|
|
361
|
+
int delta) {
|
|
362
|
+
private_data->reference_count += delta;
|
|
363
|
+
return private_data->reference_count;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
static void ArrowSharedArraySet(struct ArrowSharedArrayPrivate* private_data,
|
|
367
|
+
int64_t count) {
|
|
368
|
+
private_data->reference_count = count;
|
|
369
|
+
}
|
|
370
|
+
#endif
|
|
371
|
+
|
|
372
|
+
static void ArrowSharedBufferFree(struct ArrowBufferAllocator* allocator, uint8_t* ptr,
|
|
373
|
+
int64_t size) {
|
|
374
|
+
NANOARROW_UNUSED(allocator);
|
|
375
|
+
NANOARROW_UNUSED(ptr);
|
|
376
|
+
NANOARROW_UNUSED(size);
|
|
377
|
+
|
|
378
|
+
struct ArrowSharedBufferPrivate* private_data =
|
|
379
|
+
(struct ArrowSharedBufferPrivate*)allocator->private_data;
|
|
380
|
+
|
|
381
|
+
if (ArrowSharedBufferUpdate(private_data, -1) == 0) {
|
|
382
|
+
ArrowBufferReset(&private_data->src);
|
|
383
|
+
ArrowFree(private_data);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
static void ArrowSharedArrayBufferFree(struct ArrowBufferAllocator* allocator,
|
|
388
|
+
uint8_t* ptr, int64_t size) {
|
|
389
|
+
NANOARROW_UNUSED(ptr);
|
|
390
|
+
NANOARROW_UNUSED(size);
|
|
391
|
+
|
|
392
|
+
struct ArrowSharedArrayPrivate* private_data =
|
|
393
|
+
(struct ArrowSharedArrayPrivate*)allocator->private_data;
|
|
394
|
+
|
|
395
|
+
if (ArrowSharedArrayUpdate(private_data, -1) == 0) {
|
|
396
|
+
if (private_data->src.release != NULL) {
|
|
397
|
+
ArrowArrayRelease(&private_data->src);
|
|
398
|
+
}
|
|
399
|
+
ArrowFree(private_data);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
ArrowErrorCode ArrowSharedBufferInit(struct ArrowBuffer* shared,
|
|
404
|
+
struct ArrowBuffer* src) {
|
|
405
|
+
if (src->data == NULL) {
|
|
406
|
+
ArrowBufferMove(src, shared);
|
|
407
|
+
return NANOARROW_OK;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
struct ArrowSharedBufferPrivate* private_data =
|
|
411
|
+
(struct ArrowSharedBufferPrivate*)ArrowMalloc(
|
|
412
|
+
sizeof(struct ArrowSharedBufferPrivate));
|
|
413
|
+
if (private_data == NULL) {
|
|
414
|
+
return ENOMEM;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
ArrowBufferMove(src, &private_data->src);
|
|
418
|
+
ArrowSharedBufferSet(private_data, 1);
|
|
419
|
+
|
|
420
|
+
ArrowBufferInit(shared);
|
|
421
|
+
shared->data = private_data->src.data;
|
|
422
|
+
shared->size_bytes = private_data->src.size_bytes;
|
|
423
|
+
// Don't expose any extra capcity from src so that any calls to ArrowBufferAppend
|
|
424
|
+
// on this buffer will fail.
|
|
425
|
+
shared->capacity_bytes = private_data->src.size_bytes;
|
|
426
|
+
shared->allocator = ArrowBufferDeallocator(&ArrowSharedBufferFree, private_data);
|
|
427
|
+
return NANOARROW_OK;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
int ArrowIsSharedBuffer(struct ArrowBuffer* buffer) {
|
|
431
|
+
return buffer->allocator.free == &ArrowSharedBufferFree ||
|
|
432
|
+
buffer->allocator.free == &ArrowSharedArrayBufferFree;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
ArrowErrorCode ArrowSharedBufferClone(struct ArrowBuffer* shared,
|
|
436
|
+
struct ArrowBuffer* shared_out) {
|
|
437
|
+
// If the buffer has no data, initialize an empty buffer
|
|
438
|
+
if (shared->data == NULL) {
|
|
439
|
+
ArrowBufferInit(shared_out);
|
|
440
|
+
return NANOARROW_OK;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (shared->allocator.free == &ArrowSharedBufferFree) {
|
|
444
|
+
struct ArrowSharedBufferPrivate* private_data =
|
|
445
|
+
(struct ArrowSharedBufferPrivate*)shared->allocator.private_data;
|
|
446
|
+
ArrowSharedBufferUpdate(private_data, 1);
|
|
447
|
+
memcpy(shared_out, shared, sizeof(struct ArrowBuffer));
|
|
448
|
+
return NANOARROW_OK;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (shared->allocator.free == &ArrowSharedArrayBufferFree) {
|
|
452
|
+
struct ArrowSharedArrayPrivate* private_data =
|
|
453
|
+
(struct ArrowSharedArrayPrivate*)shared->allocator.private_data;
|
|
454
|
+
ArrowSharedArrayUpdate(private_data, 1);
|
|
455
|
+
memcpy(shared_out, shared, sizeof(struct ArrowBuffer));
|
|
456
|
+
return NANOARROW_OK;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return EINVAL;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
ArrowErrorCode ArrowSharedArrayInit(struct ArrowSharedArray* shared,
|
|
463
|
+
struct ArrowArray* src) {
|
|
464
|
+
struct ArrowSharedArrayPrivate* private_data =
|
|
465
|
+
(struct ArrowSharedArrayPrivate*)ArrowMalloc(
|
|
466
|
+
sizeof(struct ArrowSharedArrayPrivate));
|
|
467
|
+
if (private_data == NULL) {
|
|
468
|
+
return ENOMEM;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
ArrowArrayMove(src, &private_data->src);
|
|
472
|
+
ArrowSharedArraySet(private_data, 1);
|
|
473
|
+
shared->private_data = private_data;
|
|
474
|
+
return NANOARROW_OK;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
void ArrowSharedArrayRelease(struct ArrowSharedArray* shared) {
|
|
478
|
+
if (shared->private_data == NULL) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
struct ArrowSharedArrayPrivate* private_data =
|
|
483
|
+
(struct ArrowSharedArrayPrivate*)shared->private_data;
|
|
484
|
+
|
|
485
|
+
if (ArrowSharedArrayUpdate(private_data, -1) == 0) {
|
|
486
|
+
if (private_data->src.release != NULL) {
|
|
487
|
+
ArrowArrayRelease(&private_data->src);
|
|
488
|
+
}
|
|
489
|
+
ArrowFree(private_data);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
shared->private_data = NULL;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
ArrowErrorCode ArrowSharedArrayBuffer(struct ArrowSharedArray* shared, int64_t i,
|
|
496
|
+
struct ArrowBuffer* out) {
|
|
497
|
+
struct ArrowSharedArrayPrivate* private_data =
|
|
498
|
+
(struct ArrowSharedArrayPrivate*)shared->private_data;
|
|
499
|
+
NANOARROW_DCHECK(i >= 0 && i < private_data->src.n_buffers);
|
|
500
|
+
|
|
501
|
+
ArrowSharedArrayUpdate(private_data, 1);
|
|
502
|
+
ArrowBufferInit(out);
|
|
503
|
+
|
|
504
|
+
if (ArrowArrayIsInternal(&private_data->src)) {
|
|
505
|
+
// The source array was built with nanoarrow, so we can get buffer size info
|
|
506
|
+
struct ArrowBuffer* src = ArrowArrayBuffer(&private_data->src, i);
|
|
507
|
+
out->data = src->data;
|
|
508
|
+
out->size_bytes = src->size_bytes;
|
|
509
|
+
out->capacity_bytes = src->size_bytes;
|
|
510
|
+
} else {
|
|
511
|
+
// Generic C Data Interface array: buffer sizes are not known
|
|
512
|
+
out->data = (uint8_t*)private_data->src.buffers[i];
|
|
513
|
+
out->size_bytes = 0;
|
|
514
|
+
out->capacity_bytes = 0;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
out->allocator = ArrowBufferDeallocator(&ArrowSharedArrayBufferFree, private_data);
|
|
518
|
+
return NANOARROW_OK;
|
|
519
|
+
}
|
|
520
|
+
|
|
279
521
|
static const int kInt32DecimalDigits = 9;
|
|
280
522
|
|
|
281
523
|
static const uint64_t kUInt32PowersOfTen[] = {
|
|
@@ -578,6 +820,7 @@ ArrowErrorCode ArrowDecimalAppendStringToBuffer(const struct ArrowDecimal* decim
|
|
|
578
820
|
|
|
579
821
|
#include <errno.h>
|
|
580
822
|
#include <inttypes.h>
|
|
823
|
+
#include <stdarg.h>
|
|
581
824
|
#include <stdio.h>
|
|
582
825
|
#include <stdlib.h>
|
|
583
826
|
#include <string.h>
|
|
@@ -1931,47 +2174,34 @@ ArrowErrorCode ArrowSchemaViewInit(struct ArrowSchemaView* schema_view,
|
|
|
1931
2174
|
return NANOARROW_OK;
|
|
1932
2175
|
}
|
|
1933
2176
|
|
|
1934
|
-
static
|
|
1935
|
-
char*
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
case NANOARROW_TYPE_TIME32:
|
|
1948
|
-
case NANOARROW_TYPE_TIME64:
|
|
1949
|
-
case NANOARROW_TYPE_DURATION:
|
|
1950
|
-
return snprintf(out, n, "%s('%s')", type_string,
|
|
1951
|
-
ArrowTimeUnitString(schema_view->time_unit));
|
|
1952
|
-
case NANOARROW_TYPE_FIXED_SIZE_BINARY:
|
|
1953
|
-
case NANOARROW_TYPE_FIXED_SIZE_LIST:
|
|
1954
|
-
return snprintf(out, n, "%s(%" PRId32 ")", type_string, schema_view->fixed_size);
|
|
1955
|
-
case NANOARROW_TYPE_SPARSE_UNION:
|
|
1956
|
-
case NANOARROW_TYPE_DENSE_UNION:
|
|
1957
|
-
return snprintf(out, n, "%s([%s])", type_string, schema_view->union_type_ids);
|
|
1958
|
-
default:
|
|
1959
|
-
return snprintf(out, n, "%s", type_string);
|
|
2177
|
+
static inline void ArrowSchemaToStringSNPrintF(char** out, int64_t* n_remaining,
|
|
2178
|
+
int64_t* n_chars, const char* fmt, ...) {
|
|
2179
|
+
// With _FORTIFY_SOURCE=3, vsnprintf on a null output warns, so ensure we never pass
|
|
2180
|
+
// a NULL to vsnprintf
|
|
2181
|
+
char tmp_not_null[1];
|
|
2182
|
+
char* out_not_null;
|
|
2183
|
+
size_t out_not_null_size;
|
|
2184
|
+
if (*out == NULL) {
|
|
2185
|
+
out_not_null = tmp_not_null;
|
|
2186
|
+
out_not_null_size = sizeof(tmp_not_null);
|
|
2187
|
+
} else {
|
|
2188
|
+
out_not_null = *out;
|
|
2189
|
+
out_not_null_size = (size_t)*n_remaining;
|
|
1960
2190
|
}
|
|
1961
|
-
}
|
|
1962
2191
|
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2192
|
+
va_list args;
|
|
2193
|
+
va_start(args, fmt);
|
|
2194
|
+
int n_chars_last = vsnprintf(out_not_null, out_not_null_size, fmt, args);
|
|
2195
|
+
va_end(args);
|
|
2196
|
+
|
|
1967
2197
|
// In the unlikely snprintf() returning a negative value (encoding error),
|
|
1968
2198
|
// ensure the result won't cause an out-of-bounds access.
|
|
1969
2199
|
if (n_chars_last < 0) {
|
|
1970
2200
|
n_chars_last = 0;
|
|
1971
2201
|
}
|
|
1972
2202
|
|
|
1973
|
-
*n_chars += n_chars_last;
|
|
1974
2203
|
*n_remaining -= n_chars_last;
|
|
2204
|
+
*n_chars += n_chars_last;
|
|
1975
2205
|
|
|
1976
2206
|
// n_remaining is never less than 0
|
|
1977
2207
|
if (*n_remaining < 0) {
|
|
@@ -1984,93 +2214,134 @@ static inline void ArrowToStringLogChars(char** out, int64_t n_chars_last,
|
|
|
1984
2214
|
}
|
|
1985
2215
|
}
|
|
1986
2216
|
|
|
1987
|
-
|
|
1988
|
-
|
|
2217
|
+
static void ArrowSchemaTypeToStringInternal(struct ArrowSchemaView* schema_view,
|
|
2218
|
+
char** out, int64_t* n_remaining,
|
|
2219
|
+
int64_t* n_chars) {
|
|
2220
|
+
const char* type_string = ArrowTypeString(schema_view->type);
|
|
2221
|
+
switch (schema_view->type) {
|
|
2222
|
+
case NANOARROW_TYPE_DECIMAL32:
|
|
2223
|
+
case NANOARROW_TYPE_DECIMAL64:
|
|
2224
|
+
case NANOARROW_TYPE_DECIMAL128:
|
|
2225
|
+
case NANOARROW_TYPE_DECIMAL256:
|
|
2226
|
+
ArrowSchemaToStringSNPrintF(
|
|
2227
|
+
out, n_remaining, n_chars, "%s(%" PRId32 ", %" PRId32 ")", type_string,
|
|
2228
|
+
schema_view->decimal_precision, schema_view->decimal_scale);
|
|
2229
|
+
return;
|
|
2230
|
+
case NANOARROW_TYPE_TIMESTAMP:
|
|
2231
|
+
ArrowSchemaToStringSNPrintF(
|
|
2232
|
+
out, n_remaining, n_chars, "%s('%s', '%s')", type_string,
|
|
2233
|
+
ArrowTimeUnitString(schema_view->time_unit), schema_view->timezone);
|
|
2234
|
+
return;
|
|
2235
|
+
case NANOARROW_TYPE_TIME32:
|
|
2236
|
+
case NANOARROW_TYPE_TIME64:
|
|
2237
|
+
case NANOARROW_TYPE_DURATION:
|
|
2238
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "%s('%s')", type_string,
|
|
2239
|
+
ArrowTimeUnitString(schema_view->time_unit));
|
|
2240
|
+
return;
|
|
2241
|
+
case NANOARROW_TYPE_FIXED_SIZE_BINARY:
|
|
2242
|
+
case NANOARROW_TYPE_FIXED_SIZE_LIST:
|
|
2243
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "%s(%" PRId32 ")",
|
|
2244
|
+
type_string, schema_view->fixed_size);
|
|
2245
|
+
return;
|
|
2246
|
+
case NANOARROW_TYPE_SPARSE_UNION:
|
|
2247
|
+
case NANOARROW_TYPE_DENSE_UNION:
|
|
2248
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "%s([%s])", type_string,
|
|
2249
|
+
schema_view->union_type_ids);
|
|
2250
|
+
return;
|
|
2251
|
+
default:
|
|
2252
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "%s", type_string);
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
static void ArrowSchemaToStringInternal(const struct ArrowSchema* schema, char** out,
|
|
2258
|
+
int64_t* n_remaining, int64_t* n_chars,
|
|
2259
|
+
char recursive) {
|
|
1989
2260
|
if (schema == NULL) {
|
|
1990
|
-
|
|
2261
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "[invalid: pointer is null]");
|
|
2262
|
+
return;
|
|
1991
2263
|
}
|
|
1992
2264
|
|
|
1993
2265
|
if (schema->release == NULL) {
|
|
1994
|
-
|
|
2266
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars,
|
|
2267
|
+
"[invalid: schema is released]");
|
|
2268
|
+
return;
|
|
1995
2269
|
}
|
|
1996
2270
|
|
|
1997
2271
|
struct ArrowSchemaView schema_view;
|
|
1998
2272
|
struct ArrowError error;
|
|
1999
2273
|
|
|
2000
2274
|
if (ArrowSchemaViewInit(&schema_view, schema, &error) != NANOARROW_OK) {
|
|
2001
|
-
|
|
2275
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "[invalid: %s]",
|
|
2276
|
+
ArrowErrorMessage(&error));
|
|
2277
|
+
return;
|
|
2002
2278
|
}
|
|
2003
2279
|
|
|
2004
2280
|
// Extension type and dictionary should include both the top-level type
|
|
2005
2281
|
// and the storage type.
|
|
2006
2282
|
int is_extension = schema_view.extension_name.size_bytes > 0;
|
|
2007
2283
|
int is_dictionary = schema->dictionary != NULL;
|
|
2008
|
-
int64_t n_chars = 0;
|
|
2009
|
-
int64_t n_chars_last = 0;
|
|
2010
2284
|
|
|
2011
2285
|
// Uncommon but not technically impossible that both are true
|
|
2012
2286
|
if (is_extension && is_dictionary) {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2287
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "%.*s{dictionary(%s)<",
|
|
2288
|
+
(int)schema_view.extension_name.size_bytes,
|
|
2289
|
+
schema_view.extension_name.data,
|
|
2290
|
+
ArrowTypeString(schema_view.storage_type));
|
|
2016
2291
|
} else if (is_extension) {
|
|
2017
|
-
|
|
2018
|
-
|
|
2292
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "%.*s{",
|
|
2293
|
+
(int)schema_view.extension_name.size_bytes,
|
|
2294
|
+
schema_view.extension_name.data);
|
|
2019
2295
|
} else if (is_dictionary) {
|
|
2020
|
-
|
|
2021
|
-
|
|
2296
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "dictionary(%s)<",
|
|
2297
|
+
ArrowTypeString(schema_view.storage_type));
|
|
2022
2298
|
}
|
|
2023
2299
|
|
|
2024
|
-
ArrowToStringLogChars(&out, n_chars_last, &n, &n_chars);
|
|
2025
|
-
|
|
2026
2300
|
if (!is_dictionary) {
|
|
2027
|
-
|
|
2301
|
+
ArrowSchemaTypeToStringInternal(&schema_view, out, n_remaining, n_chars);
|
|
2028
2302
|
} else {
|
|
2029
|
-
|
|
2303
|
+
ArrowSchemaToStringInternal(schema->dictionary, out, n_remaining, n_chars, recursive);
|
|
2030
2304
|
}
|
|
2031
2305
|
|
|
2032
|
-
ArrowToStringLogChars(&out, n_chars_last, &n, &n_chars);
|
|
2033
|
-
|
|
2034
2306
|
if (recursive && schema->format[0] == '+') {
|
|
2035
|
-
|
|
2036
|
-
ArrowToStringLogChars(&out, n_chars_last, &n, &n_chars);
|
|
2307
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "<");
|
|
2037
2308
|
|
|
2038
2309
|
for (int64_t i = 0; i < schema->n_children; i++) {
|
|
2039
2310
|
if (i > 0) {
|
|
2040
|
-
|
|
2041
|
-
ArrowToStringLogChars(&out, n_chars_last, &n, &n_chars);
|
|
2311
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, ", ");
|
|
2042
2312
|
}
|
|
2043
2313
|
|
|
2044
2314
|
// ArrowSchemaToStringInternal() will validate the child and print the error,
|
|
2045
2315
|
// but we need the name first
|
|
2046
2316
|
if (schema->children[i] != NULL && schema->children[i]->release != NULL &&
|
|
2047
2317
|
schema->children[i]->name != NULL) {
|
|
2048
|
-
|
|
2049
|
-
|
|
2318
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars,
|
|
2319
|
+
"%s: ", schema->children[i]->name);
|
|
2050
2320
|
}
|
|
2051
2321
|
|
|
2052
|
-
|
|
2053
|
-
|
|
2322
|
+
ArrowSchemaToStringInternal(schema->children[i], out, n_remaining, n_chars,
|
|
2323
|
+
recursive);
|
|
2054
2324
|
}
|
|
2055
2325
|
|
|
2056
|
-
|
|
2057
|
-
ArrowToStringLogChars(&out, n_chars_last, &n, &n_chars);
|
|
2326
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, ">");
|
|
2058
2327
|
}
|
|
2059
2328
|
|
|
2060
2329
|
if (is_extension && is_dictionary) {
|
|
2061
|
-
|
|
2330
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, ">}");
|
|
2062
2331
|
} else if (is_extension) {
|
|
2063
|
-
|
|
2332
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, "}");
|
|
2064
2333
|
} else if (is_dictionary) {
|
|
2065
|
-
|
|
2334
|
+
ArrowSchemaToStringSNPrintF(out, n_remaining, n_chars, ">");
|
|
2066
2335
|
}
|
|
2336
|
+
}
|
|
2067
2337
|
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2338
|
+
int64_t ArrowSchemaToString(const struct ArrowSchema* schema, char* out, int64_t n,
|
|
2339
|
+
char recursive) {
|
|
2340
|
+
NANOARROW_DCHECK(n >= 0);
|
|
2341
|
+
NANOARROW_DCHECK(out != NULL || n == 0);
|
|
2342
|
+
int64_t n_chars = 0;
|
|
2343
|
+
ArrowSchemaToStringInternal(schema, &out, &n, &n_chars, recursive);
|
|
2344
|
+
return n_chars;
|
|
2074
2345
|
}
|
|
2075
2346
|
|
|
2076
2347
|
ArrowErrorCode ArrowMetadataReaderInit(struct ArrowMetadataReader* reader,
|
|
@@ -2363,7 +2634,7 @@ static void ArrowArrayReleaseInternal(struct ArrowArray* array) {
|
|
|
2363
2634
|
array->release = NULL;
|
|
2364
2635
|
}
|
|
2365
2636
|
|
|
2366
|
-
|
|
2637
|
+
int ArrowArrayIsInternal(struct ArrowArray* array) {
|
|
2367
2638
|
return array->release == &ArrowArrayReleaseInternal;
|
|
2368
2639
|
}
|
|
2369
2640
|
|
|
@@ -2858,6 +3129,172 @@ ArrowErrorCode ArrowArrayFinishBuildingDefault(struct ArrowArray* array,
|
|
|
2858
3129
|
return ArrowArrayFinishBuilding(array, NANOARROW_VALIDATION_LEVEL_DEFAULT, error);
|
|
2859
3130
|
}
|
|
2860
3131
|
|
|
3132
|
+
static int ArrowArrayIsShared(struct ArrowArray* array) {
|
|
3133
|
+
if (!ArrowArrayIsInternal(array)) {
|
|
3134
|
+
return 0;
|
|
3135
|
+
}
|
|
3136
|
+
|
|
3137
|
+
for (int64_t i = 0; i < array->n_buffers; i++) {
|
|
3138
|
+
struct ArrowBuffer* buffer = ArrowArrayBuffer(array, i);
|
|
3139
|
+
if (buffer->data != NULL && !ArrowIsSharedBuffer(buffer)) {
|
|
3140
|
+
return 0;
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3144
|
+
for (int64_t i = 0; i < array->n_children; i++) {
|
|
3145
|
+
if (!ArrowArrayIsShared(array->children[i])) {
|
|
3146
|
+
return 0;
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
|
|
3150
|
+
if (array->dictionary != NULL && !ArrowArrayIsShared(array->dictionary)) {
|
|
3151
|
+
return 0;
|
|
3152
|
+
}
|
|
3153
|
+
|
|
3154
|
+
return 1;
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3157
|
+
static ArrowErrorCode ArrowArrayMoveSharedInternal(struct ArrowArray* src,
|
|
3158
|
+
struct ArrowArray* dst) {
|
|
3159
|
+
if (ArrowArrayIsShared(src)) {
|
|
3160
|
+
ArrowArrayMove(src, dst);
|
|
3161
|
+
return NANOARROW_OK;
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3164
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayInitFromType(dst, NANOARROW_TYPE_UNINITIALIZED));
|
|
3165
|
+
|
|
3166
|
+
// Allocate children and move source children to dst children
|
|
3167
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayAllocateChildren(dst, src->n_children));
|
|
3168
|
+
for (int64_t i = 0; i < src->n_children; i++) {
|
|
3169
|
+
NANOARROW_RETURN_NOT_OK(
|
|
3170
|
+
ArrowArrayMoveSharedInternal(src->children[i], dst->children[i]));
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
// Allocate dictionary if needed and move source dictionary to dst dictionary
|
|
3174
|
+
if (src->dictionary != NULL) {
|
|
3175
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayAllocateDictionary(dst));
|
|
3176
|
+
NANOARROW_RETURN_NOT_OK(
|
|
3177
|
+
ArrowArrayMoveSharedInternal(src->dictionary, dst->dictionary));
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
// We might need some more buffers if we are shallowly copying a string/binary view
|
|
3181
|
+
if (src->n_buffers > 3) {
|
|
3182
|
+
if (src->n_buffers > INT_MAX) {
|
|
3183
|
+
return EINVAL;
|
|
3184
|
+
}
|
|
3185
|
+
|
|
3186
|
+
NANOARROW_RETURN_NOT_OK(
|
|
3187
|
+
ArrowArrayAddVariadicBuffers(dst, (int32_t)src->n_buffers - 3));
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
// Move src into a shared array and set dst's buffers using the ref-counted version
|
|
3191
|
+
struct ArrowSharedArray shared_array;
|
|
3192
|
+
NANOARROW_RETURN_NOT_OK(ArrowSharedArrayInit(&shared_array, src));
|
|
3193
|
+
|
|
3194
|
+
for (int64_t i = 0; i < src->n_buffers; i++) {
|
|
3195
|
+
struct ArrowBuffer* dst_buffer = ArrowArrayBuffer(dst, i);
|
|
3196
|
+
ArrowErrorCode result = ArrowSharedArrayBuffer(&shared_array, i, dst_buffer);
|
|
3197
|
+
if (result != NANOARROW_OK) {
|
|
3198
|
+
ArrowSharedArrayRelease(&shared_array);
|
|
3199
|
+
return result;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
|
|
3203
|
+
ArrowSharedArrayRelease(&shared_array);
|
|
3204
|
+
|
|
3205
|
+
dst->n_buffers = src->n_buffers;
|
|
3206
|
+
dst->length = src->length;
|
|
3207
|
+
dst->null_count = src->null_count;
|
|
3208
|
+
dst->offset = src->offset;
|
|
3209
|
+
|
|
3210
|
+
// Flush internal buffer pointers to array->buffers
|
|
3211
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayFlushInternalPointers(dst));
|
|
3212
|
+
|
|
3213
|
+
return NANOARROW_OK;
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
static ArrowErrorCode ArrowArrayCloneSharedInternal(struct ArrowArray* src,
|
|
3217
|
+
struct ArrowArray* dst) {
|
|
3218
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayInitFromType(dst, NANOARROW_TYPE_UNINITIALIZED));
|
|
3219
|
+
|
|
3220
|
+
// Allocate children and clone source children to dst children
|
|
3221
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayAllocateChildren(dst, src->n_children));
|
|
3222
|
+
for (int64_t i = 0; i < src->n_children; i++) {
|
|
3223
|
+
NANOARROW_RETURN_NOT_OK(
|
|
3224
|
+
ArrowArrayCloneSharedInternal(src->children[i], dst->children[i]));
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
// Allocate dictionary if needed and clone source dictionary to dst dictionary
|
|
3228
|
+
if (src->dictionary != NULL) {
|
|
3229
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayAllocateDictionary(dst));
|
|
3230
|
+
NANOARROW_RETURN_NOT_OK(
|
|
3231
|
+
ArrowArrayCloneSharedInternal(src->dictionary, dst->dictionary));
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
// We might need some more buffers if we are shallowly copying a string/binary view
|
|
3235
|
+
if (src->n_buffers > 3) {
|
|
3236
|
+
if (src->n_buffers > INT_MAX) {
|
|
3237
|
+
return EINVAL;
|
|
3238
|
+
}
|
|
3239
|
+
|
|
3240
|
+
NANOARROW_RETURN_NOT_OK(
|
|
3241
|
+
ArrowArrayAddVariadicBuffers(dst, (int32_t)src->n_buffers - 3));
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
for (int64_t i = 0; i < src->n_buffers; i++) {
|
|
3245
|
+
struct ArrowBuffer* src_buffer = ArrowArrayBuffer(src, i);
|
|
3246
|
+
struct ArrowBuffer* dst_buffer = ArrowArrayBuffer(dst, i);
|
|
3247
|
+
NANOARROW_RETURN_NOT_OK(ArrowSharedBufferClone(src_buffer, dst_buffer));
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
dst->n_buffers = src->n_buffers;
|
|
3251
|
+
dst->length = src->length;
|
|
3252
|
+
dst->null_count = src->null_count;
|
|
3253
|
+
dst->offset = src->offset;
|
|
3254
|
+
|
|
3255
|
+
// Flush internal buffer pointers to array->buffers
|
|
3256
|
+
NANOARROW_RETURN_NOT_OK(ArrowArrayFlushInternalPointers(dst));
|
|
3257
|
+
|
|
3258
|
+
return NANOARROW_OK;
|
|
3259
|
+
}
|
|
3260
|
+
|
|
3261
|
+
ArrowErrorCode ArrowArrayMoveShared(struct ArrowArray* array, struct ArrowArray* shared) {
|
|
3262
|
+
struct ArrowArray tmp;
|
|
3263
|
+
tmp.release = NULL;
|
|
3264
|
+
ArrowErrorCode result = ArrowArrayMoveSharedInternal(array, shared);
|
|
3265
|
+
if (result != NANOARROW_OK) {
|
|
3266
|
+
// On failure, release the temporary output
|
|
3267
|
+
if (tmp.release != NULL) {
|
|
3268
|
+
ArrowArrayRelease(&tmp);
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
// Because this operation may have partially moved the input array at this point
|
|
3272
|
+
// we also have to release it on failure to be predictable. These failures are
|
|
3273
|
+
// usually failed heap allocations and are difficult to trigger in practice.
|
|
3274
|
+
if (array->release != NULL) {
|
|
3275
|
+
ArrowArrayRelease(array);
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
return result;
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
ArrowErrorCode ArrowArrayCloneShared(struct ArrowArray* shared,
|
|
3283
|
+
struct ArrowArray* array) {
|
|
3284
|
+
if (!ArrowArrayIsShared(shared)) {
|
|
3285
|
+
return EINVAL;
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
struct ArrowArray tmp;
|
|
3289
|
+
tmp.release = NULL;
|
|
3290
|
+
ArrowErrorCode result = ArrowArrayCloneSharedInternal(shared, array);
|
|
3291
|
+
if (result != NANOARROW_OK && tmp.release != NULL) {
|
|
3292
|
+
ArrowArrayRelease(&tmp);
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3295
|
+
return result;
|
|
3296
|
+
}
|
|
3297
|
+
|
|
2861
3298
|
void ArrowArrayViewInitFromType(struct ArrowArrayView* array_view,
|
|
2862
3299
|
enum ArrowType storage_type) {
|
|
2863
3300
|
memset(array_view, 0, sizeof(struct ArrowArrayView));
|
|
@@ -3803,10 +4240,26 @@ static int ArrowArrayViewValidateFull(struct ArrowArrayView* array_view,
|
|
|
3803
4240
|
NANOARROW_RETURN_NOT_OK(ArrowArrayViewValidateFull(array_view->children[i], error));
|
|
3804
4241
|
}
|
|
3805
4242
|
|
|
3806
|
-
// Dictionary validation
|
|
4243
|
+
// Dictionary index validation
|
|
3807
4244
|
if (array_view->dictionary != NULL) {
|
|
3808
4245
|
NANOARROW_RETURN_NOT_OK(ArrowArrayViewValidateFull(array_view->dictionary, error));
|
|
3809
|
-
|
|
4246
|
+
|
|
4247
|
+
// Validate that all non-null indices are within the dictionary bounds
|
|
4248
|
+
int64_t dictionary_length = array_view->dictionary->length;
|
|
4249
|
+
for (int64_t i = 0; i < array_view->length; i++) {
|
|
4250
|
+
if (ArrowArrayViewIsNull(array_view, i)) {
|
|
4251
|
+
continue;
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
int64_t index = ArrowArrayViewGetIntUnsafe(array_view, i);
|
|
4255
|
+
if (index < 0 || index >= dictionary_length) {
|
|
4256
|
+
ArrowErrorSet(error,
|
|
4257
|
+
"[%" PRId64 "] Expected dictionary index >= 0 and < %" PRId64
|
|
4258
|
+
" but found value %" PRId64,
|
|
4259
|
+
i, dictionary_length, index);
|
|
4260
|
+
return EINVAL;
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
3810
4263
|
}
|
|
3811
4264
|
|
|
3812
4265
|
return NANOARROW_OK;
|
data/lib/nanoarrow/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nanoarrow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
64
64
|
- !ruby/object:Gem::Version
|
|
65
65
|
version: '0'
|
|
66
66
|
requirements: []
|
|
67
|
-
rubygems_version: 4.0.
|
|
67
|
+
rubygems_version: 4.0.20
|
|
68
68
|
specification_version: 4
|
|
69
69
|
summary: Zero-dependency Arrow library for Ruby
|
|
70
70
|
test_files: []
|