001/*
002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.platform.importer.random;
023
024import java.io.IOException;
025import java.util.HashMap;
026import java.util.Map;
027import java.util.Random;
028
029import org.nuxeo.ecm.core.api.NuxeoException;
030
031/**
032 * Random text generator to be used for load testing
033 *
034 * @author Thierry Delprat
035 */
036public class RandomTextGenerator {
037
038    protected DictionaryHolder dictionaryHolder;
039
040    protected Map<String, String> paragraphCache = new HashMap<String, String>();
041
042    protected Map<String, String> pageCache = new HashMap<String, String>();
043
044    protected Map<String, String> blockCache = new HashMap<String, String>();
045
046    protected static final int PARAGRAPH_CACHE_SIZE = 100;
047
048    protected static final int PARAGRAPH_CACHE_HIT = 100;
049
050    protected static final int PAGE_CACHE_SIZE = 50;
051
052    protected static final int PAGE_CACHE_HIT = 30;
053
054    protected static final int BLOC_CACHE_SIZE = 30;
055
056    protected static final int BLOC_CACHE_HIT = 20;
057
058    protected static final int BLOC_SIZE = 10 * 1024;
059
060    protected static final int NB_WORDS_PER_LINE = 20;
061
062    protected static final int NB_LINES_PER_PARAGRAPH = 40;
063
064    protected static final int NB_PARAGRAPH_PER_PAGE = 8;
065
066    protected static final int NB_PAGE_PER_BLOC = 3;
067
068    protected Random generator;
069
070    public RandomTextGenerator(DictionaryHolder dictionary) {
071        dictionaryHolder = dictionary;
072        generator = new Random(System.currentTimeMillis());
073    }
074
075    protected int getTargetPageMaxSizeB() {
076        return (int) (1.2 * (BLOC_SIZE / NB_PAGE_PER_BLOC));
077    }
078
079    protected int getTargetParagraphMaxSizeB() {
080        return (int) (1.2 * (getTargetPageMaxSizeB() / NB_PARAGRAPH_PER_PAGE));
081    }
082
083    public String getRandomTitle(int nbWord) {
084        StringBuffer sb = new StringBuffer();
085        for (int i = 0; i < nbWord; i++) {
086            sb.append(dictionaryHolder.getRandomWord());
087        }
088        return sb.toString();
089
090    }
091
092    public String getRandomLine() {
093        int nbW = 10 + generator.nextInt(NB_WORDS_PER_LINE);
094        StringBuffer sb = new StringBuffer();
095
096        for (int i = 0; i < nbW; i++) {
097            sb.append(dictionaryHolder.getRandomWord());
098        }
099        sb.append(".\n");
100        return sb.toString();
101    }
102
103    public String generateParagraph() {
104        int nbL = 10 + generator.nextInt(NB_LINES_PER_PARAGRAPH);
105        StringBuffer sb = new StringBuffer();
106
107        int maxSize = getTargetParagraphMaxSizeB();
108
109        for (int i = 0; i < nbL; i++) {
110            sb.append(getRandomLine());
111            if (sb.length() > maxSize) {
112                break;
113            }
114        }
115        sb.append("\n\n");
116        return sb.toString();
117    }
118
119    public void prefilCache() {
120
121        try {
122            dictionaryHolder.init();
123        } catch (IOException e) {
124            throw new NuxeoException(e);
125        }
126
127        for (int i = 0; i < PARAGRAPH_CACHE_SIZE; i++) {
128            paragraphCache.put("P" + i, generateParagraph());
129        }
130
131        for (int i = 0; i < PAGE_CACHE_SIZE; i++) {
132            String page = generatePage();
133            pageCache.put("P" + i, page);
134        }
135
136        for (int i = 0; i < BLOC_CACHE_SIZE; i++) {
137            String page = generateBloc();
138            blockCache.put("B" + i, page);
139        }
140
141    }
142
143    public String getRandomParagraph() {
144        int rand = generator.nextInt();
145        int idx = generator.nextInt(PARAGRAPH_CACHE_SIZE);
146        String paragraph = null;
147        if (rand % PARAGRAPH_CACHE_HIT != 0) {
148            paragraph = paragraphCache.get("P" + idx);
149        }
150        if (paragraph == null) {
151            paragraph = generateParagraph();
152            paragraphCache.put("P" + idx, paragraph);
153        }
154        return paragraph;
155    }
156
157    public String generatePage() {
158        int nbL = generator.nextInt(NB_PARAGRAPH_PER_PAGE) + 1;
159        StringBuffer sb = new StringBuffer();
160
161        int maxTargetPageSize = getTargetPageMaxSizeB();
162        for (int i = 0; i < nbL; i++) {
163            sb.append(getRandomParagraph());
164            if (sb.length() > maxTargetPageSize) {
165                break;
166            }
167        }
168        sb.append("\n\n");
169        return sb.toString();
170    }
171
172    public String getRandomPage() {
173        int rand = generator.nextInt();
174        int idx = generator.nextInt(PAGE_CACHE_SIZE);
175        String page = null;
176        if (rand % PAGE_CACHE_HIT != 0) {
177            page = pageCache.get("P" + idx);
178        }
179        if (page == null) {
180            page = generatePage();
181            pageCache.put("P" + idx, page);
182        }
183        return page;
184    }
185
186    public String generateBloc() {
187        StringBuffer sb = new StringBuffer();
188
189        while (sb.length() < BLOC_SIZE) {
190            sb.append(getRandomPage());
191        }
192        return sb.toString();
193    }
194
195    public String getRandomBloc() {
196        int rand = generator.nextInt();
197        int idx = generator.nextInt(BLOC_CACHE_SIZE);
198        String bloc = null;
199        if (rand % BLOC_CACHE_HIT != 0) {
200            bloc = blockCache.get("B" + idx);
201        }
202        if (bloc == null) {
203            bloc = generateBloc();
204            blockCache.put("B" + idx, bloc);
205        }
206        return bloc;
207    }
208
209    public String getRandomText(int avSizeInK) {
210        if (avSizeInK == 0) {
211            return "";
212        }
213        StringBuffer sb = new StringBuffer();
214        int minSize = (int) (avSizeInK * 1024 * (0.8 + 0.4 * generator.nextFloat()));
215        while (sb.length() < (minSize - BLOC_SIZE)) {
216            String p = getRandomBloc();
217            sb.append(p);
218        }
219        while (sb.length() < minSize) {
220            String p = getRandomPage();
221            sb.append(p);
222        }
223        return sb.toString();
224    }
225
226    public String getRandomText() {
227        int sizeK = generator.nextInt(500) + 1;
228        return getRandomText(sizeK);
229    }
230
231}