if (nxt_fast_path(p != NULL)) {
memcpy(p, start, size);
- if (size != length && length >= NJS_STRING_MAP_OFFSET) {
+ if (size != length && length >= NJS_STRING_MAP_STRIDE) {
njs_string_offset_map_init(p, size);
}
value->data.external0 = 0;
value->data.string_size = size;
- if (size != length && length > NJS_STRING_MAP_OFFSET) {
- total = nxt_align_size(size, sizeof(uint32_t));
- total += ((length - 1) / NJS_STRING_MAP_OFFSET) * sizeof(uint32_t);
+ if (size != length && length > NJS_STRING_MAP_STRIDE) {
+ total = njs_string_map_offset(size) + njs_string_map_size(length);
} else {
total = size;
return length;
}
- if (length > NJS_STRING_MAP_OFFSET) {
+ if (length > NJS_STRING_MAP_STRIDE) {
/*
* Reallocate the long string with offset map
* after the string.
*/
- new_size = nxt_align_size(size, sizeof(uint32_t));
- new_size += ((length - 1) / NJS_STRING_MAP_OFFSET)
- * sizeof(uint32_t);
+ new_size = njs_string_map_offset(size)
+ + njs_string_map_size(length);
start = nxt_mem_cache_alloc(vm->mem_cache_pool, new_size);
if (nxt_slow_path(start == NULL)) {
const u_char *p, *end;
end = start + size;
- map = (uint32_t *) nxt_align_ptr(end, sizeof(uint32_t));
+ map = njs_string_map_start(end);
p = start;
n = 0;
- offset = NJS_STRING_MAP_OFFSET;
+ offset = NJS_STRING_MAP_STRIDE;
do {
if (offset == 0) {
map[n++] = p - start;
- offset = NJS_STRING_MAP_OFFSET;
+ offset = NJS_STRING_MAP_STRIDE;
}
/* The UTF-8 string should be valid since its length is known. */
p += string.size;
}
- if (length >= NJS_STRING_MAP_OFFSET && size != length) {
+ if (length >= NJS_STRING_MAP_STRIDE && size != length) {
njs_string_offset_map_init(start, size);
}
if (length >= 0) {
- if (length < NJS_STRING_MAP_OFFSET || (size_t) length == slice.length) {
+ if (length < NJS_STRING_MAP_STRIDE || (size_t) length == slice.length) {
/* ASCII or short UTF-8 string. */
return njs_string_create(vm, &vm->retval, string.start,
slice.length, length);
s = nxt_utf8_encode(s, *p);
}
- if (slice.length >= NJS_STRING_MAP_OFFSET || size != slice.length) {
+ if (slice.length >= NJS_STRING_MAP_STRIDE || size != slice.length) {
njs_string_offset_map_init(start, size);
}
}
uint32_t *map;
nxt_uint_t skip;
- if (index >= NJS_STRING_MAP_OFFSET) {
- map = (uint32_t *) nxt_align_ptr(end, sizeof(uint32_t));
+ if (index >= NJS_STRING_MAP_STRIDE) {
+ map = njs_string_map_start(end);
- start += map[index / NJS_STRING_MAP_OFFSET - 1];
+ start += map[index / NJS_STRING_MAP_STRIDE - 1];
}
- for (skip = index % NJS_STRING_MAP_OFFSET; skip != 0; skip--) {
+ for (skip = index % NJS_STRING_MAP_STRIDE; skip != 0; skip--) {
start = nxt_utf8_next(start, end);
}
last = 0;
index = 0;
- if (string->length >= NJS_STRING_MAP_OFFSET) {
+ if (string->length >= NJS_STRING_MAP_STRIDE) {
end = string->start + string->size;
- map = (uint32_t *) nxt_align_ptr(end, sizeof(uint32_t));
+ map = njs_string_map_start(end);
- while (index + NJS_STRING_MAP_OFFSET < string->length
+ while (index + NJS_STRING_MAP_STRIDE < string->length
&& *map <= offset)
{
last = *map++;
- index += NJS_STRING_MAP_OFFSET;
+ index += NJS_STRING_MAP_STRIDE;
}
}
size--;
}
- if (string.length >= NJS_STRING_MAP_OFFSET) {
+ if (string.length >= NJS_STRING_MAP_STRIDE) {
njs_string_offset_map_init(start, string.size);
}
}
size--;
}
- if (string.length >= NJS_STRING_MAP_OFFSET) {
+ if (string.length >= NJS_STRING_MAP_STRIDE) {
njs_string_offset_map_init(start, string.size);
}
}
n--;
}
- if (length >= NJS_STRING_MAP_OFFSET && size != length) {
+ if (length >= NJS_STRING_MAP_STRIDE && size != length) {
njs_string_offset_map_init(start, size);
}
/* GC: release valid values. */
}
- if (length >= NJS_STRING_MAP_OFFSET && size != length) {
+ if (length >= NJS_STRING_MAP_STRIDE && size != length) {
njs_string_offset_map_init(string, size);
}
length = src->data.u.string->length;
- if (size != length && length > NJS_STRING_MAP_OFFSET) {
- size = nxt_align_size(size, sizeof(uint32_t));
- size += ((length - 1) / NJS_STRING_MAP_OFFSET)
- * sizeof(uint32_t);
+ if (size != length && length > NJS_STRING_MAP_STRIDE) {
+ size = njs_string_map_offset(size)
+ + njs_string_map_size(length);
}
}
* division and remainder operations but no less than 16 because the maximum
* length of short string inlined in njs_value_t is less than 16 bytes.
*/
-#define NJS_STRING_MAP_OFFSET 32
+#define NJS_STRING_MAP_STRIDE 32
+
+#define njs_string_map_offset(size) nxt_align_size((size), sizeof(uint32_t))
+
+#define njs_string_map_start(p) \
+ ((uint32_t *) nxt_align_ptr((p), sizeof(uint32_t)))
+
+#define njs_string_map_size(length) \
+ (((length - 1) / NJS_STRING_MAP_STRIDE) * sizeof(uint32_t))
/*
* The JavaScript standard states that strings are stored in UTF-16.
* encoding does not allow to get quickly a character at specified position.
* To speed up this search a map of offsets is stored after the UTF-8 string.
* The map is aligned to uint32_t and contains byte positions of each
- * NJS_STRING_MAP_OFFSET UTF-8 character except zero position. The map
+ * NJS_STRING_MAP_STRIDE UTF-8 character except zero position. The map
* can be allocated and updated on demand. If a string come outside
* JavaScript as byte sequnece just to be concatenated or to be used in
* regular expressions the offset map is not required.
* 1) if the length is zero hence it is a byte string;
* 2) if the size and length are equal so the string contains only ASCII
* characters map is not required;
- * 3) if the length is less than NJS_STRING_MAP_OFFSET.
+ * 3) if the length is less than NJS_STRING_MAP_STRIDE.
*
* The current implementation does not support Unicode surrogate pairs.
* If offset in map points to surrogate pair then the previous offset