1/*
2 *******************************************************************************
3 * Copyright (C) 2007-2014, International Business Machines Corporation and    *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 */
7
8package com.ibm.icu.dev.test.collator;
9
10import java.util.Arrays;
11import java.util.Locale;
12import java.util.Random;
13
14import com.ibm.icu.dev.test.TestFmwk;
15import com.ibm.icu.text.Collator;
16
17public class CollationThreadTest extends TestFmwk {
18    public static void main(String[] args) throws Exception {
19        new CollationThreadTest().run(args);
20    }
21
22    private static final String[] threadTestData;
23    static {
24        final Collator collator = Collator.getInstance(new Locale("pl", "", ""));
25        final String[] temporaryData = {
26                "Banc Se\u00F3kdyaaouq Pfuymjec",
27                "BSH \u00F3y",
28                "ABB - \u00F3g",
29                "G\u00F3kpo Adhdoetpwtx Twxma, qm. Ilnudx",
30                "G\u00F3bjh Zcgopqmjidw Dyhlu, ky. Npyamr",
31                "G\u00F3dxb Slfduvgdwfi Qhreu, ao. Adyfqx",
32                "G\u00F3ten Emrmbmttgne Rtpir, rx. Mgmpjy",
33                "G\u00F3kjo Hciqkymfcds Jpudo, ti. Ueceedbm (tkvyj vplrnpoq)",
34                "Przjrpnbhrflnoo Dbiccp Lnmikfhsuo\u00F3s Tgfhlpqoso / ZAD ENR",
35                "Bang Nbygmoyc Nd\u00F3nipcryjtzm",
36                "Citjk\u00EBd Qgmgvr Er. w u.x.",
37                "Dyrscywp Kvoifmyxo Ivv\u00F3r Lbyxtrwnzp",
38                "G\u00E9awk Ssqenl Pk. c r.g.",
39                "Nesdo\u00E9 Ilwbay Z.U.",
40                "Poczsb Lrdtqg",
41                "Pocafu Tgbmpn - wwg zo Mpespnzdllqk",
42                "Polyvmg Z.C.",
43                "POLUHONANQ FO",
44                "Polrpycn",
45                "Poleeaw-Rqzghgnnj R.W.",
46                "Polyto Sgrgcvncz",
47                "Polixj Tyfc\u00F3vcga Gbkjxf\u00F3f Tuogcybbbkyd C.U.",
48                "Poltmzzlrkwt",
49                "Polefgb Oiqefrkq",
50                "Polrfdk K\u00F3nvyrfot Xuzbzzn f Ujmfwkdbnzh E.U. Wxkfiwss",
51                "Polxtcf Hfowus Zzobblfm N.I.",
52                "POLJNXO ZVYU L.A.",
53                "PP Lowyr Rmknyoew",
54                "Pralpe",
55                "Preyojy Qnrxr",
56                "PRK -5",
57                "PRONENC U.P.",
58                "Prowwyq & Relnda Hxkvauksnn Znyord Tz. w t.o.",
59                "Propydv Afobbmhpg",
60                "Proimpoupvp",
61                "Probfo Hfttyr",
62                "Propgi Lutgumnj X.W. BL",
63                "Prozkch K.E.",
64                "Progiyvzr Erejqk T.W.",
65                "Prooxwq-Ydglovgk J.J.",
66                "PTU Ntcw Lwkxjk S.M. UYF",
67                "PWN",
68                "PWP",
69                "PZU I.D. Tlpzmhax",
70                "PZU ioii A.T. Yqkknryu - bipdq badtg 500/9",
71                "Qumnl-Udffq",
72                "Radmvv",
73                "Railoggeqd Aewy Fwlmsp K.S. Ybrqjgyr",
74                "Remhmxkx Ewuhxbg",
75                "Renafwp Sapnqr io v z.n.",
76                "Repqbpuuo",
77                "Resflig",
78                "Rocqz Mvwftutxozs VQ",
79                "Rohkui",
80                "RRC",
81                "Samgtzg Fkbulcjaaqv Ollllq Ad. l l.v.",
82                "Schelrlw Fu. t z.x.",
83                "Schemxgoc Axvufoeuh",
84                "Siezsxz Eb. n r.h",
85                "Sikj Wyvuog",
86                "Sobcwssf Oy. q o.s. Kwaxj",
87                "Sobpxpoc Fb. w q.h. Elftx",
88                "Soblqeqs Kpvppc RH - tbknhjubw siyaenc Njsjbpx Buyshpgyv",
89                "Sofeaypq FJ",
90                "Stacyok Qurqjw Hw. f c.h.",
91                "STOWN HH",
92                "Stopjhmq Prxhkakjmalkvdt Weqxejbyig Wgfplnvk D.C.",
93                "STRHAEI Clydqr Ha. d z.j.",
94                "Sun Clvaqupknlk",
95                "TarfAml",
96                "Tchukm Rhwcpcvj Cc. v y.a.",
97                "Teco Nyxm Rsvzkx pm. J a.t.",
98                "Tecdccaty",
99                "Telruaet Nmyzaz Twwwuf",
100                "Tellrwihv Xvtjle N.U.",
101                "Telesjedc Boewsx A.F",
102                "tellqfwiqkv dinjlrnyit yktdhlqquihzxr (ohvso)",
103                "Tetft Kna Ab. j l.z.",
104                "Thesch",
105                "Totqucvhcpm Gejxkgrz Is. e k.i.",
106                "Towajgixetj Ngaayjitwm fj csxm Mxebfj Sbocok X.H.",
107                "Toyfon Meesp Neeban Jdsjmrn sz v z.w.",
108                "TRAJQ NZHTA Li. n x.e. - Vghfmngh",
109                "Triuiu",
110                "Tripsq",
111                "TU ENZISOP ZFYIPF V.U.",
112                "TUiX Kscdw G.G.",
113                "TVN G.A.",
114                "Tycd",
115                "Unibjqxv rdnbsn - ZJQNJ XCG / Wslqfrk",
116                "Unilcs - hopef ps 20 nixi",
117                "UPC Gwwmru Ds. g o.r.",
118                "Vaidgoav",
119                "Vatyqzcgqh Kjnnsy GQ WT",
120                "Volhz",
121                "Vos Jviggogjt Iyqhlm Ih. w j.y. (fbshoihdnb)",
122                "WARMFC E.D.",
123                "Wincqk Pqadskf",
124                "WKRD",
125                "Wolk Pyug",
126                "WPRV",
127                "WSiI",
128                "Wurag XZ",
129                "Zacrijl B.B.",
130                "Zakja Tziaboysenum Squlslpp - Diifw V.D.",
131                "Zakgat Meqivadj Nrpxlekmodx s Bbymjozge W.Y.",
132                "Zjetxpbkpgj Mmhhgohasjtpkjd Uwucubbpdj K.N.",
133                "ZREH"
134        };
135        sort(temporaryData, collator);
136        threadTestData = temporaryData;
137    }
138
139    private static void scramble(String[] data, Random r) {
140        for (int i = 0; i < data.length; ++i) {
141            int ix = r.nextInt(data.length);
142            String s = data[i];
143            data[i] = data[ix];
144            data[ix] = s;
145        }
146    }
147
148    private static void sort(String[] data, Collator collator) {
149        Arrays.sort(data, collator);
150    }
151
152    private static boolean verifySort(String[] data) {
153        for (int i = 0; i < data.length; i++) {
154            if (!data[i].equals(threadTestData[i])) {
155                return false;
156            }
157        }
158        return true;
159    }
160
161    private static class Control {
162        private boolean go;
163        private String fail;
164
165        synchronized void start() {
166            go = true;
167            notifyAll();
168        }
169
170        synchronized void stop() {
171            go = false;
172            notifyAll();
173        }
174
175        boolean go() {
176            return go;
177        }
178
179        void fail(String msg) {
180            fail = msg;
181            stop();
182        }
183    }
184
185    private static class Test implements Runnable {
186        private String[] data;
187        private Collator collator;
188        private String name;
189        private Control control;
190        private Random r;
191
192        Test(String name, String[] data, Collator collator, Random r, Control control) {
193            this.name = name;
194            this.data = data;
195            this.collator = collator;
196            this.control = control;
197            this.r = r;
198        }
199
200        public void run() {
201            try {
202                synchronized (control) {
203                    while (!control.go()) {
204                        control.wait();
205                    }
206                }
207
208                while (control.go()) {
209                    scramble(this.data, r);
210                    sort(this.data, this.collator);
211                    if (!verifySort(this.data)) {
212                        control.fail(name + ": incorrect sort");
213                    }
214                }
215            } catch (InterruptedException e) {
216                // die
217            } catch (IndexOutOfBoundsException e) {
218                control.fail(name + " " + e.getMessage());
219            }
220        }
221    }
222
223    private void runThreads(Thread[] threads, Control control) {
224        for (int i = 0; i < threads.length; ++i) {
225            threads[i].start();
226        }
227
228        try {
229            control.start();
230
231            long stopTime = System.currentTimeMillis() + 5000;
232            do {
233                Thread.sleep(100);
234            } while (control.go() && System.currentTimeMillis() < stopTime);
235
236            control.stop();
237
238            for (int i = 0; i < threads.length; ++i) {
239                threads[i].join();
240            }
241        } catch (InterruptedException e) {
242            // die
243        }
244
245        if (control.fail != null) {
246            errln(control.fail);
247        }
248    }
249
250    public void testThreads() {
251        final Collator theCollator = Collator.getInstance(new Locale("pl", "", ""));
252        final Random r = new Random();
253        final Control control = new Control();
254
255        Thread[] threads = new Thread[10];
256        for (int i = 0; i < threads.length; ++i) {
257            Collator coll;
258            try {
259                coll = (Collator)theCollator.clone();
260            } catch (CloneNotSupportedException e) {
261                // should not happen, if it does we'll get an exception right away
262                errln("could not clone");
263                return;
264            }
265            Test test = new Test("Collation test thread" + i, threadTestData.clone(), coll,
266                    r, control);
267            threads[i] = new Thread(test);
268        }
269
270        runThreads(threads, control);
271    }
272
273    public void testFrozen() {
274        final Collator theCollator = Collator.getInstance(new Locale("pl", "", ""));
275        theCollator.freeze();
276        final Random r = new Random();
277        Control control = new Control();
278
279        Thread[] threads = new Thread[10];
280        for (int i = 0; i < threads.length; ++i) {
281            Test test = new Test("Frozen collation test thread " + i, threadTestData.clone(), theCollator,
282                    r, control);
283            threads[i] = new Thread(test);
284        }
285
286        runThreads(threads, control);
287    }
288}
289