File: cache.m

package info (click to toggle)
gnustep-base 1.31.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 26,580 kB
  • sloc: objc: 239,446; ansic: 36,519; cpp: 122; sh: 112; makefile: 100; xml: 32
file content (131 lines) | stat: -rw-r--r-- 4,016 bytes parent folder | download | duplicates (6)
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
#import "ObjectTesting.h"
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSCache.h>


@interface TestObject : NSObject <NSDiscardableContent>
{
  BOOL _discarded;
}
@end

@implementation TestObject

- (BOOL)beginContentAccess
{
  return YES;
}

- (void)endContentAccess
{
}

- (void)discardContentIfPossible
{
  _discarded = YES;
}



- (BOOL)isContentDiscarded
{
  return _discarded;
}
@end

int main()
{
  NSAutoreleasePool     *arp = [NSAutoreleasePool new];
  NSCache		*cache = [[NSCache new] autorelease];

  [cache setName: @"Foo"];
  PASS_EQUAL(@"Foo", [cache name], "Name can be set an accessed");

  [cache setCountLimit: 2];
  PASS(2 == [cache countLimit], "Count limit can be set and accessed");

  [cache setTotalCostLimit: 3];
  PASS(3 == [cache totalCostLimit], "Total cost limit can be set and accessed");

  [cache setObject: @"bar" forKey: @"foo"];
  PASS_EQUAL(@"bar", [cache objectForKey: @"foo"],
    "Cached object can be returned");


  /*
   * NOTE: The following to test sets currently won't work. The only available
   * eviction strategy is to evict under the following conditions:
   *
   * - evictsObjectsWithDiscardedContent is set on the receiver
   * - the cached object implements NSDiscardableContent
   * - the content is actually discarded
   */
  START_SET("count-based eviction")
    testHopeful = YES;
    /* Let's test count based eviction: We add two more items and expect the
     * first one (foo) to be removed because the count limit is two
     */
    [cache setObject: @"baz" forKey: @"bar"];
    NSUInteger i = 0;
    for (i = 0; i < 50; i++)
      {
        /* We need to heat this object in the cache so that the first one
         * becomes elligible for eviction
         */
        [cache objectForKey: @"bar"];
      }
    [cache setObject: @"frubble" forKey: @"baz"];
    PASS_EQUAL(@"frubble", [cache objectForKey: @"baz"],
      "LRU object retained on count overflow");
    PASS_EQUAL(@"baz", [cache objectForKey: @"bar"],
      "second object retained on count overflow");
    PASS(nil == [cache objectForKey: @"foo"], "Oldest object evicted");
  END_SET("count-based eviction")
  [cache removeAllObjects];

  START_SET("cost-based eviction")
    testHopeful = YES;
    [cache setObject: @"bar" forKey: @"foo" cost: 2];
    // This should push out the previous object because the cumulative cost (4)
    // exceeds the limit (3)
    [cache setObject: @"baz" forKey: @"bar" cost: 2];
    PASS_EQUAL(@"baz", [cache objectForKey: @"bar"],
      "LRU  object retained on cost overflow");
    PASS(nil == [cache objectForKey: @"foo"], "Overflowing object evicted");
  END_SET("cost-based eviction")

  [cache removeAllObjects];
  START_SET("eviction of discardable content")
    cache = [[NSCache new] autorelease];
    [cache setCountLimit: 1];
    [cache setEvictsObjectsWithDiscardedContent: YES];
    TestObject *a = [[TestObject new] autorelease];
    TestObject *b = [[TestObject new] autorelease];
    [cache setObject: a forKey: @"foo"];
    [cache setObject: b forKey: @"bar"];
    PASS_EQUAL(b, [cache objectForKey: @"bar"],
      "LRU  object retained on count overflow");
    PASS(nil == [cache objectForKey: @"foo"],
      "Overflowing object evicted on count overflow");

    PASS([a isContentDiscarded],
      "Cache did call -discardContentIfPossible on cached object");
    [cache removeAllObjects];
    [cache setCountLimit: 0];
    [cache setTotalCostLimit: 3];
    a = [[TestObject new] autorelease];
    b = [[TestObject new] autorelease];
    [cache setObject: a forKey: @"foo" cost: 2];
    [cache setObject: b forKey: @"bar" cost: 2];
    PASS_EQUAL(b, [cache objectForKey: @"bar"],
      "LRU  object retained on cost overflow");
    PASS(nil == [cache objectForKey: @"foo"],
      "Overflowing object evicted on cost overflow");
      PASS([a isContentDiscarded],
        "Cache did call -discardContentIfPossible on cached object");
  END_SET("eviction of discardable content")


  [arp release]; arp = nil;
  return 0;
}