# Copyright (c) 2010 gocept gmbh & co. kg
# See also LICENSE.txt

import csv
import persistent
import random
import zc.queue
import zeit.vgwort.interfaces
import zope.container.contained
import zope.interface


class TokenStorage(persistent.Persistent,
                   zope.container.contained.Contained):

    zope.interface.implements(zeit.vgwort.interfaces.ITokens)

    def __init__(self):
        self._data = zc.queue.CompositeQueue(compositeSize=100)

    def load(self, csv_file):
        reader = csv.reader(csv_file, delimiter=';')
        reader.next()  # skip first line
        for public_token, private_token in reader:
            self._data.put((public_token, private_token))

    def claim(self):
        if len(self) == 0:
            raise ValueError("No tokens available.")
        return self._data.pull(random.randint(0, len(self) - 1))

    def __len__(self):
        return len(self._data)

@@ -59,16 +59,37 @@
 SE.txt%0A%0A
+import BTrees.Length%0A
 import c
@@ -474,16 +474,59 @@
 ize=100)
+%0A        self._len = BTrees.Length.Length()
 %0A%0A    de
@@ -751,16 +751,48 @@
 _token))
+%0A            self._len.change(1)
 %0A%0A    de
@@ -894,22 +894,23 @@
         
-return
+value =
  self._d
@@ -951,16 +951,66 @@
 f) - 1))
+%0A        self._len.change(-1)%0A        return value
 %0A%0A    de
@@ -1045,20 +1045,16 @@
 urn 
-len(
 self._
-data
+len(
 )%0A

use a separate length object so we don't have to load the whole data to get the length