Skip to content

Commit bc23f0f

Browse files
authored
Destructive vector-push! (#3258)
1 parent 40082d1 commit bc23f0f

File tree

11 files changed

+753
-1252
lines changed

11 files changed

+753
-1252
lines changed

prelude.scm

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,7 @@
15241524
list->bytevector
15251525
bytevector->list)
15261526

1527-
(import (stak base) (only (srfi 1) fold last))
1527+
(import (stak base) (only (srfi 1) last))
15281528

15291529
(begin
15301530
; Vector
@@ -1537,20 +1537,24 @@
15371537

15381538
(define vector? (instance? vector-type))
15391539
(define vector-length car)
1540+
(define vector-set-length! set-car!)
15401541
(define vector-root cdr)
1542+
(define vector-set-root! set-cdr!)
15411543

15421544
(define (make-vector* length root)
15431545
(data-rib vector-type length root))
15441546

1545-
(define empty-vector (make-vector* 0 '()))
1547+
(define (empty-vector)
1548+
(make-vector* 0 '()))
15461549

15471550
(define (make-vector length . rest)
15481551
(define fill (and (pair? rest) (car rest)))
15491552

1550-
(do ((xs empty-vector (vector-push xs fill))
1553+
(do ((xs (empty-vector))
15511554
(index 0 (+ index 1)))
15521555
((>= index length)
1553-
xs)))
1556+
xs)
1557+
(vector-push! xs fill)))
15541558

15551559
(define (vector . xs)
15561560
(list->vector xs))
@@ -1581,39 +1585,40 @@
15811585
(set-car! (vector-cell xs index) x))
15821586

15831587
(define (vector-append . rest)
1584-
(fold
1585-
(lambda (xs ys)
1586-
(do ((xs xs (vector-push xs (vector-ref ys index)))
1587-
(index 0 (+ index 1)))
1588-
((= index (vector-length ys))
1589-
xs)))
1590-
empty-vector
1591-
rest))
1592-
1593-
(define (vector-push xs x)
1594-
(make-vector*
1595-
(+ (vector-length xs) 1)
1596-
(let ((result
1597-
(let loop ((xs (vector-root xs))
1598-
(h (vector-height xs)))
1599-
(let ((n (length xs)))
1600-
(if (zero? h)
1601-
(node-push xs n x)
1602-
(let* ((result (loop (last xs) (- h 1)))
1603-
(y (car result))
1604-
(xs (list-copy xs)))
1605-
(list-set! xs (- n 1) y)
1606-
(if (pair? (cdr result))
1607-
(node-push xs n (cdr result))
1608-
(list xs))))))))
1609-
(if (pair? (cdr result))
1610-
(list (car result) (cdr result))
1611-
(car result)))))
1612-
1613-
(define (node-push xs n x)
1614-
(if (< n factor)
1615-
(list (append xs (list x)))
1616-
(list xs x)))
1588+
(let ((ys (empty-vector)))
1589+
(for-each
1590+
(lambda (xs)
1591+
(vector-for-each
1592+
(lambda (x) (vector-push! ys x))
1593+
xs))
1594+
rest)
1595+
ys))
1596+
1597+
(define (vector-push! xs x)
1598+
(vector-set-root!
1599+
xs
1600+
(let ((root (vector-root xs)))
1601+
(if (null? root)
1602+
(list x)
1603+
(let ((ys
1604+
(let loop ((xs root)
1605+
(h (vector-height xs)))
1606+
(if (zero? h)
1607+
(node-push! xs x)
1608+
(let ((ys (loop (last xs) (- h 1))))
1609+
(and ys (node-push! xs ys)))))))
1610+
(if ys
1611+
(list root ys)
1612+
root)))))
1613+
(vector-set-length! xs (+ (vector-length xs) 1)))
1614+
1615+
(define (node-push! xs x)
1616+
(let ((n (length xs)))
1617+
(if (< n factor)
1618+
(begin
1619+
(set-cdr! (list-tail xs (- n 1)) (list x))
1620+
#f)
1621+
(list x))))
16171622

16181623
(define (parse-range xs rest)
16191624
(cons
@@ -1628,11 +1633,10 @@
16281633
(define range (parse-range xs rest))
16291634

16301635
(do ((index (car range) (+ index 1))
1631-
(ys
1632-
empty-vector
1633-
(vector-push ys (vector-ref xs index))))
1636+
(ys (empty-vector)))
16341637
((>= index (cdr range))
1635-
ys)))
1638+
ys)
1639+
(vector-push! ys (vector-ref xs index))))
16361640

16371641
(define (vector-copy! to at from . rest)
16381642
(define range (parse-range from rest))
@@ -1652,10 +1656,11 @@
16521656
(vector-set! xs index fill)))
16531657

16541658
(define (list->vector xs)
1655-
(do ((xs xs (cdr xs))
1656-
(ys empty-vector (vector-push ys (car xs))))
1657-
((not (pair? xs))
1658-
ys)))
1659+
(let ((ys (empty-vector)))
1660+
(for-each
1661+
(lambda (x) (vector-push! ys x))
1662+
xs)
1663+
ys))
16591664

16601665
(define (vector->list xs)
16611666
(do ((height (vector-height xs) (- height 1))
@@ -1670,11 +1675,12 @@
16701675
(apply f (map (lambda (xs) (vector-ref xs index)) (cons x xs))))
16711676

16721677
(define (vector-map f x . xs)
1673-
(let ((length (min-length x xs)))
1674-
(do ((index 0 (+ index 1))
1675-
(ys empty-vector (vector-push ys (map-element f x xs index))))
1676-
((= index length)
1677-
ys))))
1678+
(do ((index 0 (+ index 1))
1679+
(length (min-length x xs))
1680+
(ys (empty-vector)))
1681+
((= index length)
1682+
ys)
1683+
(vector-push! ys (map-element f x xs index))))
16781684

16791685
(define (vector-for-each f x . xs)
16801686
(let ((length (min-length x xs)))

0 commit comments

Comments
 (0)