001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.importer.random; 021 022import java.io.IOException; 023import java.util.HashMap; 024import java.util.Map; 025import java.util.Random; 026 027import org.nuxeo.ecm.core.api.NuxeoException; 028 029/** 030 * Random text generator to be used for load testing 031 * 032 * @author Thierry Delprat 033 */ 034public class RandomTextGenerator { 035 036 protected DictionaryHolder dictionaryHolder; 037 038 protected Map<String, String> paragraphCache = new HashMap<String, String>(); 039 040 protected Map<String, String> pageCache = new HashMap<String, String>(); 041 042 protected Map<String, String> blockCache = new HashMap<String, String>(); 043 044 protected static final int PARAGRAPH_CACHE_SIZE = 100; 045 046 protected static final int PARAGRAPH_CACHE_HIT = 100; 047 048 protected static final int PAGE_CACHE_SIZE = 50; 049 050 protected static final int PAGE_CACHE_HIT = 30; 051 052 protected static final int BLOC_CACHE_SIZE = 30; 053 054 protected static final int BLOC_CACHE_HIT = 20; 055 056 protected static final int BLOC_SIZE = 10 * 1024; 057 058 protected static final int NB_WORDS_PER_LINE = 20; 059 060 protected static final int NB_LINES_PER_PARAGRAPH = 40; 061 062 protected static final int NB_PARAGRAPH_PER_PAGE = 8; 063 064 protected static final int NB_PAGE_PER_BLOC = 3; 065 066 protected Random generator; 067 068 public RandomTextGenerator(DictionaryHolder dictionary) { 069 dictionaryHolder = dictionary; 070 generator = new Random(System.currentTimeMillis()); 071 } 072 073 protected int getTargetPageMaxSizeB() { 074 return (int) (1.2 * (BLOC_SIZE / NB_PAGE_PER_BLOC)); 075 } 076 077 protected int getTargetParagraphMaxSizeB() { 078 return (int) (1.2 * (getTargetPageMaxSizeB() / NB_PARAGRAPH_PER_PAGE)); 079 } 080 081 public String getRandomLine() { 082 int nbW = 10 + generator.nextInt(NB_WORDS_PER_LINE); 083 StringBuffer sb = new StringBuffer(); 084 085 for (int i = 0; i < nbW; i++) { 086 sb.append(dictionaryHolder.getRandomWord()); 087 } 088 sb.append(".\n"); 089 return sb.toString(); 090 } 091 092 public String generateParagraph() { 093 int nbL = 10 + generator.nextInt(NB_LINES_PER_PARAGRAPH); 094 StringBuffer sb = new StringBuffer(); 095 096 int maxSize = getTargetParagraphMaxSizeB(); 097 098 for (int i = 0; i < nbL; i++) { 099 sb.append(getRandomLine()); 100 if (sb.length() > maxSize) { 101 break; 102 } 103 } 104 sb.append("\n\n"); 105 return sb.toString(); 106 } 107 108 public void prefilCache() { 109 110 try { 111 dictionaryHolder.init(); 112 } catch (IOException e) { 113 throw new NuxeoException(e); 114 } 115 116 for (int i = 0; i < PARAGRAPH_CACHE_SIZE; i++) { 117 paragraphCache.put("P" + i, generateParagraph()); 118 } 119 120 for (int i = 0; i < PAGE_CACHE_SIZE; i++) { 121 String page = generatePage(); 122 pageCache.put("P" + i, page); 123 } 124 125 for (int i = 0; i < BLOC_CACHE_SIZE; i++) { 126 String page = generateBloc(); 127 blockCache.put("B" + i, page); 128 } 129 130 } 131 132 public String getRandomParagraph() { 133 int rand = generator.nextInt(); 134 int idx = generator.nextInt(PARAGRAPH_CACHE_SIZE); 135 String paragraph = null; 136 if (rand % PARAGRAPH_CACHE_HIT != 0) { 137 paragraph = paragraphCache.get("P" + idx); 138 } 139 if (paragraph == null) { 140 paragraph = generateParagraph(); 141 paragraphCache.put("P" + idx, paragraph); 142 } 143 return paragraph; 144 } 145 146 public String generatePage() { 147 int nbL = generator.nextInt(NB_PARAGRAPH_PER_PAGE) + 1; 148 StringBuffer sb = new StringBuffer(); 149 150 int maxTargetPageSize = getTargetPageMaxSizeB(); 151 for (int i = 0; i < nbL; i++) { 152 sb.append(getRandomParagraph()); 153 if (sb.length() > maxTargetPageSize) { 154 break; 155 } 156 } 157 sb.append("\n\n"); 158 return sb.toString(); 159 } 160 161 public String getRandomPage() { 162 int rand = generator.nextInt(); 163 int idx = generator.nextInt(PAGE_CACHE_SIZE); 164 String page = null; 165 if (rand % PAGE_CACHE_HIT != 0) { 166 page = pageCache.get("P" + idx); 167 } 168 if (page == null) { 169 page = generatePage(); 170 pageCache.put("P" + idx, page); 171 } 172 return page; 173 } 174 175 public String generateBloc() { 176 StringBuffer sb = new StringBuffer(); 177 178 while (sb.length() < BLOC_SIZE) { 179 sb.append(getRandomPage()); 180 } 181 return sb.toString(); 182 } 183 184 public String getRandomBloc() { 185 int rand = generator.nextInt(); 186 int idx = generator.nextInt(BLOC_CACHE_SIZE); 187 String bloc = null; 188 if (rand % BLOC_CACHE_HIT != 0) { 189 bloc = blockCache.get("B" + idx); 190 } 191 if (bloc == null) { 192 bloc = generateBloc(); 193 blockCache.put("B" + idx, bloc); 194 } 195 return bloc; 196 } 197 198 public String getRandomText(int avSizeInK) { 199 StringBuffer sb = new StringBuffer(); 200 int minSize = (int) (avSizeInK * 1024 * (0.8 + 0.4 * generator.nextFloat())); 201 while (sb.length() < (minSize - BLOC_SIZE)) { 202 String p = getRandomBloc(); 203 sb.append(p); 204 } 205 while (sb.length() < minSize) { 206 String p = getRandomPage(); 207 sb.append(p); 208 } 209 return sb.toString(); 210 } 211 212 public String getRandomText() { 213 int sizeK = generator.nextInt(500) + 1; 214 return getRandomText(sizeK); 215 } 216 217}