My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!python
# Parsing.
import re

index_pattern = re.compile(r'(?:(?P<vnum>\d+)\.zon)|\$$')

def parseindex(index_name):
## return [int(i) for i in
## map(lambda n:index_pattern.match(n).groupdict()['vnum'],
## open(index_name).readlines()) \
## if type(i) is str and i.isdigit()]

# Something more verbose, to debug:
index = []
for line in open(index_name).readlines():
match = index_pattern.match(line)
if match is not None:
vnum = match.groupdict()['vnum']
if type(vnum) is str and vnum.isdigit():
index.append(int(vnum))

return index

def segment(array, nr):
nr = int(nr)

ln = len(array)
step = ln / nr

assert step

## print 'ln: %s, nr: %s, step: %s' % (ln, nr, step)
## print array

x = 0
while (ln - x) >= step:
## print 'x: %s, x+step: %s: ln-x: %s, array[x:x+step]: %s' % \
## (x, x+step, ln-x, array[x:x+step])

yield array[x:x+step]
x += step

yield array[x:]

def nr_segments(total_size, max_size, allowance):
return total_size / ((1 - float(allowance)) * max_size)

# Build.
def writeIndex(filename, index):
fl = open(filename, 'w')
for vnum in index:
fl.write('%d.zon\n' % vnum)

fl.write('$\n')
fl.flush()
fl.close()

from os.path import dirname, basename, join as joinpath, isdir, isfile
from os import mkdir, system
from tempfile import gettempdir

def getDirectory(base, *parts):
if not isdir(base) and base:
mkdir(base)

for d in parts:
base = joinpath(base, d)
if not isdir(base):
mkdir(base)

return base

def getBuildSegmentBase(build_name, nr):
return getDirectory(gettempdir(), build_name, '%04d' % nr)

## def getZoneSpan(base, vnum):
## # Todo: build this once!
## from stuphlib.wldlib import WorldLoader
## from stuphlib.dblib import LocalFileIndex
## loader = WorldLoader(LocalFileIndex(base))
##
## zone = loader.createZone(vnum)
## return zone.span

def copy_file(src, dest):
if isfile(src):
system('/bin/cp "%s" "%s"' % (src, dest))

def remove_directory(path):
system('/bin/rm -Rf "%s"' % path)

def zip_archive(name, source):
print 'zip_archive: %r -> %r' % (source, name)

# Zip up contents without containing segmentation folder.
system('cd "%s"; zip -c "%s" .' % (source, name))
# system('zip -c "%s" "%s"' % (name, source))

FIXES = ('zon', 'wld', 'obj', 'mob', 'shp', 'sch')

def prepare_segment((build_name, world_base, index_name, archive_base), (segment, nr)):
#
# This builds a temporary directory and then zips it to file.
# Todo: compile zip archive directly without intermediate fs.
#
try:
# Rebuild a world index segment.
build_base = getBuildSegmentBase(build_name, nr)
print 'build_base: %r' % build_base

# Build parts containers.
parts = {}
for fix in FIXES:
parts[fix] = getDirectory(build_base, fix)

# Build zon index.
writeIndex(joinpath(parts['zon'], index_name), segment)

# This is not true: Spanned contents go into one file!
## # Must load the zone record to discover zone span!
## span = getZoneSpan(world_base, vnum)

# Build parts.
for fix in FIXES:
for vnum in segment:
this = '%d.%s' % (vnum, fix)
copy_file(joinpath(world_base, fix, this),
joinpath(parts[fix], this))

# Zip Archive.
zip_archive(joinpath(archive_base, '%04d.zip' % nr),
build_base)

finally:
# Remove temporary build directories.
remove_directory(build_base)

def prepare_segmented_index(index_file, build_name,
(total_size, max_size, allowance)):

world_base = dirname(dirname(index_file))
index_name = basename(index_file)

archive_base = getDirectory(world_base, build_name)

total = nr_segments(total_size, max_size, allowance)
nr = 1

for seg in segment(parseindex(index_file), total):
prepare_segment((build_name, world_base, index_name, archive_base),
(seg, nr))
nr += 1

# Test -- Calculate index segments where each (average) size
# will fit within maximum allowed size, with room to spare.
TOTAL_SIZE = 4676642
MAX_SIZE = (1 << 20)
ALLOWANCE = 0.25

# INDEX_FILE = r'H:/StuphMUD/lib/world/zon/index'

BUILD_NAME = 'stuphworld-segments'
BUILD_PARTS = [BUILD_NAME] # 'only'

def parse_cmdln(argv):
from optparse import OptionParser
parser = OptionParser()
return parser.parse_args(argv)

def main(argv = None):
(options, args) = parse_cmdln(argv)
index_file = args[0]

this_build = '-'.join(BUILD_PARTS)
prepare_segmented_index(index_file, this_build,
(TOTAL_SIZE, MAX_SIZE, ALLOWANCE))

if __name__ == '__main__':
main()

Change log

r11 by cbanis on May 19, 2010   Diff
Rewrote parseindex to be more verbose, and
more efficient for not building
intermediate lists.
Also pre-compiles index_pattern

zip_archive no longer puts entries into
the segmentation folder in the archive
(compat)
Go to: 
Project members, sign in to write a code review

Older revisions

r9 by cbanis on Apr 24, 2010   Diff
Added splitindex.
All revisions of this file

File info

Size: 5238 bytes, 179 lines

File properties

svn:executable
*
Powered by Google Project Hosting