Skip to content

Commit 17d1786

Browse files
author
Huahai Yang
committed
0.6.6
1 parent b4921f5 commit 17d1786

File tree

4 files changed

+159
-3
lines changed

4 files changed

+159
-3
lines changed

.github/workflows/build.yml

+15-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,23 @@ jobs:
1616
- name: Git checkout
1717
uses: actions/checkout@v1
1818

19+
- name: Prepare java
20+
uses: actions/setup-java@v3
21+
with:
22+
distribution: 'temurin'
23+
java-version: '8'
24+
25+
- name: Install clojure tools
26+
uses: DeLaGuardo/[email protected]
27+
with:
28+
lein: 2.9.1
29+
30+
- uses: actions/setup-node@v4
31+
with:
32+
node-version: '20'
33+
1934
- name: Run JVM tests
2035
run: lein test
2136

2237
- name: Run node tests
2338
run: lein doo node once
24-

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Change Log
22

3-
## [0.6.5] - 2025-01-24
3+
## [0.6.6] - 2025-01-24
44
### Added
55
- `data-nodes` to return the number of nodes of a piece of data.
66
- `change-ratio` to return an approximation of an editscript's ratio of change

project.clj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(defproject juji/editscript "0.6.5"
1+
(defproject juji/editscript "0.6.6"
22
:description "A diff library for Clojure/ClojureScript data structures"
33
:url "https://github.com/juji-io/editscript"
44
:lein-release {:deploy-via :clojars}

src/editscript/util/index.cljc

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
;;
2+
;; Copyright (c) Huahai Yang. All rights reserved.
3+
;; The use and distribution terms for this software are covered by the
4+
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5+
;; which can be found in the file LICENSE at the root of this distribution.
6+
;; By using this software in any fashion, you are agreeing to be bound by
7+
;; the terms of this license.
8+
;; You must not remove this notice, or any other, from this software.
9+
;;
10+
11+
(ns editscript.util.index
12+
(:require [editscript.edit :as e]
13+
#?(:cljs [goog.math.Long :refer [getMaxValue]]))
14+
#?(:clj (:import [clojure.lang PersistentVector]
15+
[java.io Writer])) )
16+
17+
;; indexing
18+
19+
(defprotocol INode
20+
(get-path [this] "Get the path to the node from root")
21+
(get-value [this] "Get the actual data")
22+
(get-children [this] "Get all children node in a map")
23+
(add-child [this node] "Add a child node")
24+
(get-key [this] "Get the key of this node")
25+
(get-parent [this] "Get the parent node")
26+
(get-first [this] "Get the first child node")
27+
(get-last [this] "Get the last child node")
28+
(get-next [this] "Get the next sibling node")
29+
(set-next [this node] "Set the next sibling node")
30+
(set-order [this o] "Set the traversal order of this node")
31+
(get-order [this] "Get the order of this node in traversal")
32+
(get-size [this] "Get the size of sub-tree, used to estimate cost")
33+
(set-size [this s] "Set the size of sub-tree"))
34+
35+
(deftype Node [^PersistentVector path
36+
value
37+
parent
38+
^:unsynchronized-mutable children
39+
^:unsynchronized-mutable first
40+
^:unsynchronized-mutable last
41+
^:unsynchronized-mutable next
42+
^:unsynchronized-mutable index
43+
^:unsynchronized-mutable ^long order
44+
^:unsynchronized-mutable ^long size]
45+
INode
46+
(get-path [_] path)
47+
(get-key [this] (-> this get-path peek))
48+
(get-value [_] value)
49+
(get-parent [_] parent)
50+
(get-children [_] children)
51+
(get-first [_] first)
52+
(get-last [_] last)
53+
(get-next [_] next)
54+
(set-next [_ n] (set! next n))
55+
(get-order [_] order)
56+
(set-order [this o] (set! order (long o)) this)
57+
(get-size [_] size)
58+
(set-size [this s] (set! size (long s)) this)
59+
(add-child [_ node]
60+
(set! children (assoc children (get-key node) node))
61+
(when last (set-next last node))
62+
(when-not first (set! first node))
63+
(set! last node)
64+
node))
65+
66+
#?(:clj
67+
(defmethod print-method Node
68+
[x ^Writer writer]
69+
(print-method {:value (get-value x)
70+
:order (get-order x)
71+
:children (get-children x)}
72+
writer)))
73+
74+
(declare index*)
75+
76+
(defn- associative-children
77+
"map and vector are associative"
78+
[order path data parent]
79+
(reduce-kv
80+
(fn [_ k v]
81+
(index* order (conj path k) v parent))
82+
nil
83+
data))
84+
85+
(defn- set-children
86+
"set is a map of keys to themselves"
87+
[order path data parent]
88+
(doseq [x data]
89+
(index* order (conj path x) x parent)))
90+
91+
(defn- list-children
92+
"add index as key"
93+
[order path data parent]
94+
(reduce
95+
(fn [i x]
96+
(index* order (conj path i) x parent)
97+
(inc ^long i))
98+
0
99+
data))
100+
101+
(defn- inc-order
102+
"order value reflects the size of elements"
103+
[order ^long size]
104+
(vswap! order (fn [o] (+ size ^long o))))
105+
106+
(defn- index-collection
107+
[type order path data parent]
108+
(let [node (->Node path data parent {} nil nil nil 0 0 1)]
109+
(add-child parent node)
110+
(case type
111+
(:map :vec) (associative-children order path data node)
112+
:set (set-children order path data node)
113+
:lst (list-children order path data node))
114+
(let [^long cs (->> (get-children node) vals (map get-size) (reduce +))
115+
size (+ (long (get-size node)) cs)]
116+
(doto node
117+
(set-order @order)
118+
(set-size size))
119+
(inc-order order size))
120+
node))
121+
122+
(defn- index-value
123+
[order path data parent]
124+
(let [node (->Node path data parent nil nil nil nil 0 @order 1)]
125+
(add-child parent node)
126+
(inc-order order 1)
127+
node))
128+
129+
(defn- index*
130+
[order path data parent]
131+
(let [type (e/get-type data)]
132+
(if (or (= type :val) (= type :str))
133+
(index-value order path data parent)
134+
(index-collection type order path data parent))))
135+
136+
(defn index
137+
"Traverse data to build an indexing tree of Nodes,
138+
compute path, sizes of sub-trees, siblings, etc. for each Node.
139+
This takes little time"
140+
[data]
141+
(let [order (volatile! 0)]
142+
(index* order [] data (->Node [] ::dummy nil {} nil nil nil 0 -1 0))))

0 commit comments

Comments
 (0)