def _policy_RequestIG(self, books_needed):
'''Select books from IGs specified in interleave_request attribute.
If interleave_request_pos is present use it as the starting point.'''
db = self.LCEobj.db
ig_req = db.get_xattr(self.shelf, self.XATTR_IG_REQ)
self.LCEobj.errno = errno.ERANGE
assert ig_req is not None, \
'RequestIG policy requires prior %s' % self.XATTR_IG_REQ
assert len(ig_req), \
'RequestIG policy requires prior %s' % self.XATTR_IG_REQ
# Get a starting position for the interleave_request list
self.LCEobj.errno = errno.ENOSPC
pos = db.get_xattr(self.shelf, self.XATTR_IG_REQ_POS)
try:
ig_pos = int(pos)
if ig_pos < 0 or ig_pos > (len(ig_req) - 1):
ig_pos = 0
except TypeError as err: # TSNH, see create_shelf. Legacy paranoia.
ig_pos = 0
resp = db.create_xattr(self.shelf, self.XATTR_IG_REQ_POS, ig_pos)
except ValueError as err:
ig_pos = 0
reqIGs = [ord(ig_req[i:i+1]) for i in range(0, len(ig_req), 1)]
# Determine number of books needed from each IG
igCnt = defaultdict(int)
cur = ig_pos
for cnt in range(0, books_needed):
ig = reqIGs[cur % len(reqIGs)]
igCnt[ig] += 1
cur += 1
# Allocate specified number of books from each selected IG
booksIG = {}
for ig in igCnt.keys():
booksIG[ig] = db.get_books_by_intlv_group(
igCnt[ig], (ig, ), exclude=False)
# Build list of books using request_interleave pattern
self.LCEobj.errno = errno.ENOSPC
bookList = []
cur = ig_pos
for cnt in range(0, books_needed):
ig = reqIGs[cur % len(reqIGs)]
assert len(booksIG[ig]) != 0, 'Not enough books remaining in IG'
bookList.append(booksIG[ig].pop(0))
cur += 1
# Save current position in interleave_request list
db.modify_xattr(self.shelf, self.XATTR_IG_REQ_POS, cur % len(reqIGs))
return bookList
评论列表
文章目录