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 getRandomLine() {
084        int nbW = 10 + generator.nextInt(NB_WORDS_PER_LINE);
085        StringBuffer sb = new StringBuffer();
086
087        for (int i = 0; i < nbW; i++) {
088            sb.append(dictionaryHolder.getRandomWord());
089        }
090        sb.append(".\n");
091        return sb.toString();
092    }
093
094    public String generateParagraph() {
095        int nbL = 10 + generator.nextInt(NB_LINES_PER_PARAGRAPH);
096        StringBuffer sb = new StringBuffer();
097
098        int maxSize = getTargetParagraphMaxSizeB();
099
100        for (int i = 0; i < nbL; i++) {
101            sb.append(getRandomLine());
102            if (sb.length() > maxSize) {
103                break;
104            }
105        }
106        sb.append("\n\n");
107        return sb.toString();
108    }
109
110    public void prefilCache() {
111
112        try {
113            dictionaryHolder.init();
114        } catch (IOException e) {
115            throw new NuxeoException(e);
116        }
117
118        for (int i = 0; i < PARAGRAPH_CACHE_SIZE; i++) {
119            paragraphCache.put("P" + i, generateParagraph());
120        }
121
122        for (int i = 0; i < PAGE_CACHE_SIZE; i++) {
123            String page = generatePage();
124            pageCache.put("P" + i, page);
125        }
126
127        for (int i = 0; i < BLOC_CACHE_SIZE; i++) {
128            String page = generateBloc();
129            blockCache.put("B" + i, page);
130        }
131
132    }
133
134    public String getRandomParagraph() {
135        int rand = generator.nextInt();
136        int idx = generator.nextInt(PARAGRAPH_CACHE_SIZE);
137        String paragraph = null;
138        if (rand % PARAGRAPH_CACHE_HIT != 0) {
139            paragraph = paragraphCache.get("P" + idx);
140        }
141        if (paragraph == null) {
142            paragraph = generateParagraph();
143            paragraphCache.put("P" + idx, paragraph);
144        }
145        return paragraph;
146    }
147
148    public String generatePage() {
149        int nbL = generator.nextInt(NB_PARAGRAPH_PER_PAGE) + 1;
150        StringBuffer sb = new StringBuffer();
151
152        int maxTargetPageSize = getTargetPageMaxSizeB();
153        for (int i = 0; i < nbL; i++) {
154            sb.append(getRandomParagraph());
155            if (sb.length() > maxTargetPageSize) {
156                break;
157            }
158        }
159        sb.append("\n\n");
160        return sb.toString();
161    }
162
163    public String getRandomPage() {
164        int rand = generator.nextInt();
165        int idx = generator.nextInt(PAGE_CACHE_SIZE);
166        String page = null;
167        if (rand % PAGE_CACHE_HIT != 0) {
168            page = pageCache.get("P" + idx);
169        }
170        if (page == null) {
171            page = generatePage();
172            pageCache.put("P" + idx, page);
173        }
174        return page;
175    }
176
177    public String generateBloc() {
178        StringBuffer sb = new StringBuffer();
179
180        while (sb.length() < BLOC_SIZE) {
181            sb.append(getRandomPage());
182        }
183        return sb.toString();
184    }
185
186    public String getRandomBloc() {
187        int rand = generator.nextInt();
188        int idx = generator.nextInt(BLOC_CACHE_SIZE);
189        String bloc = null;
190        if (rand % BLOC_CACHE_HIT != 0) {
191            bloc = blockCache.get("B" + idx);
192        }
193        if (bloc == null) {
194            bloc = generateBloc();
195            blockCache.put("B" + idx, bloc);
196        }
197        return bloc;
198    }
199
200    public String getRandomText(int avSizeInK) {
201        StringBuffer sb = new StringBuffer();
202        int minSize = (int) (avSizeInK * 1024 * (0.8 + 0.4 * generator.nextFloat()));
203        while (sb.length() < (minSize - BLOC_SIZE)) {
204            String p = getRandomBloc();
205            sb.append(p);
206        }
207        while (sb.length() < minSize) {
208            String p = getRandomPage();
209            sb.append(p);
210        }
211        return sb.toString();
212    }
213
214    public String getRandomText() {
215        int sizeK = generator.nextInt(500) + 1;
216        return getRandomText(sizeK);
217    }
218
219}