You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2013/06/07 18:10:27 UTC
[lucy-commits] [12/16] Build Lucy with external Clownfish library
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/Util/NumberUtils.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Util/NumberUtils.cfh b/core/Clownfish/Util/NumberUtils.cfh
deleted file mode 100644
index cd6c750..0000000
--- a/core/Clownfish/Util/NumberUtils.cfh
+++ /dev/null
@@ -1,474 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-/** Provide various number-related utilies.
- *
- * Provide utilities for dealing with endian issues, sub-byte-width arrays,
- * compressed integers, and so on.
- */
-inert class Clownfish::Util::NumberUtils cnick NumUtil {
-
- inert const uint8_t[8] u1masks;
- inert const uint8_t[4] u2masks;
- inert const uint8_t[4] u2shifts;
- inert const uint8_t[2] u4masks;
- inert const uint8_t[2] u4shifts;
-
- /** Encode an unsigned 16-bit integer as 2 bytes in the buffer provided,
- * using big-endian byte order.
- */
- inert inline void
- encode_bigend_u16(uint16_t value, void *dest);
-
- /** Encode an unsigned 32-bit integer as 4 bytes in the buffer provided,
- * using big-endian byte order.
- */
- inert inline void
- encode_bigend_u32(uint32_t value, void *dest);
-
- /** Encode an unsigned 64-bit integer as 8 bytes in the buffer provided,
- * using big-endian byte order.
- */
- inert inline void
- encode_bigend_u64(uint64_t value, void *dest);
-
- /** Interpret a sequence of bytes as a big-endian unsigned 16-bit int.
- */
- inert inline uint16_t
- decode_bigend_u16(void *source);
-
- /** Interpret a sequence of bytes as a big-endian unsigned 32-bit int.
- */
- inert inline uint32_t
- decode_bigend_u32(void *source);
-
- /** Interpret a sequence of bytes as a big-endian unsigned 64-bit int.
- */
- inert inline uint64_t
- decode_bigend_u64(void *source);
-
- /** Encode a 32-bit floating point number as 4 bytes in the buffer
- * provided, using big-endian byte order.
- */
- inert inline void
- encode_bigend_f32(float value, void *dest);
-
- /** Encode a 64-bit floating point number as 8 bytes in the buffer
- * provided, using big-endian byte order.
- */
- inert inline void
- encode_bigend_f64(double value, void *dest);
-
- /** Interpret a sequence of bytes as a 32-bit float stored in big-endian
- * byte order.
- */
- inert inline float
- decode_bigend_f32(void *source);
-
- /** Interpret a sequence of bytes as a 64-bit float stored in big-endian
- * byte order.
- */
- inert inline double
- decode_bigend_f64(void *source);
-
- /** Encode a C32 at the space pointed to by <code>dest</code>. As a side
- * effect, <code>dest</code> will be advanced to immediately after the end
- * of the C32.
- */
- inert inline void
- encode_c32(uint32_t value, char **dest);
-
- /** Encode a C32 at the space pointed to by <code>dest</code>, but add
- * "leading zeroes" so that the space consumed will always be 5 bytes. As
- * a side effect, <code>dest</code> will be advanced to immediately after
- * the end of the C32.
- */
- inert inline void
- encode_padded_c32(uint32_t value, char **dest);
-
- /** Encode a C64 at the space pointed to by <code>dest</code>. As a side
- * effect, <code>dest</code> will be advanced to immediately after the end
- * of the C64.
- */
- inert inline void
- encode_c64(uint64_t value, char **dest);
-
- /** Read a C32 from the buffer pointed to by <code>source</code>. As a
- * side effect, advance the pointer, consuming the bytes occupied by the
- * C32.
- */
- inert inline uint32_t
- decode_c32(char **source);
-
- /** Read a C64 from the buffer pointed to by <code>source</code>. As a
- * side effect, advance the pointer, consuming the bytes occupied by the
- * C64.
- */
- inert inline uint64_t
- decode_c64(char **source);
-
- /** Advance <code>source</code> past one encoded C32 or C64.
- */
- inert inline void
- skip_cint(char **source);
-
- /** Interpret <code>array</code> as an array of bits; return true if the
- * bit at <code>tick</code> is set, false otherwise.
- */
- inert inline bool
- u1get(void *array, uint32_t tick);
-
- /** Interpret <code>array</code> as an array of bits; set the bit at
- * <code>tick</code>.
- */
- inert inline void
- u1set(void *array, uint32_t tick);
-
- /** Interpret <code>array</code> as an array of bits; clear the bit at
- * <code>tick</code>.
- */
- inert inline void
- u1clear(void *array, uint32_t tick);
-
- /** Interpret <code>array</code> as an array of bits; flip the bit at
- * <code>tick</code>.
- */
- inert inline void
- u1flip(void *array, uint32_t tick);
-
- /** Interpret <code>array</code> as an array of two-bit integers; return
- * the value at <code>tick</code>.
- */
- inert inline uint8_t
- u2get(void *array, uint32_t tick);
-
- /** Interpret <code>array</code> as an array of two-bit integers; set the
- * element at <code>tick</code> to <code>value</code>.
- */
- inert inline void
- u2set(void *array, uint32_t tick, uint8_t value);
-
- /** Interpret <code>array</code> as an array of four-bit integers; return
- * the value at <code>tick</code>.
- */
- inert inline uint8_t
- u4get(void *array, uint32_t tick);
-
- /** Interpret <code>array</code> as an array of four-bit integers; set the
- * element at <code>tick</code> to <code>value</code>.
- */
- inert inline void
- u4set(void *array, uint32_t tick, uint8_t value);
-}
-
-__C__
-
-#include <string.h>
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_bigend_u16(uint16_t value, void *dest_ptr) {
- uint8_t *dest = *(uint8_t**)dest_ptr;
-#ifdef CHY_BIG_END
- memcpy(dest, &value, sizeof(uint16_t));
-#else // little endian
- uint8_t *source = (uint8_t*)&value;
- dest[0] = source[1];
- dest[1] = source[0];
-#endif // CHY_BIG_END (and little endian)
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_bigend_u32(uint32_t value, void *dest_ptr) {
- uint8_t *dest = *(uint8_t**)dest_ptr;
-#ifdef CHY_BIG_END
- memcpy(dest, &value, sizeof(uint32_t));
-#else // little endian
- uint8_t *source = (uint8_t*)&value;
- dest[0] = source[3];
- dest[1] = source[2];
- dest[2] = source[1];
- dest[3] = source[0];
-#endif // CHY_BIG_END (and little endian)
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_bigend_u64(uint64_t value, void *dest_ptr) {
- uint8_t *dest = *(uint8_t**)dest_ptr;
-#ifdef CHY_BIG_END
- memcpy(dest, &value, sizeof(uint64_t));
-#else // little endian
- uint8_t *source = (uint8_t*)&value;
- dest[0] = source[7];
- dest[1] = source[6];
- dest[2] = source[5];
- dest[3] = source[4];
- dest[4] = source[3];
- dest[5] = source[2];
- dest[6] = source[1];
- dest[7] = source[0];
-#endif // CHY_BIG_END (and little endian)
-}
-
-static CFISH_INLINE uint16_t
-cfish_NumUtil_decode_bigend_u16(void *source) {
- uint8_t *const buf = (uint8_t*)source;
- return (buf[0] << 8) |
- (buf[1]);
-}
-
-static CFISH_INLINE uint32_t
-cfish_NumUtil_decode_bigend_u32(void *source) {
- uint8_t *const buf = (uint8_t*)source;
- return (buf[0] << 24) |
- (buf[1] << 16) |
- (buf[2] << 8) |
- (buf[3]);
-}
-
-static CFISH_INLINE uint64_t
-cfish_NumUtil_decode_bigend_u64(void *source) {
- uint8_t *const buf = (uint8_t*)source;
- uint64_t high_bits = (buf[0] << 24) |
- (buf[1] << 16) |
- (buf[2] << 8) |
- (buf[3]);
- uint32_t low_bits = (buf[4] << 24) |
- (buf[5] << 16) |
- (buf[6] << 8) |
- (buf[7]);
- uint64_t retval = high_bits << 32;
- retval |= low_bits;
- return retval;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_bigend_f32(float value, void *dest_ptr) {
- uint8_t *dest = *(uint8_t**)dest_ptr;
-#ifdef CHY_BIG_END
- memcpy(dest, &value, sizeof(float));
-#else
- union { float f; uint32_t u32; } duo;
- duo.f = value;
- cfish_NumUtil_encode_bigend_u32(duo.u32, &dest);
-#endif
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_bigend_f64(double value, void *dest_ptr) {
- uint8_t *dest = *(uint8_t**)dest_ptr;
-#ifdef CHY_BIG_END
- memcpy(dest, &value, sizeof(double));
-#else
- union { double d; uint64_t u64; } duo;
- duo.d = value;
- cfish_NumUtil_encode_bigend_u64(duo.u64, &dest);
-#endif
-}
-
-static CFISH_INLINE float
-cfish_NumUtil_decode_bigend_f32(void *source) {
- union { float f; uint32_t u32; } duo;
- memcpy(&duo, source, sizeof(float));
-#ifdef CHY_LITTLE_END
- duo.u32 = cfish_NumUtil_decode_bigend_u32(&duo.u32);
-#endif
- return duo.f;
-}
-
-static CFISH_INLINE double
-cfish_NumUtil_decode_bigend_f64(void *source) {
- union { double d; uint64_t u64; } duo;
- memcpy(&duo, source, sizeof(double));
-#ifdef CHY_LITTLE_END
- duo.u64 = cfish_NumUtil_decode_bigend_u64(&duo.u64);
-#endif
- return duo.d;
-}
-
-#define CFISH_NUMUTIL_C32_MAX_BYTES ((sizeof(uint32_t) * 8 / 7) + 1) // 5
-#define CFISH_NUMUTIL_C64_MAX_BYTES ((sizeof(uint64_t) * 8 / 7) + 1) // 10
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_c32(uint32_t value, char **out_buf) {
- uint8_t buf[CFISH_NUMUTIL_C32_MAX_BYTES];
- uint8_t *const limit = buf + sizeof(buf);
- uint8_t *ptr = limit - 1;
- int num_bytes;
- // Write last byte first, which has no continue bit.
- *ptr = value & 0x7f;
- value >>= 7;
- while (value) {
- // Work backwards, writing bytes with continue bits set.
- *--ptr = ((value & 0x7f) | 0x80);
- value >>= 7;
- }
- num_bytes = limit - ptr;
- memcpy(*out_buf, ptr, num_bytes);
- *out_buf += num_bytes;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_c64(uint64_t value, char **out_buf) {
- uint8_t buf[CFISH_NUMUTIL_C64_MAX_BYTES];
- uint8_t *const limit = buf + sizeof(buf);
- uint8_t *ptr = limit - 1;
- int num_bytes;
- // Write last byte first, which has no continue bit.
- *ptr = value & 0x7f;
- value >>= 7;
- while (value) {
- // Work backwards, writing bytes with continue bits set.
- *--ptr = ((value & 0x7f) | 0x80);
- value >>= 7;
- }
- num_bytes = limit - ptr;
- memcpy(*out_buf, ptr, num_bytes);
- *out_buf += num_bytes;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_encode_padded_c32(uint32_t value, char **out_buf) {
- uint8_t buf[CFISH_NUMUTIL_C32_MAX_BYTES]
- = { 0x80, 0x80, 0x80, 0x80, 0x80 };
- uint8_t *const limit = buf + sizeof(buf);
- uint8_t *ptr = limit - 1;
- // Write last byte first, which has no continue bit.
- *ptr = value & 0x7f;
- value >>= 7;
- while (value) {
- // Work backwards, writing bytes with continue bits set.
- *--ptr = ((value & 0x7f) | 0x80);
- value >>= 7;
- }
- memcpy(*out_buf, buf, CFISH_NUMUTIL_C32_MAX_BYTES);
- *out_buf += sizeof(buf);
-}
-
-// Decode a compressed integer up to size of 'var', advancing 'source'
-#define CFISH_NUMUTIL_DECODE_CINT(var, source) \
- do { \
- var = (*source & 0x7f); \
- while (*source++ & 0x80) { \
- var = (*source & 0x7f) | (var << 7); \
- } \
- } while (0)
-
-static CFISH_INLINE uint32_t
-cfish_NumUtil_decode_c32(char **source_ptr) {
- char *source = *source_ptr;
- uint32_t decoded;
- CFISH_NUMUTIL_DECODE_CINT(decoded, source);
- *source_ptr = source;
- return decoded;
-}
-
-static CFISH_INLINE uint64_t
-cfish_NumUtil_decode_c64(char **source_ptr) {
- char *source = *source_ptr;
- uint64_t decoded;
- CFISH_NUMUTIL_DECODE_CINT(decoded, source);
- *source_ptr = source;
- return decoded;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_skip_cint(char **source_ptr) {
- uint8_t *ptr = *(uint8_t**)source_ptr;
- while ((*ptr++ & 0x80) != 0) { }
- *source_ptr = (char*)ptr;
-}
-
-static CFISH_INLINE bool
-cfish_NumUtil_u1get(void *array, uint32_t tick) {
- uint8_t *const u8bits = (uint8_t*)array;
- const uint32_t byte_offset = tick >> 3;
- const uint8_t mask = cfish_NumUtil_u1masks[tick & 0x7];
- return !((u8bits[byte_offset] & mask) == 0);
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_u1set(void *array, uint32_t tick) {
- uint8_t *const u8bits = (uint8_t*)array;
- const uint32_t byte_offset = tick >> 3;
- const uint8_t mask = cfish_NumUtil_u1masks[tick & 0x7];
- u8bits[byte_offset] |= mask;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_u1clear(void *array, uint32_t tick) {
- uint8_t *const u8bits = (uint8_t*)array;
- const uint32_t byte_offset = tick >> 3;
- const uint8_t mask = cfish_NumUtil_u1masks[tick & 0x7];
- u8bits[byte_offset] &= ~mask;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_u1flip(void *array, uint32_t tick) {
- uint8_t *const u8bits = (uint8_t*)array;
- const uint32_t byte_offset = tick >> 3;
- const uint8_t mask = cfish_NumUtil_u1masks[tick & 0x7];
- u8bits[byte_offset] ^= mask;
-}
-
-static CFISH_INLINE uint8_t
-cfish_NumUtil_u2get(void *array, uint32_t tick) {
- uint8_t *ints = (uint8_t*)array;
- uint8_t byte = ints[(tick >> 2)];
- int shift = cfish_NumUtil_u2shifts[tick & 0x3];
- return (byte >> shift) & 0x3;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_u2set(void *array, uint32_t tick, uint8_t value) {
- uint8_t *ints = (uint8_t*)array;
- unsigned sub_tick = tick & 0x3;
- int shift = cfish_NumUtil_u2shifts[sub_tick];
- uint8_t mask = cfish_NumUtil_u2masks[sub_tick];
- uint8_t new_val = value & 0x3;
- uint8_t new_bits = new_val << shift;
- ints[(tick >> 2)] = (ints[(tick >> 2)] & ~mask) | new_bits;
-}
-
-
-static CFISH_INLINE uint8_t
-cfish_NumUtil_u4get(void *array, uint32_t tick) {
- uint8_t *ints = (uint8_t*)array;
- uint8_t byte = ints[(tick >> 1)];
- int shift = cfish_NumUtil_u4shifts[(tick & 1)];
- return (byte >> shift) & 0xF;
-}
-
-static CFISH_INLINE void
-cfish_NumUtil_u4set(void *array, uint32_t tick, uint8_t value) {
- uint8_t *ints = (uint8_t*)array;
- unsigned sub_tick = tick & 0x1;
- int shift = cfish_NumUtil_u4shifts[sub_tick];
- uint8_t mask = cfish_NumUtil_u4masks[sub_tick];
- uint8_t new_val = value & 0xF;
- uint8_t new_bits = new_val << shift;
- ints[(tick >> 1)] = (ints[(tick >> 1)] & ~mask) | new_bits;
-}
-
-#ifdef CFISH_USE_SHORT_NAMES
- #define C32_MAX_BYTES CFISH_NUMUTIL_C32_MAX_BYTES
- #define C64_MAX_BYTES CFISH_NUMUTIL_C64_MAX_BYTES
-#endif
-
-__END_C__
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/Util/SortUtils.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Util/SortUtils.c b/core/Clownfish/Util/SortUtils.c
deleted file mode 100644
index f4c0236..0000000
--- a/core/Clownfish/Util/SortUtils.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_SORTUTILS
-#define CFISH_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include <string.h>
-#include "Clownfish/Util/SortUtils.h"
-#include "Clownfish/Err.h"
-
-// Define four-byte and eight-byte types so that we can dereference void
-// pointers like integer pointers. The only significance of using int32_t and
-// int64_t is that they are 4 and 8 bytes.
-#define FOUR_BYTE_TYPE int32_t
-#define EIGHT_BYTE_TYPE int64_t
-
-/***************************** mergesort ************************************/
-
-// Recursive merge sorting functions.
-static void
-S_msort4(void *velems, void *vscratch, uint32_t left, uint32_t right,
- Cfish_Sort_Compare_t compare, void *context);
-static void
-S_msort8(void *velems, void *vscratch, uint32_t left, uint32_t right,
- Cfish_Sort_Compare_t compare, void *context);
-static void
-S_msort_any(void *velems, void *vscratch, uint32_t left, uint32_t right,
- Cfish_Sort_Compare_t compare, void *context, size_t width);
-
-static INLINE void
-SI_merge(void *left_vptr, uint32_t left_size,
- void *right_vptr, uint32_t right_size,
- void *vdest, size_t width, Cfish_Sort_Compare_t compare, void *context);
-
-void
-Sort_mergesort(void *elems, void *scratch, uint32_t num_elems, uint32_t width,
- Cfish_Sort_Compare_t compare, void *context) {
- // Arrays of 0 or 1 items are already sorted.
- if (num_elems < 2) { return; }
-
- // Validate.
- if (num_elems >= INT32_MAX) {
- THROW(ERR, "Provided %u64 elems, but can't handle more than %i32",
- (uint64_t)num_elems, INT32_MAX);
- }
-
- // Dispatch by element size.
- switch (width) {
- case 0:
- THROW(ERR, "Parameter 'width' cannot be 0");
- break;
- case 4:
- S_msort4(elems, scratch, 0, num_elems - 1, compare, context);
- break;
- case 8:
- S_msort8(elems, scratch, 0, num_elems - 1, compare, context);
- break;
- default:
- S_msort_any(elems, scratch, 0, num_elems - 1, compare,
- context, width);
- break;
- }
-}
-
-void
-Sort_merge(void *left_ptr, uint32_t left_size,
- void *right_ptr, uint32_t right_size,
- void *dest, size_t width, Cfish_Sort_Compare_t compare,
- void *context) {
- switch (width) {
- case 0:
- THROW(ERR, "Parameter 'width' cannot be 0");
- break;
- case 4:
- SI_merge(left_ptr, left_size, right_ptr, right_size,
- dest, 4, compare, context);
- break;
- case 8:
- SI_merge(left_ptr, left_size, right_ptr, right_size,
- dest, 8, compare, context);
- break;
- default:
- SI_merge(left_ptr, left_size, right_ptr, right_size,
- dest, width, compare, context);
- break;
- }
-}
-
-#define WIDTH 4
-static void
-S_msort4(void *velems, void *vscratch, uint32_t left, uint32_t right,
- Cfish_Sort_Compare_t compare, void *context) {
- uint8_t *elems = (uint8_t*)velems;
- uint8_t *scratch = (uint8_t*)vscratch;
- if (right > left) {
- const uint32_t mid = ((right + left) / 2) + 1;
- S_msort4(elems, scratch, left, mid - 1, compare, context);
- S_msort4(elems, scratch, mid, right, compare, context);
- SI_merge((elems + left * WIDTH), (mid - left),
- (elems + mid * WIDTH), (right - mid + 1),
- scratch, WIDTH, compare, context);
- memcpy((elems + left * WIDTH), scratch, ((right - left + 1) * WIDTH));
- }
-}
-
-#undef WIDTH
-#define WIDTH 8
-static void
-S_msort8(void *velems, void *vscratch, uint32_t left, uint32_t right,
- Cfish_Sort_Compare_t compare, void *context) {
- uint8_t *elems = (uint8_t*)velems;
- uint8_t *scratch = (uint8_t*)vscratch;
- if (right > left) {
- const uint32_t mid = ((right + left) / 2) + 1;
- S_msort8(elems, scratch, left, mid - 1, compare, context);
- S_msort8(elems, scratch, mid, right, compare, context);
- SI_merge((elems + left * WIDTH), (mid - left),
- (elems + mid * WIDTH), (right - mid + 1),
- scratch, WIDTH, compare, context);
- memcpy((elems + left * WIDTH), scratch, ((right - left + 1) * WIDTH));
- }
-}
-
-#undef WIDTH
-static void
-S_msort_any(void *velems, void *vscratch, uint32_t left, uint32_t right,
- Cfish_Sort_Compare_t compare, void *context, size_t width) {
- uint8_t *elems = (uint8_t*)velems;
- uint8_t *scratch = (uint8_t*)vscratch;
- if (right > left) {
- const uint32_t mid = ((right + left) / 2) + 1;
- S_msort_any(elems, scratch, left, mid - 1, compare, context, width);
- S_msort_any(elems, scratch, mid, right, compare, context, width);
- SI_merge((elems + left * width), (mid - left),
- (elems + mid * width), (right - mid + 1),
- scratch, width, compare, context);
- memcpy((elems + left * width), scratch, ((right - left + 1) * width));
- }
-}
-
-static INLINE void
-SI_merge(void *left_vptr, uint32_t left_size,
- void *right_vptr, uint32_t right_size,
- void *vdest, size_t width, Cfish_Sort_Compare_t compare,
- void *context) {
- uint8_t *left_ptr = (uint8_t*)left_vptr;
- uint8_t *right_ptr = (uint8_t*)right_vptr;
- uint8_t *left_limit = left_ptr + left_size * width;
- uint8_t *right_limit = right_ptr + right_size * width;
- uint8_t *dest = (uint8_t*)vdest;
-
- while (left_ptr < left_limit && right_ptr < right_limit) {
- if (compare(context, left_ptr, right_ptr) < 1) {
- memcpy(dest, left_ptr, width);
- dest += width;
- left_ptr += width;
- }
- else {
- memcpy(dest, right_ptr, width);
- dest += width;
- right_ptr += width;
- }
- }
-
- const size_t left_remaining = left_limit - left_ptr;
- memcpy(dest, left_ptr, left_remaining);
- dest += left_remaining;
- const size_t right_remaining = right_limit - right_ptr;
- memcpy(dest, right_ptr, right_remaining);
-}
-
-/***************************** quicksort ************************************/
-
-// Quicksort implementations optimized for four-byte and eight-byte elements.
-static void
-S_qsort4(FOUR_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context);
-static void
-S_qsort8(EIGHT_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context);
-
-// Swap two elements.
-static INLINE void
-SI_exchange4(FOUR_BYTE_TYPE *elems, int32_t left, int32_t right);
-static INLINE void
-SI_exchange8(EIGHT_BYTE_TYPE *elems, int32_t left, int32_t right);
-
-/* Select a pivot by choosing the median of three values, guarding against
- * the worst-case behavior of quicksort. Place the pivot in the rightmost
- * slot.
- *
- * Possible states:
- *
- * abc => abc => abc => acb
- * acb => acb => acb => acb
- * bac => abc => abc => acb
- * bca => bca => acb => acb
- * cba => bca => acb => acb
- * cab => acb => acb => acb
- * aab => aab => aab => aba
- * aba => aba => aba => aba
- * baa => aba => aba => aba
- * bba => bba => abb => abb
- * bab => abb => abb => abb
- * abb => abb => abb => abb
- * aaa => aaa => aaa => aaa
- */
-static INLINE FOUR_BYTE_TYPE*
-SI_choose_pivot4(FOUR_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context);
-static INLINE EIGHT_BYTE_TYPE*
-SI_choose_pivot8(EIGHT_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context);
-
-void
-Sort_quicksort(void *elems, size_t num_elems, size_t width,
- Cfish_Sort_Compare_t compare, void *context) {
- // Arrays of 0 or 1 items are already sorted.
- if (num_elems < 2) { return; }
-
- // Validate.
- if (num_elems >= INT32_MAX) {
- THROW(ERR, "Provided %u64 elems, but can't handle more than %i32",
- (uint64_t)num_elems, INT32_MAX);
- }
-
- if (width == 4) {
- S_qsort4((FOUR_BYTE_TYPE*)elems, 0, num_elems - 1, compare, context);
- }
- else if (width == 8) {
- S_qsort8((EIGHT_BYTE_TYPE*)elems, 0, num_elems - 1, compare, context);
- }
- else {
- THROW(ERR, "Unsupported width: %i64", (int64_t)width);
- }
-}
-
-/************************* quicksort 4 byte *********************************/
-
-static INLINE void
-SI_exchange4(FOUR_BYTE_TYPE *elems, int32_t left, int32_t right) {
- FOUR_BYTE_TYPE saved = elems[left];
- elems[left] = elems[right];
- elems[right] = saved;
-}
-
-static INLINE FOUR_BYTE_TYPE*
-SI_choose_pivot4(FOUR_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context) {
- if (right - left > 1) {
- int32_t mid = left + (right - left) / 2;
- if (compare(context, elems + left, elems + mid) > 0) {
- SI_exchange4(elems, left, mid);
- }
- if (compare(context, elems + left, elems + right) > 0) {
- SI_exchange4(elems, left, right);
- }
- if (compare(context, elems + right, elems + mid) > 0) {
- SI_exchange4(elems, right, mid);
- }
- }
- return elems + right;
-}
-
-static void
-S_qsort4(FOUR_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context) {
- FOUR_BYTE_TYPE *const pivot
- = SI_choose_pivot4(elems, left, right, compare, context);
- int32_t i = left - 1;
- int32_t j = right;
- int32_t p = left - 1;
- int32_t q = right;
-
- if (right <= left) { return; }
-
- /* TODO: A standard optimization for quicksort is to fall back to an
- * insertion sort when the the number of elements to be sorted becomes
- * small enough. */
-
- while (1) {
- int comparison1;
- int comparison2;
-
- // Find an element from the left that is greater than or equal to the
- // pivot (i.e. that should move to the right).
- while (1) {
- i++;
- comparison1 = compare(context, elems + i, pivot);
- if (comparison1 >= 0) { break; }
- if (i == right) { break; }
- }
-
- // Find an element from the right that is less than or equal to the
- // pivot (i.e. that should move to the left).
- while (1) {
- j--;
- comparison2 = compare(context, elems + j, pivot);
- if (comparison2 <= 0) { break; }
- if (j == left) { break; }
- }
-
- // Bail out of loop when we meet in the middle.
- if (i >= j) { break; }
-
- // Swap the elements we found, so the lesser element moves left and
- // the greater element moves right.
- SI_exchange4(elems, i, j);
-
- // Move any elements which test as "equal" to the pivot to the outside
- // edges of the array.
- if (comparison2 == 0) {
- p++;
- SI_exchange4(elems, p, i);
- }
- if (comparison1 == 0) {
- q--;
- SI_exchange4(elems, j, q);
- }
- }
-
- /* Move "equal" elements from the outside edges to the center.
- *
- * Before:
- *
- * equal | less_than | greater_than | equal
- *
- * After:
- *
- * less_than | equal | greater_than
- */
- SI_exchange4(elems, i, right);
- j = i - 1;
- i++;
- for (int32_t k = left; k < p; k++, j--) { SI_exchange4(elems, k, j); }
- for (int32_t k = right - 1; k > q; k--, i++) { SI_exchange4(elems, i, k); }
-
- // Recurse.
- S_qsort4(elems, left, j, compare, context); // Sort less_than.
- S_qsort4(elems, i, right, compare, context); // Sort greater_than.
-}
-
-/************************* quicksort 8 byte *********************************/
-
-static INLINE void
-SI_exchange8(EIGHT_BYTE_TYPE *elems, int32_t left, int32_t right) {
- EIGHT_BYTE_TYPE saved = elems[left];
- elems[left] = elems[right];
- elems[right] = saved;
-}
-
-static INLINE EIGHT_BYTE_TYPE*
-SI_choose_pivot8(EIGHT_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context) {
- if (right - left > 1) {
- int32_t mid = left + (right - left) / 2;
- if (compare(context, elems + left, elems + mid) > 0) {
- SI_exchange8(elems, left, mid);
- }
- if (compare(context, elems + left, elems + right) > 0) {
- SI_exchange8(elems, left, right);
- }
- if (compare(context, elems + right, elems + mid) > 0) {
- SI_exchange8(elems, right, mid);
- }
- }
- return elems + right;
-}
-
-static void
-S_qsort8(EIGHT_BYTE_TYPE *elems, int32_t left, int32_t right,
- Cfish_Sort_Compare_t compare, void *context) {
- EIGHT_BYTE_TYPE *const pivot
- = SI_choose_pivot8(elems, left, right, compare, context);
- int32_t i = left - 1;
- int32_t j = right;
- int32_t p = left - 1;
- int32_t q = right;
-
- if (right <= left) { return; }
-
- /* TODO: A standard optimization for quicksort is to fall back to an
- * insertion sort when the the number of elements to be sorted becomes
- * small enough. */
-
- while (1) {
- int comparison1;
- int comparison2;
-
- // Find an element from the left that is greater than or equal to the
- // pivot (i.e. that should move to the right).
- while (1) {
- i++;
- comparison1 = compare(context, elems + i, pivot);
- if (comparison1 >= 0) { break; }
- if (i == right) { break; }
- }
-
- // Find an element from the right that is less than or equal to the
- // pivot (i.e. that should move to the left).
- while (1) {
- j--;
- comparison2 = compare(context, elems + j, pivot);
- if (comparison2 <= 0) { break; }
- if (j == left) { break; }
- }
-
- // Bail out of loop when we meet in the middle.
- if (i >= j) { break; }
-
- // Swap the elements we found, so the lesser element moves left and
- // the greater element moves right.
- SI_exchange8(elems, i, j);
-
- // Move any elements which test as "equal" to the pivot to the outside
- // edges of the array.
- if (comparison2 == 0) {
- p++;
- SI_exchange8(elems, p, i);
- }
- if (comparison1 == 0) {
- q--;
- SI_exchange8(elems, j, q);
- }
- }
-
- /* Move "equal" elements from the outside edges to the center.
- *
- * Before:
- *
- * equal | less_than | greater_than | equal
- *
- * After:
- *
- * less_than | equal | greater_than
- */
- SI_exchange8(elems, i, right);
- j = i - 1;
- i++;
- for (int32_t k = left; k < p; k++, j--) { SI_exchange8(elems, k, j); }
- for (int32_t k = right - 1; k > q; k--, i++) { SI_exchange8(elems, i, k); }
-
- // Recurse.
- S_qsort8(elems, left, j, compare, context); // Sort less_than.
- S_qsort8(elems, i, right, compare, context); // Sort greater_than.
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/Util/SortUtils.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Util/SortUtils.cfh b/core/Clownfish/Util/SortUtils.cfh
deleted file mode 100644
index 39ac2d1..0000000
--- a/core/Clownfish/Util/SortUtils.cfh
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-__C__
-typedef int
-(*Cfish_Sort_Compare_t)(void *context, const void *va, const void *vb);
-__END_C__
-
-/** Specialized sorting routines.
- *
- * SortUtils provides a merge sort algorithm which allows access to its
- * internals, enabling specialized functions to jump in and only execute part
- * of the sort.
- *
- * SortUtils also provides a quicksort with an additional context argument.
- */
-inert class Clownfish::Util::SortUtils cnick Sort {
-
- /** Perform a mergesort. In addition to providing a contiguous array of
- * elements to be sorted and their count, the caller must also provide a
- * scratch buffer with room for at least as many elements as are to be
- * sorted.
- */
- inert void
- mergesort(void *elems, void *scratch, uint32_t num_elems, uint32_t width,
- Cfish_Sort_Compare_t compare, void *context);
-
- /** Merge two source arrays together using the classic mergesort merge
- * algorithm, storing the result in <code>dest</code>.
- *
- * Most merge functions operate on a single contiguous array and copy the
- * merged results results back into the source array before returning.
- * These two differ in that it is possible to operate on two discontiguous
- * source arrays. Copying the results back into the source array is the
- * responsibility of the caller.
- *
- * Lucy's external sort takes advantage of this when it is reading
- * back pre-sorted runs from disk and merging the streams into a
- * consolidated buffer.
- */
- inert void
- merge(void *left_ptr, uint32_t left_num_elems,
- void *right_ptr, uint32_t right_num_elems,
- void *dest, size_t width, Cfish_Sort_Compare_t compare, void *context);
-
- /** Quicksort.
- */
- inert void
- quicksort(void *elems, size_t num_elems, size_t width,
- Cfish_Sort_Compare_t compare, void *context);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/Util/StringHelper.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Util/StringHelper.c b/core/Clownfish/Util/StringHelper.c
deleted file mode 100644
index c62431a..0000000
--- a/core/Clownfish/Util/StringHelper.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_STRINGHELPER
-#include <string.h>
-
-#define CFISH_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include "Clownfish/Util/StringHelper.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Util/Memory.h"
-
-const uint8_t cfish_StrHelp_UTF8_COUNT[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-int32_t
-StrHelp_overlap(const char *a, const char *b, size_t a_len, size_t b_len) {
- size_t i;
- const size_t len = a_len <= b_len ? a_len : b_len;
-
- for (i = 0; i < len; i++) {
- if (*a++ != *b++) { break; }
- }
- return i;
-}
-
-static const char base36_chars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-
-uint32_t
-StrHelp_to_base36(uint64_t num, void *buffer) {
- char my_buf[StrHelp_MAX_BASE36_BYTES];
- char *buf = my_buf + StrHelp_MAX_BASE36_BYTES - 1;
- char *end = buf;
-
- // Null terminate.
- *buf = '\0';
-
- // Convert to base 36 characters.
- do {
- *(--buf) = base36_chars[num % 36];
- num /= 36;
- } while (num > 0);
-
- uint32_t size = end - buf;
- memcpy(buffer, buf, size + 1);
- return size;
-}
-
-bool
-StrHelp_utf8_valid(const char *ptr, size_t size) {
- const uint8_t *string = (const uint8_t*)ptr;
- const uint8_t *const end = string + size;
- while (string < end) {
- const uint8_t header_byte = *string++;
- int count = StrHelp_UTF8_COUNT[header_byte] & 0x7;
- switch (count & 0x7) {
- case 1:
- // ASCII
- break;
- case 2:
- if (string == end) { return false; }
- // Disallow non-shortest-form ASCII.
- if (!(header_byte & 0x1E)) { return false; }
- if ((*string++ & 0xC0) != 0x80) { return false; }
- break;
- case 3:
- if (end - string < 2) { return false; }
- if (header_byte == 0xED) {
- if (*string < 0x80 || *string > 0x9F) {
- return false;
- }
- }
- else if (!(header_byte & 0x0F)) {
- if (!(*string & 0x20)) {
- return false;
- }
- }
- if ((*string++ & 0xC0) != 0x80) { return false; }
- if ((*string++ & 0xC0) != 0x80) { return false; }
- break;
- case 4:
- if (end - string < 3) { return false; }
- if (!(header_byte & 0x07)) {
- if (!(*string & 0x30)) {
- return false;
- }
- }
- if ((*string++ & 0xC0) != 0x80) { return false; }
- if ((*string++ & 0xC0) != 0x80) { return false; }
- if ((*string++ & 0xC0) != 0x80) { return false; }
- break;
- default:
- return false;
- }
- }
-
- return true;
-}
-
-bool
-StrHelp_is_whitespace(uint32_t code_point) {
- switch (code_point) {
- // <control-0009>..<control-000D>
- case 0x0009: case 0x000A: case 0x000B: case 0x000C: case 0x000D:
- case 0x0020: // SPACE
- case 0x0085: // <control-0085>
- case 0x00A0: // NO-BREAK SPACE
- case 0x1680: // OGHAM SPACE MARK
- case 0x180E: // MONGOLIAN VOWEL SEPARATOR
- // EN QUAD..HAIR SPACE
- case 0x2000: case 0x2001: case 0x2002: case 0x2003: case 0x2004:
- case 0x2005: case 0x2006: case 0x2007: case 0x2008: case 0x2009:
- case 0x200A:
- case 0x2028: // LINE SEPARATOR
- case 0x2029: // PARAGRAPH SEPARATOR
- case 0x202F: // NARROW NO-BREAK SPACE
- case 0x205F: // MEDIUM MATHEMATICAL SPACE
- case 0x3000: // IDEOGRAPHIC SPACE
- return true;
-
- default:
- return false;
- }
-}
-
-uint32_t
-StrHelp_encode_utf8_char(uint32_t code_point, void *buffer) {
- uint8_t *buf = (uint8_t*)buffer;
- if (code_point <= 0x7F) { // ASCII
- buf[0] = (uint8_t)code_point;
- return 1;
- }
- else if (code_point <= 0x07FF) { // 2 byte range
- buf[0] = (uint8_t)(0xC0 | (code_point >> 6));
- buf[1] = (uint8_t)(0x80 | (code_point & 0x3f));
- return 2;
- }
- else if (code_point <= 0xFFFF) { // 3 byte range
- buf[0] = (uint8_t)(0xE0 | (code_point >> 12));
- buf[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
- buf[2] = (uint8_t)(0x80 | (code_point & 0x3f));
- return 3;
- }
- else if (code_point <= 0x10FFFF) { // 4 byte range
- buf[0] = (uint8_t)(0xF0 | (code_point >> 18));
- buf[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
- buf[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
- buf[3] = (uint8_t)(0x80 | (code_point & 0x3f));
- return 4;
- }
- else {
- THROW(ERR, "Illegal Unicode code point: %u32", code_point);
- UNREACHABLE_RETURN(uint32_t);
- }
-}
-
-uint32_t
-StrHelp_decode_utf8_char(const char *ptr) {
- const uint8_t *const string = (const uint8_t*)ptr;
- uint32_t retval = *string;
- int bytes = StrHelp_UTF8_COUNT[retval];
-
- switch (bytes & 0x7) {
- case 1:
- break;
-
- case 2:
- retval = ((retval & 0x1F) << 6)
- | (string[1] & 0x3F);
- break;
-
- case 3:
- retval = ((retval & 0x0F) << 12)
- | ((string[1] & 0x3F) << 6)
- | (string[2] & 0x3F);
- break;
-
- case 4:
- retval = ((retval & 0x07) << 18)
- | ((string[1] & 0x3F) << 12)
- | ((string[2] & 0x3F) << 6)
- | (string[3] & 0x3F);
- break;
-
- default:
- THROW(ERR, "Invalid UTF-8 header byte: %x32", retval);
- }
-
- return retval;
-}
-
-const char*
-StrHelp_back_utf8_char(const char *ptr, char *start) {
- while (--ptr >= start) {
- if ((*ptr & 0xC0) != 0x80) { return ptr; }
- }
- return NULL;
-}
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/Util/StringHelper.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Util/StringHelper.cfh b/core/Clownfish/Util/StringHelper.cfh
deleted file mode 100644
index 482666f..0000000
--- a/core/Clownfish/Util/StringHelper.cfh
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-inert class Clownfish::Util::StringHelper cnick StrHelp {
-
- /* A table where the values indicate the number of bytes in a UTF-8
- * sequence implied by the leading utf8 byte.
- */
- inert const uint8_t[] UTF8_COUNT;
-
- /** Return the number of bytes that two strings have in common.
- */
- inert int32_t
- overlap(const char *a, const char *b, size_t a_len, size_t b_len);
-
- /** Encode a NULL-terminated string representation of a value in base 36
- * into <code>buffer</code>.
- *
- * @param value The number to be encoded.
- * @param buffer A buffer at least MAX_BASE36_BYTES bytes long.
- * @return the number of digits encoded (not including the terminating
- * NULL).
- */
- inert uint32_t
- to_base36(uint64_t value, void *buffer);
-
- /** Return true if the string is valid UTF-8, false otherwise.
- */
- inert bool
- utf8_valid(const char *ptr, size_t len);
-
- /** Returns true if the code point qualifies as Unicode whitespace.
- */
- inert bool
- is_whitespace(uint32_t code_point);
-
- /** Encode a Unicode code point to a UTF-8 sequence.
- *
- * @param code_point A legal unicode code point.
- * @param buffer Write buffer which must hold at least 4 bytes (the
- * maximum legal length for a UTF-8 char).
- */
- inert uint32_t
- encode_utf8_char(uint32_t code_point, void *buffer);
-
- /** Decode a UTF-8 sequence to a Unicode code point. Assumes valid UTF-8.
- */
- inert uint32_t
- decode_utf8_char(const char *utf8);
-
- /** Return the first non-continuation byte before the supplied pointer.
- * If backtracking progresses beyond the supplied start, return NULL.
- */
- inert nullable const char*
- back_utf8_char(const char *utf8, char *start);
-}
-
-__C__
-/** The maximum number of bytes encoded by to_base36(), including the
- * terminating NULL.
- */
-#define cfish_StrHelp_MAX_BASE36_BYTES 14
-#ifdef CFISH_USE_SHORT_NAMES
- #define StrHelp_MAX_BASE36_BYTES cfish_StrHelp_MAX_BASE36_BYTES
-#endif
-__END_C__
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/VArray.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/VArray.c b/core/Clownfish/VArray.c
deleted file mode 100644
index 2370eb9..0000000
--- a/core/Clownfish/VArray.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_VARRAY
-#include <string.h>
-#include <stdlib.h>
-
-#define CFISH_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include "Clownfish/VTable.h"
-#include "Clownfish/VArray.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Util/Memory.h"
-#include "Clownfish/Util/SortUtils.h"
-
-VArray*
-VA_new(uint32_t capacity) {
- VArray *self = (VArray*)VTable_Make_Obj(VARRAY);
- VA_init(self, capacity);
- return self;
-}
-
-VArray*
-VA_init(VArray *self, uint32_t capacity) {
- // Init.
- self->size = 0;
-
- // Assign.
- self->cap = capacity;
-
- // Derive.
- self->elems = (Obj**)CALLOCATE(capacity, sizeof(Obj*));
-
- return self;
-}
-
-void
-VA_destroy(VArray *self) {
- if (self->elems) {
- Obj **elems = self->elems;
- Obj **const limit = elems + self->size;
- for (; elems < limit; elems++) {
- DECREF(*elems);
- }
- FREEMEM(self->elems);
- }
- SUPER_DESTROY(self, VARRAY);
-}
-
-VArray*
-VA_dump(VArray *self) {
- VArray *dump = VA_new(self->size);
- for (uint32_t i = 0, max = self->size; i < max; i++) {
- Obj *elem = VA_Fetch(self, i);
- if (elem) { VA_Store(dump, i, Obj_Dump(elem)); }
- }
- return dump;
-}
-
-VArray*
-VA_load(VArray *self, Obj *dump) {
- VArray *source = (VArray*)CERTIFY(dump, VARRAY);
- VArray *loaded = VA_new(source->size);
- UNUSED_VAR(self);
-
- for (uint32_t i = 0, max = source->size; i < max; i++) {
- Obj *elem_dump = VA_Fetch(source, i);
- if (elem_dump) {
- VA_Store(loaded, i, Obj_Load(elem_dump, elem_dump));
- }
- }
-
- return loaded;
-}
-
-VArray*
-VA_clone(VArray *self) {
- VArray *twin = VA_new(self->size);
-
- // Clone each element.
- for (uint32_t i = 0; i < self->size; i++) {
- Obj *elem = self->elems[i];
- if (elem) {
- twin->elems[i] = Obj_Clone(elem);
- }
- }
-
- // Ensure that size is the same if NULL elems at end.
- twin->size = self->size;
-
- return twin;
-}
-
-VArray*
-VA_shallow_copy(VArray *self) {
- // Dupe, then increment refcounts.
- VArray *twin = VA_new(self->size);
- Obj **elems = twin->elems;
- memcpy(elems, self->elems, self->size * sizeof(Obj*));
- twin->size = self->size;
- for (uint32_t i = 0; i < self->size; i++) {
- if (elems[i] != NULL) {
- (void)INCREF(elems[i]);
- }
- }
-
- return twin;
-}
-
-void
-VA_push(VArray *self, Obj *element) {
- if (self->size == self->cap) {
- VA_Grow(self, Memory_oversize(self->size + 1, sizeof(Obj*)));
- }
- self->elems[self->size] = element;
- self->size++;
-}
-
-void
-VA_push_varray(VArray *self, VArray *other) {
- uint32_t tick = self->size;
- uint32_t new_size = self->size + other->size;
- if (new_size > self->cap) {
- VA_Grow(self, Memory_oversize(new_size, sizeof(Obj*)));
- }
- for (uint32_t i = 0; i < other->size; i++, tick++) {
- Obj *elem = VA_Fetch(other, i);
- if (elem != NULL) {
- self->elems[tick] = INCREF(elem);
- }
- }
- self->size = new_size;
-}
-
-Obj*
-VA_pop(VArray *self) {
- if (!self->size) {
- return NULL;
- }
- self->size--;
- return self->elems[self->size];
-}
-
-void
-VA_unshift(VArray *self, Obj *elem) {
- if (self->size == self->cap) {
- VA_Grow(self, Memory_oversize(self->size + 1, sizeof(Obj*)));
- }
- memmove(self->elems + 1, self->elems, self->size * sizeof(Obj*));
- self->elems[0] = elem;
- self->size++;
-}
-
-Obj*
-VA_shift(VArray *self) {
- if (!self->size) {
- return NULL;
- }
- else {
- Obj *const return_val = self->elems[0];
- self->size--;
- if (self->size > 0) {
- memmove(self->elems, self->elems + 1,
- self->size * sizeof(Obj*));
- }
- return return_val;
- }
-}
-
-Obj*
-VA_fetch(VArray *self, uint32_t num) {
- if (num >= self->size) {
- return NULL;
- }
-
- return self->elems[num];
-}
-
-void
-VA_store(VArray *self, uint32_t tick, Obj *elem) {
- if (tick >= self->cap) {
- VA_Grow(self, Memory_oversize(tick + 1, sizeof(Obj*)));
- }
- if (tick < self->size) { DECREF(self->elems[tick]); }
- else { self->size = tick + 1; }
- self->elems[tick] = elem;
-}
-
-void
-VA_grow(VArray *self, uint32_t capacity) {
- if (capacity > self->cap) {
- self->elems = (Obj**)REALLOCATE(self->elems, capacity * sizeof(Obj*));
- self->cap = capacity;
- memset(self->elems + self->size, 0,
- (capacity - self->size) * sizeof(Obj*));
- }
-}
-
-Obj*
-VA_delete(VArray *self, uint32_t num) {
- Obj *elem = NULL;
- if (num < self->size) {
- elem = self->elems[num];
- self->elems[num] = NULL;
- }
- return elem;
-}
-
-void
-VA_excise(VArray *self, uint32_t offset, uint32_t length) {
- if (self->size <= offset) { return; }
- else if (self->size < offset + length) { length = self->size - offset; }
-
- for (uint32_t i = 0; i < length; i++) {
- DECREF(self->elems[offset + i]);
- }
-
- uint32_t num_to_move = self->size - (offset + length);
- memmove(self->elems + offset, self->elems + offset + length,
- num_to_move * sizeof(Obj*));
- self->size -= length;
-}
-
-void
-VA_clear(VArray *self) {
- VA_excise(self, 0, self->size);
-}
-
-void
-VA_resize(VArray *self, uint32_t size) {
- if (size < self->size) {
- VA_Excise(self, size, self->size - size);
- }
- else if (size > self->size) {
- VA_Grow(self, size);
- }
- self->size = size;
-}
-
-uint32_t
-VA_get_size(VArray *self) {
- return self->size;
-}
-
-uint32_t
-VA_get_capacity(VArray *self) {
- return self->cap;
-}
-
-static int
-S_default_compare(void *context, const void *va, const void *vb) {
- Obj *a = *(Obj**)va;
- Obj *b = *(Obj**)vb;
- UNUSED_VAR(context);
- if (a != NULL && b != NULL) { return Obj_Compare_To(a, b); }
- else if (a == NULL && b == NULL) { return 0; }
- else if (a == NULL) { return 1; } // NULL to the back
- else /* b == NULL */ { return -1; } // NULL to the back
-}
-
-void
-VA_sort(VArray *self, Cfish_Sort_Compare_t compare, void *context) {
- if (!compare) { compare = S_default_compare; }
- Sort_quicksort(self->elems, self->size, sizeof(void*), compare, context);
-}
-
-bool
-VA_equals(VArray *self, Obj *other) {
- VArray *twin = (VArray*)other;
- if (twin == self) { return true; }
- if (!Obj_Is_A(other, VARRAY)) { return false; }
- if (twin->size != self->size) {
- return false;
- }
- else {
- for (uint32_t i = 0, max = self->size; i < max; i++) {
- Obj *val = self->elems[i];
- Obj *other_val = twin->elems[i];
- if ((val && !other_val) || (other_val && !val)) { return false; }
- if (val && !Obj_Equals(val, other_val)) { return false; }
- }
- }
- return true;
-}
-
-VArray*
-VA_gather(VArray *self, VA_Gather_Test_t test, void *data) {
- VArray *gathered = VA_new(self->size);
- for (uint32_t i = 0, max = self->size; i < max; i++) {
- if (test(self, i, data)) {
- Obj *elem = self->elems[i];
- VA_Push(gathered, elem ? INCREF(elem) : NULL);
- }
- }
- return gathered;
-}
-
-VArray*
-VA_slice(VArray *self, uint32_t offset, uint32_t length) {
- // Adjust ranges if necessary.
- if (offset >= self->size) {
- offset = 0;
- length = 0;
- }
- else if (length > UINT32_MAX - offset
- || offset + length > self->size
- ) {
- length = self->size - offset;
- }
-
- // Copy elements.
- VArray *slice = VA_new(length);
- slice->size = length;
- Obj **slice_elems = slice->elems;
- Obj **my_elems = self->elems;
- for (uint32_t i = 0; i < length; i++) {
- slice_elems[i] = INCREF(my_elems[offset + i]);
- }
-
- return slice;
-}
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/VArray.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/VArray.cfh b/core/Clownfish/VArray.cfh
deleted file mode 100644
index f171a7b..0000000
--- a/core/Clownfish/VArray.cfh
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-__C__
-#include "Clownfish/Util/SortUtils.h"
-
-typedef bool
-(*Cfish_VA_Gather_Test_t)(cfish_VArray *self, uint32_t tick, void *data);
-
-#ifdef CFISH_USE_SHORT_NAMES
- #define VA_Gather_Test_t Cfish_VA_Gather_Test_t
-#endif
-__END_C__
-
-/** Variable-sized array.
- */
-class Clownfish::VArray cnick VA inherits Clownfish::Obj {
-
- Obj **elems;
- uint32_t size;
- uint32_t cap;
-
- inert incremented VArray*
- new(uint32_t capacity);
-
- /**
- * @param capacity Initial number of elements that the object will be able
- * to hold before reallocation.
- */
- inert VArray*
- init(VArray *self, uint32_t capacity);
-
- /** Push an item onto the end of a VArray.
- */
- void
- Push(VArray *self, decremented Obj *element = NULL);
-
- /** Push all the elements of another VArray onto the end of this one.
- */
- void
- Push_VArray(VArray *self, VArray *other);
-
- /** Pop an item off of the end of a VArray.
- */
- incremented nullable Obj*
- Pop(VArray *self);
-
- /** Unshift an item onto the front of a VArray.
- */
- void
- Unshift(VArray *self, decremented Obj *element = NULL);
-
- /** Shift an item off of the front of a VArray.
- */
- incremented nullable Obj*
- Shift(VArray *self);
-
- /** Ensure that the VArray has room for at least <code>capacity</code>
- * elements.
- */
- void
- Grow(VArray *self, uint32_t capacity);
-
- /** Fetch the element at <code>tick</tick>.
- */
- nullable Obj*
- Fetch(VArray *self, uint32_t tick);
-
- /** Store an element at index <code>tick</code>, possibly displacing an
- * existing element.
- */
- void
- Store(VArray *self, uint32_t tick, decremented Obj *elem = NULL);
-
- /** Replace an element in the VArray with NULL and return it.
- *
- * @return whatever was stored at <code>tick</code>.
- */
- incremented nullable Obj*
- Delete(VArray *self, uint32_t tick);
-
- /** Remove <code>length</code> elements from the array, starting at
- * <code>offset</code>. Move elements over to fill in the gap.
- */
- void
- Excise(VArray *self, uint32_t offset, uint32_t length);
-
- /** Clone the VArray but merely increment the refcounts of its elements
- * rather than clone them.
- */
- incremented VArray*
- Shallow_Copy(VArray *self);
-
- /** Dupe the VArray, cloning each internal element.
- */
- public incremented VArray*
- Clone(VArray *self);
-
- /** Quicksort the VArry using the supplied comparison routine. Safety
- * checks are the responsibility of the caller.
- *
- * @param compare Comparison routine. The default uses Obj_Compare_To and
- * sorts NULL elements towards the end.
- * @param context Argument supplied to the comparison routine.
- */
- void
- Sort(VArray *self, Cfish_Sort_Compare_t compare = NULL,
- void *context = NULL);
-
- /** Set the size for the VArray. If the new size is larger than the
- * current size, grow the object to accommodate NULL elements; if smaller
- * than the current size, decrement and discard truncated elements.
- */
- void
- Resize(VArray *self, uint32_t size);
-
- /** Empty the VArray.
- */
- void
- Clear(VArray *self);
-
- /** Accessor for <code>size</code> member.
- */
- public uint32_t
- Get_Size(VArray *self);
-
- /** Accessor for <code>capacity</code> member.
- */
- uint32_t
- Get_Capacity(VArray *self);
-
- /** Return all elements for which <code>test</code> returns true.
- */
- public incremented VArray*
- Gather(VArray *self, Cfish_VA_Gather_Test_t test, void *data);
-
- /** Return a new array consisting of elements from a contiguous slice. If
- * the specified range is out of bounds, return an array with fewer
- * elements -- potentially none.
- *
- * @param offset The index of the element to start at.
- * @param length The maximum number of elements to slice.
- */
- public incremented VArray*
- Slice(VArray *self, uint32_t offset, uint32_t length);
-
- public bool
- Equals(VArray *self, Obj *other);
-
- public incremented VArray*
- Dump(VArray *self);
-
- public incremented VArray*
- Load(VArray *self, Obj *dump);
-
- public void
- Destroy(VArray *self);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/VTable.c b/core/Clownfish/VTable.c
deleted file mode 100644
index 8743d15..0000000
--- a/core/Clownfish/VTable.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_VTABLE
-#define C_CFISH_OBJ
-#define C_CFISH_CHARBUF
-#define C_CFISH_METHOD
-#define CFISH_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include <string.h>
-#include <ctype.h>
-
-#include "Clownfish/VTable.h"
-#include "Clownfish/CharBuf.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Hash.h"
-#include "Clownfish/LockFreeRegistry.h"
-#include "Clownfish/Method.h"
-#include "Clownfish/Num.h"
-#include "Clownfish/VArray.h"
-#include "Clownfish/Util/Atomic.h"
-#include "Clownfish/Util/Memory.h"
-
-size_t VTable_offset_of_parent = offsetof(VTable, parent);
-
-// Remove spaces and underscores, convert to lower case.
-static void
-S_scrunch_charbuf(CharBuf *source, CharBuf *target);
-
-LockFreeRegistry *VTable_registry = NULL;
-
-void
-VTable_bootstrap(VTableSpec *specs, size_t num_specs)
-{
- /* Pass 1:
- * - Allocate memory.
- * - Initialize parent, flags, obj_alloc_size, vt_alloc_size.
- * - Initialize method pointers.
- */
- for (size_t i = 0; i < num_specs; ++i) {
- VTableSpec *spec = &specs[i];
- VTable *parent = spec->parent ? *spec->parent : NULL;
-
- size_t vt_alloc_size = parent
- ? parent->vt_alloc_size
- : offsetof(VTable, method_ptrs);
- vt_alloc_size += spec->num_novel * sizeof(cfish_method_t);
- VTable *vtable = (VTable*)Memory_wrapped_calloc(vt_alloc_size, 1);
-
- vtable->parent = parent;
- vtable->flags = 0;
- vtable->obj_alloc_size = spec->obj_alloc_size;
- vtable->vt_alloc_size = vt_alloc_size;
-
- if (parent) {
- size_t parent_ptrs_size = parent->vt_alloc_size
- - offsetof(VTable, method_ptrs);
- memcpy(vtable->method_ptrs, parent->method_ptrs, parent_ptrs_size);
- }
-
- for (size_t i = 0; i < spec->num_fresh; ++i) {
- MethodSpec *mspec = &spec->method_specs[i];
- VTable_override(vtable, mspec->func, *mspec->offset);
- }
-
- *spec->vtable = vtable;
- }
-
- /* Pass 2:
- * - Initialize 'vtable' instance variable.
- * - Initialize refcount.
- */
- for (size_t i = 0; i < num_specs; ++i) {
- VTableSpec *spec = &specs[i];
- VTable *vtable = *spec->vtable;
-
- VTable_init_obj(VTABLE, vtable);
- }
-
- /* Now it's safe to call methods.
- *
- * Pass 3:
- * - Inititalize name and method array.
- * - Register vtable.
- */
- for (size_t i = 0; i < num_specs; ++i) {
- VTableSpec *spec = &specs[i];
- VTable *vtable = *spec->vtable;
-
- vtable->name = CB_newf("%s", spec->name);
- vtable->methods = VA_new(0);
-
- for (size_t i = 0; i < spec->num_fresh; ++i) {
- MethodSpec *mspec = &spec->method_specs[i];
- if (mspec->is_novel) {
- CharBuf *name = CB_newf("%s", mspec->name);
- Method *method = Method_new(name, mspec->callback_func,
- *mspec->offset);
- VA_Push(vtable->methods, (Obj*)method);
- DECREF(name);
- }
- }
-
- VTable_add_to_registry(vtable);
- }
-}
-
-void
-VTable_destroy(VTable *self) {
- THROW(ERR, "Insane attempt to destroy VTable for class '%o'", self->name);
-}
-
-VTable*
-VTable_clone(VTable *self) {
- VTable *twin
- = (VTable*)Memory_wrapped_calloc(self->vt_alloc_size, 1);
-
- memcpy(twin, self, self->vt_alloc_size);
- VTable_Init_Obj(self->vtable, twin); // Set refcount.
- twin->name = CB_Clone(self->name);
-
- return twin;
-}
-
-Obj*
-VTable_inc_refcount(VTable *self) {
- return (Obj*)self;
-}
-
-uint32_t
-VTable_dec_refcount(VTable *self) {
- UNUSED_VAR(self);
- return 1;
-}
-
-uint32_t
-VTable_get_refcount(VTable *self) {
- UNUSED_VAR(self);
- /* VTable_Get_RefCount() lies to other Clownfish code about the refcount
- * because we don't want to have to synchronize access to the cached host
- * object to which we have delegated responsibility for keeping refcounts.
- * It always returns 1 because 1 is a positive number, and thus other
- * Clownfish code will be fooled into believing it never needs to take
- * action such as initiating a destructor.
- *
- * It's possible that the host has in fact increased the refcount of the
- * cached host object if there are multiple refs to it on the other side
- * of the Clownfish/host border, but returning 1 is good enough to fool
- * Clownfish code.
- */
- return 1;
-}
-
-void
-VTable_override(VTable *self, cfish_method_t method, size_t offset) {
- union { char *char_ptr; cfish_method_t *func_ptr; } pointer;
- pointer.char_ptr = ((char*)self) + offset;
- pointer.func_ptr[0] = method;
-}
-
-CharBuf*
-VTable_get_name(VTable *self) {
- return self->name;
-}
-
-VTable*
-VTable_get_parent(VTable *self) {
- return self->parent;
-}
-
-size_t
-VTable_get_obj_alloc_size(VTable *self) {
- return self->obj_alloc_size;
-}
-
-void
-VTable_init_registry() {
- LockFreeRegistry *reg = LFReg_new(256);
- if (Atomic_cas_ptr((void*volatile*)&VTable_registry, NULL, reg)) {
- return;
- }
- else {
- DECREF(reg);
- }
-}
-
-VTable*
-VTable_singleton(const CharBuf *class_name, VTable *parent) {
- if (VTable_registry == NULL) {
- VTable_init_registry();
- }
-
- VTable *singleton = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
- if (singleton == NULL) {
- VArray *fresh_host_methods;
- uint32_t num_fresh;
-
- if (parent == NULL) {
- CharBuf *parent_class = VTable_find_parent_class(class_name);
- if (parent_class == NULL) {
- THROW(ERR, "Class '%o' doesn't descend from %o", class_name,
- OBJ->name);
- }
- else {
- parent = VTable_singleton(parent_class, NULL);
- DECREF(parent_class);
- }
- }
-
- // Copy source vtable.
- singleton = VTable_Clone(parent);
-
- // Turn clone into child.
- singleton->parent = parent;
- DECREF(singleton->name);
- singleton->name = CB_Clone(class_name);
-
- // Allow host methods to override.
- fresh_host_methods = VTable_fresh_host_methods(class_name);
- num_fresh = VA_Get_Size(fresh_host_methods);
- if (num_fresh) {
- Hash *meths = Hash_new(num_fresh);
- CharBuf *scrunched = CB_new(0);
- for (uint32_t i = 0; i < num_fresh; i++) {
- CharBuf *meth = (CharBuf*)VA_fetch(fresh_host_methods, i);
- S_scrunch_charbuf(meth, scrunched);
- Hash_Store(meths, (Obj*)scrunched, (Obj*)CFISH_TRUE);
- }
- for (VTable *vtable = parent; vtable; vtable = vtable->parent) {
- uint32_t max = VA_Get_Size(vtable->methods);
- for (uint32_t i = 0; i < max; i++) {
- Method *method = (Method*)VA_Fetch(vtable->methods, i);
- if (method->callback_func) {
- S_scrunch_charbuf(method->name, scrunched);
- if (Hash_Fetch(meths, (Obj*)scrunched)) {
- VTable_Override(singleton, method->callback_func,
- method->offset);
- }
- }
- }
- }
- DECREF(scrunched);
- DECREF(meths);
- }
- DECREF(fresh_host_methods);
-
- // Register the new class, both locally and with host.
- if (VTable_add_to_registry(singleton)) {
- // Doing this after registering is racy, but hard to fix. :(
- VTable_register_with_host(singleton, parent);
- }
- else {
- DECREF(singleton);
- singleton = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
- if (!singleton) {
- THROW(ERR, "Failed to either insert or fetch VTable for '%o'",
- class_name);
- }
- }
- }
-
- return singleton;
-}
-
-Obj*
-VTable_load_obj(VTable *self, Obj *dump) {
- Obj_Load_t load = METHOD_PTR(self, Cfish_Obj_Load);
- if (load == Obj_load) {
- THROW(ERR, "Abstract method Load() not defined for %o", self->name);
- }
- Obj *invoker = VTable_Make_Obj(self);
- Obj *loaded = load(invoker, dump);
- DECREF(invoker);
- return loaded;
-}
-
-static void
-S_scrunch_charbuf(CharBuf *source, CharBuf *target) {
- ZombieCharBuf *iterator = ZCB_WRAP(source);
- CB_Set_Size(target, 0);
- while (ZCB_Get_Size(iterator)) {
- uint32_t code_point = ZCB_Nip_One(iterator);
- if (code_point > 127) {
- THROW(ERR, "Can't fold case for %o", source);
- }
- else if (code_point != '_') {
- CB_Cat_Char(target, tolower(code_point));
- }
- }
-}
-
-bool
-VTable_add_to_registry(VTable *vtable) {
- if (VTable_registry == NULL) {
- VTable_init_registry();
- }
- if (LFReg_Fetch(VTable_registry, (Obj*)vtable->name)) {
- return false;
- }
- else {
- CharBuf *klass = CB_Clone(vtable->name);
- bool retval
- = LFReg_Register(VTable_registry, (Obj*)klass, (Obj*)vtable);
- DECREF(klass);
- return retval;
- }
-}
-
-bool
-VTable_add_alias_to_registry(VTable *vtable, CharBuf *alias) {
- if (VTable_registry == NULL) {
- VTable_init_registry();
- }
- if (LFReg_Fetch(VTable_registry, (Obj*)alias)) {
- return false;
- }
- else {
- CharBuf *klass = CB_Clone(alias);
- bool retval
- = LFReg_Register(VTable_registry, (Obj*)klass, (Obj*)vtable);
- DECREF(klass);
- return retval;
- }
-}
-
-VTable*
-VTable_fetch_vtable(const CharBuf *class_name) {
- VTable *vtable = NULL;
- if (VTable_registry != NULL) {
- vtable = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
- }
- return vtable;
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/Clownfish/VTable.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/VTable.cfh b/core/Clownfish/VTable.cfh
deleted file mode 100644
index 1325fd4..0000000
--- a/core/Clownfish/VTable.cfh
+++ /dev/null
@@ -1,149 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-/** Virtual method dispatch table.
- *
- * VTables, which are the first element in any Clownfish object, are actually
- * objects themselves. (Their first element is a VTable which describes the
- * behavior of VTables.)
- */
-
-class Clownfish::VTable inherits Clownfish::Obj {
-
- VTable *parent;
- CharBuf *name;
- uint32_t flags;
- size_t obj_alloc_size;
- size_t vt_alloc_size;
- VArray *methods;
- cfish_method_t[1] method_ptrs; /* flexible array */
-
- inert LockFreeRegistry *registry;
- inert size_t offset_of_parent;
-
- inert void
- bootstrap(cfish_VTableSpec *specs, size_t num_specs);
-
- /** Return a singleton. If a VTable can be found in the registry based on
- * the supplied class name, it will be returned. Otherwise, a new VTable
- * will be created using [parent] as a base.
- *
- * If [parent] is NULL, an attempt will be made to find it using
- * VTable_find_parent_class(). If the attempt fails, an error will
- * result.
- */
- inert VTable*
- singleton(const CharBuf *class_name, VTable *parent);
-
- /** Register a vtable, so that it can be retrieved by class name.
- *
- * TODO: Move this functionality to some kind of class loader.
- *
- * @return true on success, false if the class was already registered.
- */
- inert bool
- add_to_registry(VTable *vtable);
-
- inert bool
- add_alias_to_registry(VTable *vtable, CharBuf *alias);
-
- /** Initialize the registry.
- */
- inert void
- init_registry();
-
- /** Tell the host about the new class.
- */
- inert void
- register_with_host(VTable *vtable, VTable *parent);
-
- /** Find a registered class and return its vtable. May return NULL if the
- * class is not registered.
- */
- inert nullable VTable*
- fetch_vtable(const CharBuf *class_name);
-
- /** Given a class name, return the name of a parent class which descends
- * from Clownfish::Obj, or NULL if such a class can't be found.
- */
- inert nullable CharBuf*
- find_parent_class(const CharBuf *class_name);
-
- /** List all of the methods defined directly within a host subclass.
- */
- inert incremented VArray*
- fresh_host_methods(const CharBuf *class_name);
-
- /** Replace a function pointer in the VTable.
- */
- void
- Override(VTable *self, cfish_method_t method_ptr, size_t offset);
-
- /** Create an empty object of the type defined by the VTable: allocate,
- * assign its vtable and give it an initial refcount of 1. The caller is
- * responsible for initialization.
- */
- Obj*
- Make_Obj(VTable *self);
-
- /** Take a raw memory allocation which is presumed to be of adequate size,
- * assign its vtable and give it an initial refcount of 1.
- */
- Obj*
- Init_Obj(VTable *self, void *allocation);
-
- /** Create a new object using the supplied dump, assuming that Load() has
- * been defined for the class.
- */
- Obj*
- Load_Obj(VTable *self, Obj *dump);
-
- /** Create a new object to go with the supplied host object.
- */
- Obj*
- Foster_Obj(VTable *self, void *host_obj);
-
- CharBuf*
- Get_Name(VTable *self);
-
- VTable*
- Get_Parent(VTable *self);
-
- size_t
- Get_Obj_Alloc_Size(VTable *self);
-
- public incremented VTable*
- Clone(VTable *self);
-
- incremented Obj*
- Inc_RefCount(VTable *self);
-
- uint32_t
- Dec_RefCount(VTable *self);
-
- uint32_t
- Get_RefCount(VTable *self);
-
- void*
- To_Host(VTable *self);
-
- public void
- Destroy(VTable *self);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/TestClownfish.c
----------------------------------------------------------------------
diff --git a/core/TestClownfish.c b/core/TestClownfish.c
deleted file mode 100644
index a946163..0000000
--- a/core/TestClownfish.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-void
-testcfish_init_parcel() {
-}
-
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/core/TestClownfish.cfp
----------------------------------------------------------------------
diff --git a/core/TestClownfish.cfp b/core/TestClownfish.cfp
deleted file mode 100644
index f1c9411..0000000
--- a/core/TestClownfish.cfp
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "TestClownfish",
- "nickname": "TestCfish",
- "version": "v0.3.0"
-}
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/perl/Build.PL
----------------------------------------------------------------------
diff --git a/perl/Build.PL b/perl/Build.PL
index 8c7307a..5c07e2e 100644
--- a/perl/Build.PL
+++ b/perl/Build.PL
@@ -30,6 +30,10 @@ my $UTF8PROC_SRC_DIR = catdir( $MODULES_DIR, qw( unicode utf8proc ) );
my $CORE_SOURCE_DIR = catdir( @BASE_PATH, 'core' );
my $XS_SOURCE_DIR = 'xs';
+my $CFR_DIR = catdir( @BASE_PATH, qw( clownfish runtime ) );
+my $CFR_CORE_SOURCE_DIR = catdir( $CFR_DIR, 'core' );
+my $CFR_XS_SOURCE_DIR = catdir( $CFR_DIR, qw( perl xs ) );
+
my $builder = Lucy::Build->new(
module_name => 'Lucy',
license => 'apache',
@@ -58,6 +62,7 @@ my $builder = Lucy::Build->new(
$SNOWSTEM_INC_DIR,
$UCD_INC_DIR,
$UTF8PROC_SRC_DIR,
+ $CFR_XS_SOURCE_DIR,
],
clownfish_params => {
source => [
@@ -67,10 +72,11 @@ my $builder = Lucy::Build->new(
$SNOWSTOP_SRC_DIR,
$UTF8PROC_SRC_DIR,
],
+ include => [
+ $CFR_CORE_SOURCE_DIR,
+ ],
},
- extra_compiler_flags => join( ' ', map { "-DCFP_$_" } qw(
- CFISH TESTCFISH LUCY TESTLUCY
- ) ),
+ extra_compiler_flags => '-DCFP_LUCY -DCFP_TESTLUCY',
add_to_cleanup => [
qw(
Lucy-*
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/perl/buildlib/Lucy/Build.pm
----------------------------------------------------------------------
diff --git a/perl/buildlib/Lucy/Build.pm b/perl/buildlib/Lucy/Build.pm
index 27ee95a..97016ed 100644
--- a/perl/buildlib/Lucy/Build.pm
+++ b/perl/buildlib/Lucy/Build.pm
@@ -50,8 +50,10 @@ my $CHARMONIZER_C = catfile( $COMMON_SOURCE_DIR, 'charmonizer.c' );
my $LEMON_DIR = catdir( @BASE_PATH, 'lemon' );
my $LEMON_EXE_PATH = catfile( $LEMON_DIR, "lemon$Config{_exe}" );
my $CORE_SOURCE_DIR = catdir( @BASE_PATH, 'core' );
-my $CLOWNFISH_DIR = catdir( @BASE_PATH, 'clownfish', 'compiler', 'perl' );
-my $CLOWNFISH_BUILD = catfile( $CLOWNFISH_DIR, 'Build' );
+my $CFC_DIR = catdir( @BASE_PATH, 'clownfish', 'compiler', 'perl' );
+my $CFC_BUILD = catfile( $CFC_DIR, 'Build' );
+my $CFR_DIR = catdir( @BASE_PATH, 'clownfish', 'runtime', 'perl' );
+my $CFR_BUILD = catfile( $CFR_DIR, 'Build' );
my $LIB_DIR = 'lib';
sub new {
@@ -119,7 +121,7 @@ sub ACTION_lemon {
sub ACTION_cfc {
my $self = shift;
my $old_dir = getcwd();
- chdir($CLOWNFISH_DIR);
+ chdir($CFC_DIR);
if ( !-f 'Build' ) {
print "\nBuilding Clownfish compiler... \n";
system("$^X Build.PL");
@@ -129,6 +131,19 @@ sub ACTION_cfc {
chdir($old_dir);
}
+sub ACTION_cfr {
+ my $self = shift;
+ my $old_dir = getcwd();
+ chdir($CFR_DIR);
+ if ( !-f 'Build' ) {
+ print "\nBuilding Clownfish runtime... \n";
+ system("$^X Build.PL");
+ system("$^X Build code");
+ print "\nFinished building Clownfish runtime.\n\n";
+ }
+ chdir($old_dir);
+}
+
sub ACTION_copy_clownfish_includes {
my $self = shift;
@@ -146,10 +161,22 @@ sub ACTION_clownfish {
$self->dispatch('charmonizer_tests');
$self->dispatch('cfc');
+ $self->dispatch('cfr');
$self->SUPER::ACTION_clownfish;
}
+sub ACTION_test {
+ my $self = shift;
+
+ # Add blib dirs of Clownfish runtime to @INC
+ local @INC = @INC;
+ push( @INC, catdir( $CFR_DIR, qw( blib lib ) ) );
+ push( @INC, catdir( $CFR_DIR, qw( blib arch ) ) );
+
+ $self->SUPER::ACTION_test;
+}
+
sub ACTION_suppressions {
my $self = shift;
my $LOCAL_SUPP = 'local.supp';
@@ -451,11 +478,18 @@ sub ACTION_semiclean {
# Run the cleanup targets for independent prerequisite builds.
sub _clean_prereq_builds {
my $self = shift;
- if ( -e $CLOWNFISH_BUILD ) {
+ if ( -e $CFC_BUILD ) {
+ my $old_dir = getcwd();
+ chdir $CFC_DIR;
+ system("$^X Build realclean")
+ and die "Clownfish compiler clean failed";
+ chdir $old_dir;
+ }
+ if ( -e $CFR_BUILD ) {
my $old_dir = getcwd();
- chdir $CLOWNFISH_DIR;
+ chdir $CFR_DIR;
system("$^X Build realclean")
- and die "Clownfish clean failed";
+ and die "Clownfish runtime clean failed";
chdir $old_dir;
}
$self->_run_make( dir => $CHARMONIZER_ORIG_DIR, args => ['clean'] );
http://git-wip-us.apache.org/repos/asf/lucy/blob/ddff7ce9/perl/buildlib/Lucy/Build/Binding/Misc.pm
----------------------------------------------------------------------
diff --git a/perl/buildlib/Lucy/Build/Binding/Misc.pm b/perl/buildlib/Lucy/Build/Binding/Misc.pm
index ea93437..02fcf76 100644
--- a/perl/buildlib/Lucy/Build/Binding/Misc.pm
+++ b/perl/buildlib/Lucy/Build/Binding/Misc.pm
@@ -22,8 +22,7 @@ $VERSION = eval $VERSION;
sub bind_all {
my $class = shift;
$class->bind_lucy;
- $class->bind_cfish_test;
- $class->bind_lucy_test;
+ $class->bind_test;
$class->bind_testschema;
$class->bind_bbsortex;
}
@@ -151,37 +150,7 @@ END_XS_CODE
Clownfish::CFC::Binding::Perl::Class->register($binding);
}
-sub bind_cfish_test {
- my $xs_code = <<'END_XS_CODE';
-MODULE = Lucy PACKAGE = Clownfish::Test
-
-bool
-run_tests(package)
- char *package;
-CODE:
- cfish_CharBuf *class_name = cfish_CB_newf("%s", package);
- cfish_TestFormatter *formatter
- = (cfish_TestFormatter*)cfish_TestFormatterTAP_new();
- cfish_TestSuite *suite = testcfish_Test_create_test_suite();
- bool result = Cfish_TestSuite_Run_Batch(suite, class_name, formatter);
- CFISH_DECREF(class_name);
- CFISH_DECREF(formatter);
- CFISH_DECREF(suite);
-
- RETVAL = result;
-OUTPUT: RETVAL
-END_XS_CODE
-
- my $binding = Clownfish::CFC::Binding::Perl::Class->new(
- parcel => "TestClownfish",
- class_name => "Clownfish::Test",
- );
- $binding->append_xs($xs_code);
-
- Clownfish::CFC::Binding::Perl::Class->register($binding);
-}
-
-sub bind_lucy_test {
+sub bind_test {
my $xs_code = <<'END_XS_CODE';
MODULE = Lucy PACKAGE = Lucy::Test