Skip to content

Commit

Permalink
Cleanup|PathMap: Removed unnecessary noise from the implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Jan 17, 2012
1 parent c857136 commit e44fcf1
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 71 deletions.
53 changes: 25 additions & 28 deletions doomsday/engine/portable/include/pathmap.h
@@ -1,24 +1,24 @@
/**\file pathmap.h
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
/**
* @file pathmap.h
* Fragment map of a delimited string. @ingroup fs
*
*\author Copyright © 2011-2012 Daniel Swanson <danij@dengine.net>
* @authors Copyright © 2011-2012 Daniel Swanson <danij@dengine.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* A map of a fragment-delimited string. Instantiate on the stack.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifndef LIBDENG_FILESYS_PATHMAP_H
Expand All @@ -33,22 +33,19 @@ typedef struct pathmapfragment_s {
struct pathmapfragment_s* next;
} PathMapFragment;

/**
* PathMap. Can be allocated on the stack.
*/
/// Size of the fixed-length "short" path (in characters) allocated with the map.
#define PATHMAP_SHORT_PATH 256

/// Size of the fixed-length "short" fragment buffer allocated with the map.
#define PATHMAP_FRAGMENTBUFFER_SIZE 8

typedef struct {
char _shortPath[PATHMAP_SHORT_PATH+1];
char* _path; // The long version.
char _delimiter;
typedef struct pathmap_s {
char shortPath[PATHMAP_SHORT_PATH+1];
char* path; // The long version.
char delimiter;

/// Total number of fragments in the path.
uint _fragmentCount;
uint fragmentCount;

/**
* Fragment map of the path. The map is composed of two
Expand All @@ -61,10 +58,10 @@ typedef struct {
* majority of paths can be represented without dynamically
* allocating memory from the heap.
*/
PathMapFragment _fragmentBuffer[PATHMAP_FRAGMENTBUFFER_SIZE];
PathMapFragment fragmentBuffer[PATHMAP_FRAGMENTBUFFER_SIZE];

/// Head of the linked list of "extra" fragments, in reverse order.
PathMapFragment* _extraFragments;
PathMapFragment* extraFragments;
} PathMap;

/**
Expand Down Expand Up @@ -106,4 +103,4 @@ uint PathMap_Size(PathMap* pathMap);
*/
const PathMapFragment* PathMap_Fragment(PathMap* pathMap, uint idx);

#endif /* LIBDENG_FILESYS_PATHMAP_H */
#endif // LIBDENG_FILESYS_PATHMAP_H
88 changes: 45 additions & 43 deletions doomsday/engine/portable/src/pathmap.c
@@ -1,24 +1,22 @@
/**\file pathmap.c
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
/**
* @file pathmap.c
* Fragment map of a delimited string @ingroup fs
*
*\author Copyright © 2011-2012 Daniel Swanson <danij@dengine.net>
* @authors Copyright © 2011-2012 Daniel Swanson <danij@dengine.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#include "de_base.h"
Expand All @@ -33,7 +31,7 @@ static ushort PathMap_HashFragment(PathMap* pm, PathMapFragment* fragment)
if(fragment->hash == PATHDIRECTORY_NOHASH)
{
fragment->hash = PathDirectory_HashPath(fragment->from,
(fragment->to - fragment->from) + 1, pm->_delimiter);
(fragment->to - fragment->from) + 1, pm->delimiter);
}
return fragment->hash;
}
Expand All @@ -48,31 +46,31 @@ static void PathMap_MapAllFragments(PathMap* pm, const char* path, size_t pathLe
assert(pm && path && path[0] && pathLen != 0);

// Skip over any trailing delimiters.
for(i = pathLen; *to && *to == pm->_delimiter && i-- > 0; to--) {}
for(i = pathLen; *to && *to == pm->delimiter && i-- > 0; to--) {}

pm->_fragmentCount = 0;
pm->_extraFragments = NULL;
pm->fragmentCount = 0;
pm->extraFragments = NULL;

// Scan for discreet fragments in the path, in reverse order.
for(;;)
{
// Find the start of the next path fragment.
for(from = to; from > begin && !(*from == pm->_delimiter); from--) {}
for(from = to; from > begin && !(*from == pm->delimiter); from--) {}

// Retrieve another fragment.
if(pm->_fragmentCount < PATHMAP_FRAGMENTBUFFER_SIZE)
if(pm->fragmentCount < PATHMAP_FRAGMENTBUFFER_SIZE)
{
fragment = pm->_fragmentBuffer + pm->_fragmentCount;
fragment = pm->fragmentBuffer + pm->fragmentCount;
}
else
{
// Allocate another "extra" fragment.
PathMapFragment* f = (PathMapFragment*)malloc(sizeof *f);
if(!f) Con_Error("PathMap::MapAllFragments: Failed on allocation of %lu bytes for new PathMap::Fragment.", (unsigned long) sizeof *f);

if(!pm->_extraFragments)
if(!pm->extraFragments)
{
pm->_extraFragments = fragment = f;
pm->extraFragments = fragment = f;
}
else
{
Expand All @@ -81,14 +79,14 @@ static void PathMap_MapAllFragments(PathMap* pm, const char* path, size_t pathLe
}
}

fragment->from = (*from == pm->_delimiter? from + 1 : from);
fragment->from = (*from == pm->delimiter? from + 1 : from);
fragment->to = to;
// Hashing is deferred; means not-hashed yet.
fragment->hash = PATHDIRECTORY_NOHASH;
fragment->next = NULL;

// There is now one more fragment in the map.
pm->_fragmentCount += 1;
pm->fragmentCount += 1;

// Are there no more parent directories?
if(from == begin) break;
Expand All @@ -102,18 +100,22 @@ static void PathMap_MapAllFragments(PathMap* pm, const char* path, size_t pathLe
static void PathMap_ClearFragments(PathMap* pm)
{
assert(pm);
while(pm->_extraFragments)
while(pm->extraFragments)
{
PathMapFragment* next = pm->_extraFragments->next;
free(pm->_extraFragments);
pm->_extraFragments = next;
PathMapFragment* next = pm->extraFragments->next;
free(pm->extraFragments);
pm->extraFragments = next;
}
}

static void PathMap_ClearPath(PathMap* pm)
{
assert(pm);
if(pm->_path) free(pm->_path), pm->_path = NULL;
if(pm->path)
{
free(pm->path);
pm->path = NULL;
}
}

PathMap* PathMap_Initialize2(PathMap* pm, const char* path, char delimiter)
Expand All @@ -127,22 +129,22 @@ PathMap* PathMap_Initialize2(PathMap* pm, const char* path, char delimiter)
if(pathLen <= PATHMAP_SHORT_PATH)
{
// Use the small search path buffer.
pm->_path = NULL;
pathBuffer = pm->_shortPath;
pm->path = NULL;
pathBuffer = pm->shortPath;
}
else
{
// Allocate a buffer large enough to hold the whole path.
pm->_path = (char*)malloc(pathLen+1);
pathBuffer = pm->_path;
pm->path = (char*)malloc(pathLen+1);
pathBuffer = pm->path;
}
if(pathLen)
{
memcpy(pathBuffer, path, pathLen);
}
pathBuffer[pathLen] = '\0';

pm->_delimiter = delimiter;
pm->delimiter = delimiter;

// Create the fragment map of the path.
PathMap_MapAllFragments(pm, pathBuffer, pathLen);
Expand All @@ -168,21 +170,21 @@ void PathMap_Destroy(PathMap* pm)
uint PathMap_Size(PathMap* pm)
{
assert(pm);
return pm->_fragmentCount;
return pm->fragmentCount;
}

const PathMapFragment* PathMap_Fragment(PathMap* pm, uint idx)
{
PathMapFragment* fragment;
if(!pm || idx >= pm->_fragmentCount) return NULL;
if(!pm || idx >= pm->fragmentCount) return NULL;
if(idx < PATHMAP_FRAGMENTBUFFER_SIZE)
{
fragment = pm->_fragmentBuffer + idx;
fragment = pm->fragmentBuffer + idx;
}
else
{
uint n = PATHMAP_FRAGMENTBUFFER_SIZE;
fragment = pm->_extraFragments;
fragment = pm->extraFragments;
while(n++ < idx)
{
fragment = fragment->next;
Expand Down

0 comments on commit e44fcf1

Please sign in to comment.