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}