Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1995, 1996 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gxbcache.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
18
/* Bitmap cache implementation */
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gsmdebug.h"
22
#include "gxbcache.h"
23
 
24
/* ------ Entire cache ------ */
25
 
26
/* Initialize a cache.  The caller must allocate and initialize */
27
/* the first chunk. */
28
void
29
gx_bits_cache_init(gx_bits_cache * bc, gx_bits_cache_chunk * bck)
30
{
31
    bck->next = bck;
32
    bc->chunks = bck;
33
    bc->cnext = 0;
34
    bc->bsize = 0;
35
    bc->csize = 0;
36
}
37
 
38
/* ------ Chunks ------ */
39
 
40
/* Initialize a chunk.  The caller must allocate it and its data. */
41
void
42
gx_bits_cache_chunk_init(gx_bits_cache_chunk * bck, byte * data, uint size)
43
{
44
    bck->next = 0;
45
    bck->data = data;
46
    bck->size = size;
47
    bck->allocated = 0;
48
    if (data != 0) {
49
	gx_cached_bits_head *cbh = (gx_cached_bits_head *) data;
50
 
51
	cbh->size = size;
52
	cb_head_set_free(cbh);
53
    }
54
}
55
 
56
/* ------ Individual entries ------ */
57
 
58
/* Attempt to allocate an entry.  If successful, set *pcbh and return 0. */
59
/* If there isn't enough room, set *pcbh to an entry requiring freeing, */
60
/* or to 0 if we are at the end of the chunk, and return -1. */
61
int
62
gx_bits_cache_alloc(gx_bits_cache * bc, ulong lsize, gx_cached_bits_head ** pcbh)
63
{
64
#define ssize ((uint)lsize)
65
    ulong lsize1 = lsize + sizeof(gx_cached_bits_head);
66
 
67
#define ssize1 ((uint)lsize1)
68
    uint cnext = bc->cnext;
69
    gx_bits_cache_chunk *bck = bc->chunks;
70
    uint left = bck->size - cnext;
71
    gx_cached_bits_head *cbh;
72
    gx_cached_bits_head *cbh_next;
73
    uint fsize = 0;
74
 
75
    if (lsize1 > bck->size - cnext && lsize != left) {	/* Not enough room to allocate in this chunk. */
76
	*pcbh = 0;
77
	return -1;
78
    }
79
    /* Look for and/or free enough space. */
80
    cbh = cbh_next = (gx_cached_bits_head *) (bck->data + cnext);
81
    while (fsize < ssize1 && fsize != ssize) {
82
	if (!cb_head_is_free(cbh_next)) {	/* Ask the caller to free the entry. */
83
	    if (fsize)
84
		cbh->size = fsize;
85
	    *pcbh = cbh_next;
86
	    return -1;
87
	}
88
	fsize += cbh_next->size;
89
	if_debug2('K', "[K]merging free bits 0x%lx(%u)\n",
90
		  (ulong) cbh_next, cbh_next->size);
91
	cbh_next = (gx_cached_bits_head *) ((byte *) cbh + fsize);
92
    }
93
    if (fsize > ssize) {	/* fsize >= ssize1 */
94
	cbh_next = (gx_cached_bits_head *) ((byte *) cbh + ssize);
95
	cbh_next->size = fsize - ssize;
96
	cb_head_set_free(cbh_next);
97
	if_debug2('K', "[K]shortening bits 0x%lx by %u (initial)\n",
98
		  (ulong) cbh, fsize - ssize);
99
    }
100
    gs_alloc_fill(cbh, gs_alloc_fill_block, ssize);
101
    cbh->size = ssize;
102
    bc->bsize += ssize;
103
    bc->csize++;
104
    bc->cnext += ssize;
105
    bck->allocated += ssize;
106
    *pcbh = cbh;
107
    return 0;
108
#undef ssize
109
#undef ssize1
110
}
111
 
112
/* Shorten an entry by a given amount. */
113
void
114
gx_bits_cache_shorten(gx_bits_cache * bc, gx_cached_bits_head * cbh,
115
		      uint diff, gx_bits_cache_chunk * bck)
116
{
117
    gx_cached_bits_head *next;
118
 
119
    if ((byte *) cbh + cbh->size == bck->data + bc->cnext &&
120
	bck == bc->chunks
121
	)
122
	bc->cnext -= diff;
123
    bc->bsize -= diff;
124
    bck->allocated -= diff;
125
    cbh->size -= diff;
126
    next = (gx_cached_bits_head *) ((byte *) cbh + cbh->size);
127
    cb_head_set_free(next);
128
    next->size = diff;
129
}
130
 
131
/* Free an entry.  The caller is responsible for removing the entry */
132
/* from any other structures (like a hash table). */
133
void
134
gx_bits_cache_free(gx_bits_cache * bc, gx_cached_bits_head * cbh,
135
		   gx_bits_cache_chunk * bck)
136
{
137
    uint size = cbh->size;
138
 
139
    bc->csize--;
140
    bc->bsize -= size;
141
    bck->allocated -= size;
142
    gs_alloc_fill(cbh, gs_alloc_fill_deleted, size);
143
    cbh->size = size;		/* gs_alloc_fill may have overwritten */
144
    cb_head_set_free(cbh);
145
}