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