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}