Skip to content
This repository was archived by the owner on Jun 27, 2025. It is now read-only.

Commit 331d744

Browse files
authored
Merge pull request #18 from static-frame/15/get-end
Refinements to `char_get_end_p()`
2 parents a386b0c + 36040b4 commit 331d744

File tree

3 files changed

+62
-32
lines changed

3 files changed

+62
-32
lines changed

arraymap.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,26 +122,26 @@ typedef enum ViewKind{
122122
} ViewKind;
123123

124124

125-
// NOTE: would like to use strchr(str, '\0') instead of this routine, but some buffers might not have a null terminator and stread by full to the the dt_size.
125+
// Return the end pointer, or the pointer to the location after the last valid character. The end pointer minus the start pointer is the number of characters. For an empty string, all characters are NULL, and the start pointer and end pointer should be equal. NOTE: would like to use strchr(str, '\0') instead of this routine, but some buffers might not have a null terminator and stread by full to the the dt_size.
126126
static inline Py_UCS4*
127127
ucs4_get_end_p(Py_UCS4* p_start, Py_ssize_t dt_size) {
128-
Py_UCS4* p;
129-
for (p = p_start + dt_size - 1; p >= p_start; p--) {
128+
for (Py_UCS4* p = p_start + dt_size - 1; p >= p_start; p--) {
130129
if (*p != '\0') {
131-
return p + 1; // return 1 more than the first non-null from the right
130+
return p + 1; // 1 after first non-null
132131
}
133132
}
134-
return p; // p is equal to p_start
133+
return p_start;
135134
}
136135

137136

138137
static inline char*
139-
char_get_end_p(char* p, Py_ssize_t dt_size) {
140-
char* p_end = p + dt_size;
141-
while (p < p_end && *p != '\0') {
142-
p++;
138+
char_get_end_p(char* p_start, Py_ssize_t dt_size) {
139+
for (char* p = p_start + dt_size - 1; p >= p_start; p--) {
140+
if (*p != '\0') {
141+
return p + 1; // 1 after first non-null
142+
}
143143
}
144-
return p;
144+
return p_start;
145145
}
146146

147147

doc/articles/npy-opt.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -343,28 +343,34 @@ def get_array(size: int) -> np.ndarray:
343343

344344

345345
def get_string_array(size: int, char_count: int, kind: str) -> str:
346-
fmt = f'-<{char_count}'
346+
fmt = f"-<{char_count}"
347347
array = np.array(
348-
[f'{hex(e) * (char_count // 8)}'.format(fmt) for e in range(INT_START, INT_START + size)],
349-
dtype=f'{kind}{char_count}')
348+
[
349+
f"{hex(e) * (char_count // 8)}".format(fmt)
350+
for e in range(INT_START, INT_START + size)
351+
],
352+
dtype=f"{kind}{char_count}",
353+
)
350354
array.flags.writeable = False
351355
return array
352356

357+
353358
class FFU8(FixtureFactory):
354359
NAME = "U8"
355360
SORT = 6
356361

357362
@staticmethod
358363
def get_array(size: int) -> np.ndarray:
359-
return get_string_array(size, 8, 'U')
364+
return get_string_array(size, 8, "U")
365+
360366

361367
class FFU16(FixtureFactory):
362368
NAME = "U16"
363369
SORT = 7
364370

365371
@staticmethod
366372
def get_array(size: int) -> np.ndarray:
367-
return get_string_array(size, 16, 'U')
373+
return get_string_array(size, 16, "U")
368374

369375

370376
class FFU32(FixtureFactory):
@@ -373,7 +379,7 @@ class FFU32(FixtureFactory):
373379

374380
@staticmethod
375381
def get_array(size: int) -> np.ndarray:
376-
return get_string_array(size, 32, 'U')
382+
return get_string_array(size, 32, "U")
377383

378384

379385
class FFU64(FixtureFactory):
@@ -382,7 +388,7 @@ class FFU64(FixtureFactory):
382388

383389
@staticmethod
384390
def get_array(size: int) -> np.ndarray:
385-
return get_string_array(size, 64, 'U')
391+
return get_string_array(size, 64, "U")
386392

387393

388394
class FFU128(FixtureFactory):
@@ -391,7 +397,7 @@ class FFU128(FixtureFactory):
391397

392398
@staticmethod
393399
def get_array(size: int) -> np.ndarray:
394-
return get_string_array(size, 128, 'U')
400+
return get_string_array(size, 128, "U")
395401

396402

397403
class FFS8(FixtureFactory):
@@ -400,15 +406,16 @@ class FFS8(FixtureFactory):
400406

401407
@staticmethod
402408
def get_array(size: int) -> np.ndarray:
403-
return get_string_array(size, 8, 'S')
409+
return get_string_array(size, 8, "S")
410+
404411

405412
class FFS16(FixtureFactory):
406413
NAME = "S16"
407414
SORT = 12
408415

409416
@staticmethod
410417
def get_array(size: int) -> np.ndarray:
411-
return get_string_array(size, 16, 'S')
418+
return get_string_array(size, 16, "S")
412419

413420

414421
class FFS32(FixtureFactory):
@@ -417,7 +424,7 @@ class FFS32(FixtureFactory):
417424

418425
@staticmethod
419426
def get_array(size: int) -> np.ndarray:
420-
return get_string_array(size, 32, 'S')
427+
return get_string_array(size, 32, "S")
421428

422429

423430
class FFS64(FixtureFactory):
@@ -426,17 +433,16 @@ class FFS64(FixtureFactory):
426433

427434
@staticmethod
428435
def get_array(size: int) -> np.ndarray:
429-
return get_string_array(size, 64, 'S')
436+
return get_string_array(size, 64, "S")
437+
430438

431439
class FFS128(FixtureFactory):
432440
NAME = "S128"
433441
SORT = 15
434442

435443
@staticmethod
436444
def get_array(size: int) -> np.ndarray:
437-
return get_string_array(size, 128, 'S')
438-
439-
445+
return get_string_array(size, 128, "S")
440446

441447

442448
# class FFBytes(FixtureFactory):
@@ -486,7 +492,6 @@ def get_versions() -> str:
486492
FFU32,
487493
FFU64,
488494
FFU128,
489-
490495
FFS8,
491496
FFS16,
492497
FFS32,
@@ -550,11 +555,11 @@ def plot_performance(frame, suffix: str = ""):
550555
time_min = fixture["time"].min()
551556
y_ticks = [0, time_min, time_max * 0.5, time_max]
552557
y_labels = [
553-
"",
554-
seconds_to_display(time_min),
555-
seconds_to_display(time_max * 0.5),
556-
seconds_to_display(time_max),
557-
]
558+
"",
559+
seconds_to_display(time_min),
560+
seconds_to_display(time_max * 0.5),
561+
seconds_to_display(time_max),
562+
]
558563
if time_min > time_max * 0.25:
559564
# remove the min if it is greater than quarter
560565
y_ticks.pop(1)
@@ -571,7 +576,7 @@ def plot_performance(frame, suffix: str = ""):
571576
ax.tick_params(
572577
axis="y",
573578
length=2,
574-
width=.5,
579+
width=0.5,
575580
pad=1,
576581
)
577582
fig.set_size_inches(9, 3) # width, height

test/test_unit.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,20 @@ def test_fam_copy_array_bytes_a():
234234
# ------------------------------------------------------------------------------
235235

236236

237+
def test_fam_array_bytes_get_a():
238+
a1 = np.array((b"", b" ", b" ", b" "))
239+
a1.flags.writeable = False
240+
fam = FrozenAutoMap(a1)
241+
242+
assert fam.get(b"") == 0
243+
assert fam.get(b" ") == None
244+
assert fam.get(b" ") == 2
245+
assert fam.get(b" ") == 3
246+
247+
248+
# ------------------------------------------------------------------------------
249+
250+
237251
def test_fam_array_len_a():
238252
a1 = np.array((10, 20, 30, 40), dtype=np.int64)
239253
a1.flags.writeable = False
@@ -577,6 +591,17 @@ def test_fam_array_unicode_get_a():
577591
assert fam.get("cccc") is None
578592

579593

594+
def test_fam_array_unicode_get_b():
595+
a1 = np.array(("", " ", " ", " "))
596+
a1.flags.writeable = False
597+
fam = FrozenAutoMap(a1)
598+
599+
assert fam.get("") == 0
600+
assert fam.get(" ") == None
601+
assert fam.get(" ") == 2
602+
assert fam.get(" ") == 3
603+
604+
580605
# ------------------------------------------------------------------------------
581606

582607

0 commit comments

Comments
 (0)